Deploy Azure Virtual Desktop end to end: host pools and workspaces, Entra-joined session hosts, FSLogix profiles on Azure Files, RemoteApp publishing, and PowerShell automation.
C
CloudEngineerHub Team
Published: July 19, 2026· Last Updated: September 24, 2026·12 min read
Azure Virtual Desktop (AVD) is Microsoft's desktop-and-app virtualization service on Azure: pooled multi-session Windows 11 hosts, FSLogix roaming profiles, and apps published as desktops or RemoteApps. This tutorial walks a first production deployment end to end — host pool, workspace, Entra-joined session hosts, profile storage, assignment, validation — with PowerShell equivalents for each portal step.
Visual Walkthrough
Gateway, load balancing and profile attach in one pass.
Interactive FlowAVD Session — Connect to Desktop6/6
1
User authenticates
Entra + CA verify identity and device posture.
gateway
2
Gateway brokers TLS
RDP traffic wrapped over 443 via AVD gateway.
balance
3
Host pool load-balances
Breadth/depth algorithm picks the session host.
host
4
Session host serves
Multi-session Windows 11 hosts the desktop.
profile
5
FSLogix attaches profile
VHDX mounts from storage; apps + state appear.
6
User works / drains
Sign-out detaches, merges, and frees the seat.
AVD Session — Connect to Desktop. 1. User authenticates: Entra + CA verify identity and device posture. — 2. Gateway brokers TLS: RDP traffic wrapped over 443 via AVD gateway. — 3. Host pool load-balances: Breadth/depth algorithm picks the session host. — 4. Session host serves: Multi-session Windows 11 hosts the desktop. — 5. FSLogix attaches profile: VHDX mounts from storage; apps + state appear. — 6. User works / drains: Sign-out detaches, merges, and frees the seat.
C
CloudEngineerHub Team
Author
The CloudEngineerHub editorial team — Microsoft endpoint management and cloud engineers writing hands-on guides on Intune, Azure, Entra ID, Autopilot, Defender and PowerShell. Every article is reviewed against current Microsoft documentation.
Licensing: a Microsoft 365 E3/E5, Windows E3/E5 (per user), or Windows 365 license that includes multi-session Windows and AVD entitlements — no separate RDS CALs.
Azure subscription with Contributor rights, plus Desktop Virtualization Contributor for AVD objects.
Identity: Microsoft Entra ID. Decide Entra join (modern, simplest) versus AD join or Microsoft Entra Domain Services (needed for legacy GPO-heavy estates).
Quota: vCPU quota for the session-host family in your region — request an increase before deployment day.
A test user account in a security group you will use for assignments.
How It Works
AVD has four control-plane objects. A host pool is a collection of identical session hosts (Azure VMs). A workspace is what users see in their client. Application groups connect the two: Desktop groups publish the full desktop, RemoteApp groups publish individual apps. Users or groups are assigned to application groups, and the broker sends connections to the least-loaded available session host.
Profiles roam via FSLogix: at sign-in, the Profile Container attaches a VHDX from an Azure Files share, so users get a consistent profile on any session host. Multi-session Windows allows several concurrent users per VM; the load-balancing algorithm (breadth-first spreads users, depth-first fills hosts) and the maximum-sessions limit decide placement. Scaling plans start and deallocate hosts on a schedule.
Step-by-Step Implementation
1. Create the host pool and workspace
In the portal: Azure Virtual Desktop > Host pools > Create, choosing Pooled, BreadthFirst, and Windows 11 Enterprise multi-session + Microsoft 365 Apps as the image. Then create a workspace and Desktop application group linked to the pool. The PowerShell equivalent:
Add VMs from the host pool's blade (Session hosts > Add). Choose the subnet, Entra join, and credentials type — local admin disabled, Entra credentials for sign-in. Generate a registration token so VMs can join the pool:
PowerShell
1
2
3
4
5
# Registration token for adding session hosts to the pool (valid, then used by the VM wizard)$exp = (Get-Date).ToUniversalTime().AddHours(4)
New-AzWvdRegistrationInfo -ResourceGroupName$rg -HostPoolName'hp-avd-prod' -ExpirationTime$exp
(Get-AzWvdHostPool -ResourceGroupName$rg -Name'hp-avd-prod').RegistrationInfoToken.Length
# Expected: a token string (used by session host registration); hours kept short for hygiene
3. Configure FSLogix profiles on Azure Files
Create a premium file share, assign the Storage File Data SMB Share Contributor role to your AVD users group, and enable Microsoft Entra Kerberos for the storage account (File shares blade) so Entra-joined hosts can mount it. Then set the FSLogix registry values on the session hosts (or via Intune policy):
PowerShell
1
2
3
4
5
6
7
8
# Premium file share for FSLogix profile containers$sa = New-AzStorageAccount -ResourceGroupName$rg -Name'stavdprofiles01' `
-Location$loc -SkuName'Premium_ZRS' -Kind'FileStorage'
New-AzStorageShare -Context$sa.Context -Name'profiles'# Grant AVD users SMB access via RBAC (Entra Kerberos authentication enabled in the portal)
New-AzRoleAssignment -ObjectId'<avd-users-group-object-id>' `
-RoleDefinitionName'Storage File Data SMB Share Contributor' -Scope$sa.Id
# Expected: profiles share created; role assignment visible under the account's IAM
FSLogix settings (per session host or via policy): HKLM:\SOFTWARE\FSLogix\Profiles with Enabled = 1 and VHDLocations = \\stavdprofiles01.file.core.windows.net\profiles.
4. Assign users and publish RemoteApps
Assign your AVD users security group to dag-avd-prod (Application group > Assignments). For apps, create a RemoteApp group and add applications from the Start menu or a file path. Licensing: each user needs a Microsoft 365 E3/E5 license — multi-session Windows blocks sign-in without one.
5. Harden access
Create a Conditional Access policy targeting the Azure Virtual Desktop app requiring MFA. Add RDP properties on the host pool to tune security (disable drive redirection unless needed):
PowerShell
1
2
3
4
# RDP properties: block drive and clipboard redirection to clients, allow printer
Update-AzWvdHostPool -ResourceGroupName$rg -Name'hp-avd-prod' `
-RdpProperty'drivestoredirect:s:;redirectclipboard:i:0;redirectprinters:i:1;'# Expected: host pool updated; new client connections pick up the properties
6. Validate the connection
Install the Windows App client (or use the web client at client.wvd.microsoft.com), sign in as the test user, and launch the desktop. Check the host pool's Insights workbook for connection success, and confirm the profile VHDX appears in the share after first sign-in.
Configuration Deep Dive
Pooled vs personal: pooled multi-session hosts maximize density and are the default for task workers; personal pools map a VM per user for developers or legacy apps that assume a dedicated machine.
Max session limit: start conservative (6-8 per 4-vCPU D-series with Microsoft 365 Apps) and tune from the Insights workbook — CPU contention hurts Teams calls first.
Scaling plans: define ramp-up, peak, ramp-down, and off-peak phases in local time; with force-logoff off, deallocation waits for sessions to drain.
Image strategy: start from the marketplace image, then rebuild monthly with Azure Image Builder — never patch golden images by hand.
Profile storage: premium file shares (Premium_ZRS) are the FSLogix baseline; size by IOPS (roughly 10 per user), not capacity, and keep the share in the host pool's region.
Drain mode: set hosts to drain before image updates so new sessions land elsewhere — AllowNewSession = $false per session host.
Real-World Enterprise Scenario
A 350-seat support organization replaced aging RDS servers with AVD in three weeks: one pooled host pool, 12 D4s v5 hosts, FSLogix profiles on a 1 TiB premium share, Office from the Microsoft 365 Apps image. A scaling plan deallocated hosts from 8 p.m. to 6 a.m., cutting compute roughly 40% versus always-on. The one misstep — drive redirection left enabled — was caught by the security review and closed with an RDP property change, not a rebuild.
PowerShell for Azure Virtual Desktop
Two scripts cover daily operations once the pool is live. First, a capacity and session report:
PowerShell
1
2
3
4
5
6
7
8
9
10
11
# Daily AVD capacity report: sessions per host, drain state, available capacity
Get-AzWvdSessionHost -ResourceGroupName$rg -HostPoolName'hp-avd-prod' |
Select-Object Name,
@{n='Sessions';e={$_.Session}},
@{n='MaxSessions';e={$_.MaxSessionLimit}},
@{n='AllowNew';e={$_.AllowNewSession}},
@{n='Status';e={$_.Status}} |
Sort-Object Sessions -Descending | Format-Table -AutoSize$totalSessions = (Get-AzWvdSessionHost -ResourceGroupName$rg -HostPoolName'hp-avd-prod' |
Measure-Object Session -Sum).Sum
# Expected: table of hosts with live session counts; $totalSessions = current load
Second, a maintenance helper that drains a host before patching and re-enables it after:
PowerShell
1
2
3
4
5
6
7
8
# Drain a session host for patching, then re-enable new sessions
Update-AzWvdSessionHost -ResourceGroupName$rg -HostPoolName'hp-avd-prod' `
-Name'hp-avd-prod/avd-0' -AllowNewSession$false
Start-Sleep -Seconds180 # let the broker stop sending new sessions# ...reimage/restart the VM, apply updates, validate...
Update-AzWvdSessionHost -ResourceGroupName$rg -HostPoolName'hp-avd-prod' `
-Name'hp-avd-prod/avd-0' -AllowNewSession$true# Expected: AllowNew flips false then true; users land on other hosts meanwhile
Troubleshooting
Symptom
Likely cause
Fix
User gets "We couldn't connect to the gateway because of an error"
Outbound 443 blocked from client, or broker issue
Verify client internet path and service health; test another network
"The user name or password is incorrect" on sign-in
User not assigned to the application group, or missing license
Check group membership and the Microsoft 365 license assignment
Sign-in takes minutes, temporary profile created
FSLogix cannot reach the profile share — permissions or Kerberos
Verify SMB Share Contributor RBAC, Entra Kerberos enablement, and share DNS resolution
Session host shows Unavailable in the pool
VM stopped, agent blocked, or registration token expired
Start the VM, check the Windows Agent and Boot Loader services, refresh the token
RemoteApp icon missing for one user
User assigned to the wrong application group
Confirm assignments on the correct RemoteApp group, wait for refresh
Poor Teams call quality on loaded hosts
Session limit set too high for the VM size
Lower MaxSessionLimit or scale up the SKU; review Insights CPU data
Visual Walkthrough
A repeatable monthly cadence beats artisanal snapshots.
Lifecycle LoopGolden Image Pipeline — Version by Version6/6
1
Base image versioned
Marketplace OS + language pack as the foundation layer.
Baseline settings baked in (or left to Intune — decide once).
sysprep
4
Sysprep + snapshot
Generalize; version-stamp the managed image.
distribute
5
Distribute to host pool
New VMs roll from the image with zero drift.
6
Monthly refresh cycle
Patch Tuesday wave rebuilds the pipeline — repeat.
Continuous cycle
Golden Image Pipeline — Version by Version. 1. Base image versioned: Marketplace OS + language pack as the foundation layer. — 2. Apps + agents layered: Line-of-business apps, AVD/FSLogix, monitoring agents. — 3. Hardening applied: Baseline settings baked in (or left to Intune — decide once). — 4. Sysprep + snapshot: Generalize; version-stamp the managed image. — 5. Distribute to host pool: New VMs roll from the image with zero drift. — 6. Monthly refresh cycle: Patch Tuesday wave rebuilds the pipeline — repeat.
Common Errors
NameAvailability conflict creating the host pool — object names are shared per subscription context; use a unique suffix per environment.
New-AzWvdRegistrationInfo : AuthorizationFailed — the identity lacks Desktop Virtualization Contributor on the host pool's resource group.
Session host joins the wrong pool — an old registration token embedded in the image or template; generate a fresh token and re-register.
FSLogix container locked after abrupt disconnect — orphaned VHD lock; log off the stale session from the portal before the profile reattaches.
Update-AzWvdWorkspace : PropertyChangeNotAllowed — application group references are updated as a full list; pass all IDs, not only the new one.
Best Practices
Entra join by default; keep domain join only for estates that genuinely need classic GPOs.
Store FSLogix profiles on premium file shares in the host pool's region.
Drive image builds through Azure Image Builder on a monthly cadence.
Use scaling plans from day one — the savings pay for the project.
Assign users only via security groups, never individual accounts.
Wire AVD Insights (Log Analytics) up at deployment, not after the first complaint.
Security Considerations
AVD concentrates remote access, so treat its identity surface as tier-1: Conditional Access with MFA (ideally phishing-resistant) on the Azure Virtual Desktop app, device-compliance conditions for privileged users, and no public inbound rules on session hosts — traffic is brokered over 443 outbound. Disable local admin, restrict clipboard and drive redirection with RDP properties, and keep profile shares behind private endpoints where the network allows. Review role assignments quarterly — Desktop Virtualization Contributor can read registration tokens.
FAQ
AVD or Windows 365 Cloud PC?
AVD suits pooled multi-session workloads and custom images at scale; Cloud PC is simpler per-user desktops with fixed SKUs. Many enterprises run both.
Can users install their own applications?
On pooled multi-session hosts, avoid per-user installs — they conflict across sessions. Publish via RemoteApp or MSIX App Attach.
Do we need a domain controller in Azure?
Not for Entra-joined hosts. AD DS or Domain Services only for legacy profiles or software that assumes domain membership.
How do we patch session hosts?
Azure Update Manager with maintenance configurations, one host drained at a time — the drain-mode script above.
What is the real cost driver?
Session host compute, which scaling plans can cut 30-40% for office-hours workloads; profile storage is minor when sized by IOPS.
Conclusion
A clean first AVD deployment is four objects, one share, and one policy: host pool, application group, workspace, FSLogix on Azure Files, and Conditional Access. Script the control plane from the start — the New-AzWvd cmdlets make the next host pool trivial — and let Insights data set session limits. Scaling plans and monthly image builds carry the operational load.
Comments
0No comments yet — be the first to share your thoughts.