By David,
Every application a user opens on an Azure Virtual Desktop (AVD) session host got there one of three ways. It was baked into the golden image the host was built from. It was installed after the host was built, at deploy time or later, by a package manager such as WinGet. Or it was attached at sign-in, mounted from a package on a file share by App Attach without ever being installed on the host at all.
Most estates end up using all three, and the design question is not "which one?" but "which one for this app?". Get the split right and image builds stay small, patches land in minutes, and the finance team's niche tool stops forcing a rebuild for 400 hosts that will never run it. Get it wrong and you are either rebuilding the image every time Chrome updates, or trying to package an application that was never going to survive MSIX.
This guide compares the three approaches, explains what changed when Microsoft replaced MSIX app attach with App Attach, lists the apps that package badly, and ends with a decision matrix by app type. It's vendor-neutral until the section on where Atlas AVD helps.
The short version: put the apps everyone needs and the things that must be there before first sign-in (agents, FSLogix, Office, the VDI parts of Teams) in the image. Deliver mainstream, frequently updated apps with WinGet so updating them never means an image build. Use App Attach for the apps only some groups need, once you have confirmed they package and run cleanly. When in doubt, install it.
Microsoft product details below reflect Microsoft Learn as of October 2026, with links to each source so you can check what has changed.
The three approaches, side by side
| Baked into the image | Installed with WinGet | Attached with App Attach | |
|---|---|---|---|
| How the app arrives | Installed on the source VM before capture; every host built from that version has it | winget install runs on the host at deploy time, or on demand on a running host | A disk image (CIM, VHD or VHDX) on a file share is mounted at sign-in and the app is registered for that user |
| Image size | Grows with every app | Unaffected | Unaffected |
| Update speed | Slowest: rebuild, publish, then re-image or replace hosts | Fast: run the upgrade on the hosts; no image change | Fast: publish a new package version; users pick it up at next sign-in |
| Who gets it | Everyone on hosts built from the image | Everyone on the hosts you target | Only the users or groups the package is assigned to |
| Isolation | None: a normal install, shared with everything else on the host | None: a normal install | Containerised: the app runs from its package, with its own files and registry |
| Packaging effort | None, beyond installing it | None if the app is in the WinGet catalog or you host your own manifest | Real: capture to MSIX, sign it, test it, expand it into an image |
| Licensing | Normal per-device or per-user activation | Normal per-device or per-user activation | The app's licensing still applies; activation that relies on a per-machine install needs testing |
| Dependency on first sign-in | Zero: the app is there before the first user arrives | Low: the install runs during provisioning, before the host accepts sessions | Adds work at sign-in: the mount and registration happen as the user logs on |
| What goes wrong | Image sprawl and long rebuilds | Apps that have no silent installer or no catalog entry | Apps that won't package, expired certificates, a slow or unreachable share |
Each approach is the right answer for some apps and the wrong answer for others. The sections below cover each one in the order you should consider them.
Image size, update speed and isolation pull in different directions. No single delivery method wins all three, which is why the decision is made per app.
1. Baking apps into the golden image
The oldest approach is still the most reliable. You customise a VM, install what every user needs, generalise it with Sysprep, capture it to an Azure Compute Gallery image version, and build session hosts from it. Everything in the image is present before the first user signs in, the install was tested once on the source VM, and nothing has to be downloaded at scale.
Put these in the image:
- Anything the host needs before it accepts sessions. The AVD agent, FSLogix, monitoring and security agents, VPN or ZTNA clients, printer drivers, and the WebRTC Redirector Service for Teams.
- Microsoft 365 Apps. On multi-session hosts, Microsoft's guidance is to install Microsoft 365 Apps in the image with shared computer activation (Microsoft Learn). It's large, every user needs it, and it updates on Microsoft's channel schedule rather than yours.
- Apps with drivers, services or kernel components. They can't be attached, and installing them after the host is built means every new host runs the installer again.
- Heavy, stable applications. A 20 GB CAD suite that updates twice a year belongs in the image. Downloading it onto every host at deploy time wastes time and bandwidth, and it rarely changes.
Keep these out of the image:
- Apps that update every few weeks. Browsers, PDF readers, collaboration clients. If each update means an image build, you will fall behind, and a stale browser in the image is a security finding waiting to happen.
- Apps only some users need. Each one grows the image for everyone and adds a patch obligation for every host.
- Anything with a per-machine identity. Agents that register a device ID need Sysprep-safe installs or a first-boot step, or every host will report as the same machine.
The cost of the image approach is the lifecycle. Every change is a build, a test, a publish, replication to each region, and then a rollout that drains hosts, replaces them and watches for regressions. Done well, that's a monthly rhythm aligned to Patch Tuesday. Done badly, it's a rebuild every time someone asks for a new version of something. Our full vs shallow replication post covers the replication side, and the AVD golden image management guide covers the rest of the lifecycle.
2. Installing apps at deploy time with WinGet
Windows Package Manager (WinGet) is Microsoft's command-line package manager for Windows. It ships with Windows 11 and Windows 10 through the App Installer, and it can silently install and upgrade thousands of mainstream applications from the public catalog, or from a private repository you host yourself.
For AVD, the pattern is simple: keep the image lean, and run a scripted winget install for each app as part of host provisioning, before the host joins the pool and accepts sessions. Later, run winget upgrade on the hosts to patch, or re-run the install list on hosts that are already up.
WinGet is the right answer when:
- The app is in the catalog, with a silent installer. Chrome, Edge, Firefox, Adobe Reader, 7-Zip, Notepad++, VLC, PowerShell, Visual Studio Code, Zoom, Slack and most mainstream tools are. For an in-house app, you can publish your own manifest to a private source.
- The app updates often. A browser patched through WinGet is patched on every host without touching the image. For security-sensitive software, that alone justifies the approach.
- Different pools need different app sets. A per-pool install list gives each host pool its own software without a separate image per pool.
- You want one install mechanism for the whole fleet. The same package IDs, the same silent switches, the same exit codes, on every host.
WinGet is the wrong answer when:
- The installer needs a reboot or a running user session. Provisioning-time installs run as SYSTEM, with nobody signed in, and some installers assume otherwise.
- The app isn't packaged for silent install. Some enterprise software ships as a wizard that cannot be scripted, and a private WinGet manifest can't fix that.
- The app is huge. Installing 15 GB on every new host turns a two-minute provision into a twenty-minute one, and autoscale notices.
- The install needs the app's own update mechanism turned off. WinGet handles updates, so apps that auto-update on their own need that disabled in policy, or two mechanisms fight over the version.
A WinGet install also leaves a normal installed application behind. There is no isolation and no user-level targeting: everyone on the host sees the app. That's fine for the apps most people use, and it's the reason the third approach exists for the rest.
How Atlas AVD uses WinGet goes deeper on running WinGet across a fleet, including reading the exit codes correctly and keeping a patch history off each host.
3. App Attach vs legacy MSIX app attach: what changed
App Attach delivers applications to session hosts by mounting a disk image that contains the packaged app from a file share when a user signs in, and registering the app for that user. The app appears installed, runs from the mounted image, and is never written to the host's OS disk. Sign out, and it's gone. Microsoft's overview is the authoritative reference (App attach and MSIX app attach in Azure Virtual Desktop).
There are two generations, and the names are close enough to confuse people:
| MSIX app attach (legacy) | App Attach (current) | |
|---|---|---|
| Scope of assignment | A package is added to a host pool and every user on that pool gets it | A package is an Azure resource you assign to users and groups through application groups, and the same package can serve several host pools |
| Targeting | Per host pool | Per user or group, with the package only mounted for users who are assigned it |
| Package formats | MSIX | MSIX, Appx and App-V, plus the same image formats |
| Image formats | CIM, VHD, VHDX | CIM, VHD, VHDX |
| Versioning | One version per host pool at a time | Multiple versions of a package can exist, and users pick up the version assigned to them |
| Management | Host pool settings | A first-class App attach blade in the Azure portal, with PowerShell and REST support |
| Microsoft's guidance | Existing deployments only | Use for new work; existing MSIX app attach packages can be migrated |
The practical difference is targeting. With the legacy model, "attach this package" meant everyone on the pool. With App Attach, the finance team's app is assigned to the finance group, mounts only in their sessions, and a user from another department on the same pooled host never sees it. That's what makes a shared pooled host serve different app sets to different people without a separate image or pool per department.
Both generations share the same mechanics underneath, and the requirements don't change (Set up App attach):
- A file share the hosts can reach as computer accounts. Azure Files with Entra Kerberos, Active Directory or Entra Domain Services authentication, or Azure NetApp Files. The session hosts' computer objects need read access, and the share needs to be fast enough that a mount at sign-in doesn't become a logon delay.
- A disk image per package. You expand the MSIX into a CIM, VHD or VHDX image. Microsoft recommends CIM for its lower CPU and memory cost at mount time.
- A signing certificate the hosts trust. Every MSIX package is signed, and the certificate must be trusted on the session host. An expired certificate is the classic "it worked last month" failure.
- Hosts on a supported OS build. Windows 11 or Windows 10 Enterprise and Enterprise multi-session, with the App Attach components present.
The point of App Attach is not a smaller image. It's that an app can be assigned to a group of users rather than to a host, so one pooled host can serve many different app sets.
4. Packaging effort, and the apps that don't package well
App Attach moves the work from image building to packaging, and packaging is where most pilots stall. Each application has to be captured into an MSIX package, usually with the MSIX Packaging Tool on a clean machine, signed with a certificate your hosts trust, tested as a packaged app, then expanded into an image and tested again from a share. Budget for a few hours per well-behaved app and a day or more for an awkward one, plus the same again for each major version.
Apps that package well: self-contained user-mode applications that install into their own folder and write user data under the user's profile. Most line-of-business desktop tools, viewers, reporting clients and internal utilities fit, and vendors increasingly ship MSIX packages themselves.
Apps that don't package well, or at all:
- Drivers and kernel-mode components. MSIX can't install a driver, so printer software, VPN clients, scanner tools and anything with a filter driver stay in the image.
- Windows services and scheduled tasks. A package can't register a service that starts at boot. Agents, backup clients and licensing services belong in the image.
- Apps that write into their own install folder. MSIX redirects or blocks writes to the package. Software that stores settings, caches or licence files next to its executable breaks until the vendor fixes it or you find a redirection shim that works.
- Shell extensions, COM servers and system-wide hooks. Some are supported, many are not, and the failures are subtle: a right-click menu that's missing, an add-in that another app can't see.
- Apps with per-machine activation. If the licence is tied to a machine install, the containerised copy may activate on every sign-in, or not at all. Test it with the vendor's blessing.
- Microsoft 365 Apps and Teams. Install Office in the image, and install new Teams per machine on pooled hosts with Microsoft's bootstrapper (Teams on AVD walks through it).
- Very large applications. Mounting a 30 GB CIM at every sign-in moves the cost from the image to the share and the logon. It works, but a CAD suite is rarely a good first candidate.
The honest test is this: if an app installs cleanly with a silent switch and everyone needs it, WinGet or the image will be cheaper than packaging. App Attach earns its packaging cost when the app is needed by a subset of users, updates on its own schedule, and would otherwise force a separate image or pool.
5. Decision matrix by app type
| App type | Usually | Why |
|---|---|---|
| AVD agent, FSLogix, security and monitoring agents | Image | Must be present before the first session; often include services or drivers |
| Microsoft 365 Apps | Image | Microsoft's supported path on multi-session: in the image with shared computer activation |
| Microsoft Teams (new) | Image | Per-machine install with the bootstrapper; add the WebRTC Redirector Service |
| Browsers (Edge, Chrome, Firefox) | WinGet | Update every few weeks; everyone needs them; silent installers in the catalog |
| PDF readers, archivers, media players, utilities | WinGet | Same reasons as browsers, and usually in the catalog |
| Collaboration and meeting clients (Zoom, Slack, Webex) | WinGet | Frequent updates; check the per-machine installer and VDI plug-in guidance for each |
| Line-of-business app everyone uses | Image or WinGet | Image if it's stable and heavy; WinGet if it has a silent installer and updates often |
| Line-of-business app one department uses | App Attach | Assign to the department's group; no separate image or pool |
| Vendor-supplied MSIX packages | App Attach | Packaging work already done; version by swapping the image |
| Heavy CAD, GIS or engineering suites | Image, on a dedicated pool | Large, stable, often licence-server bound and GPU-dependent; keep the pool small |
| Apps with drivers, services or per-machine licences | Image | Can't be attached; expensive to reinstall at deploy time |
| Legacy apps nobody can repackage | Image | Install once on the source VM; isolate the pool if the app is fragile |
Two rules of thumb hold across the table. First, the image is the default and the other two methods have to earn their place: WinGet by removing an image build from every patch, App Attach by removing a pool or image from the design. Second, pool boundaries still matter: an app that needs a GPU, a licence server or a fragile dependency is a reason for a separate host pool regardless of how it's delivered, and the delivery method doesn't change that.
How Atlas AVD handles app delivery
Atlas AVD manages all three layers from the same console, built around the split above. It doesn't package applications for you, and the places where it stops are called out so you can plan the gaps.
Image. From Imaging you customise a VM and capture it into an Azure Compute Gallery image version. The capture can generalise with Sysprep, install the AVD agent and pre-install FSLogix, and you pick the replication regions as part of the build. When a new version is published, the Outdated Image view lists the hosts still on an older image, and you move them with Rolling Replace (Zero Downtime) or a Scheduled Re-Image. See Image Management.
WinGet. The Application Catalog sets which WinGet apps each host pool installs. It inherits from global defaults to the tenant to the host pool, so the common baseline is defined once and department apps are added per pool. New hosts get their apps at provisioning time, running hosts can be given apps on demand through Install Apps, and an Update button on a host's Installed Software card upgrades one package on one host without a remote session. Winget History reads the Winget-AutoUpdate logs back off each host and shows what was patched, what failed and the exit code. Winget Deployment is available from the Starter plan, and Winget History from Professional.
App Attach. Atlas keeps a tenant-wide registry of your App Attach packages on the MSIX App Attach page: the CIM, VHD and VHDX images on your file share, each with its path, package family, version, certificate expiry and state. You can register a package by its https URL or upload the image into a locked-down storage account in your own subscription. The registry is reconciled against the App Attach packages Azure reports, so what Atlas lists matches what the hosts can mount. The registry is an Enterprise-plan feature.
From a host pool's settings you then assign a package to everyone in the pool or to specific Entra groups, and the assignment is published to the package in Azure. What Atlas doesn't do today: it doesn't create MSIX packages. Keep your packaging pipeline where it is; Atlas gives you the inventory, the assignments, the certificate dates and the state of each package in one place next to the pools that use them. The App Attach support article walks through registering and assigning a package.
New to AVD? Start with What Is Azure Virtual Desktop? for how the pieces fit, and the top 10 Azure Virtual Desktop mistakes for the ones app delivery causes. Moving from Citrix or VMware Horizon? Both guides map App Layering and App Volumes onto the three approaches here.
FAQ
What is App Attach in Azure Virtual Desktop?
App Attach is a way to deliver applications to AVD session hosts without installing them. The app is packaged as MSIX, Appx or App-V, stored as a disk image on a file share, and mounted and registered for a user when they sign in. The app runs from the image and leaves nothing on the host's OS disk when the user signs out.
What is the difference between App Attach and MSIX app attach?
MSIX app attach is the original feature: a package is added to a host pool and every user on that pool gets it. App Attach is its replacement: packages are Azure resources assigned to users and groups through application groups, one package can serve several host pools, and multiple versions can exist at once. Microsoft recommends App Attach for new deployments.
Should I use App Attach or WinGet to deploy apps to AVD?
Use WinGet for mainstream apps that everyone needs and that update often, such as browsers and PDF readers: they install silently from the catalog and patching never touches the image. Use App Attach for apps that only some users need, once you have confirmed they package and run cleanly. Keep agents, Office and anything with drivers or services in the image.
Which apps can't be delivered with App Attach?
Anything with a driver, a Windows service, a kernel-mode component or a per-machine licence, and most apps that write to their own install folder. Microsoft 365 Apps and Teams are installed in the image. Shell extensions and COM components need testing case by case.
Does App Attach reduce logon time?
No. It adds a mount and a registration at sign-in for each attached package, so a slow or distant file share shows up as a slower logon. Keep the share in the same region as the hosts, use CIM images, and watch sign-in times as you add packages. If logons are already slow, see Why are Azure Virtual Desktop logons slow?.
Can I use all three approaches on the same host pool?
Yes, and most estates do. A typical pooled host has agents, Office and Teams in the image, browsers and utilities installed by WinGet at provisioning, and one or two departmental apps attached at sign-in for the groups that use them.
Does Atlas AVD package apps for App Attach?
No. Atlas keeps a registry of the App Attach packages you have already built, including their paths, versions, certificate expiry and state, and it manages WinGet installs and golden images from the same console. Packaging stays with the MSIX Packaging Tool or your vendor, and you assign packages to a host pool or to Entra groups from the host pool's settings in Atlas.
Microsoft product details in this article are taken from Microsoft Learn as of October 2026: App attach and MSIX app attach, Set up App attach, Install Microsoft 365 Apps on a master VHD image, Windows Package Manager and the MSIX Packaging Tool. Supported formats and requirements change, so check those pages before you commit to a design.