Azure Virtual Desktop ships 14 built-in RBAC roles and almost every AVD permission problem comes from picking the wrong one, assigning it at the wrong scope, or missing a required pairing. This cheatsheet maps each role to the job it exists for, gives you the assignment commands, and covers the two service-principal roles that autoscale and Start VM on Connect refuse to work without.
πΊοΈ The 14 Roles at a Glance
Every AVD-specific role starts with "Desktop Virtualization". Here's the full set and who each one is for:
| Role | Who it's for | One-line job description |
|---|---|---|
| Desktop Virtualization Contributor | AVD platform admins | Manage all AVD objects (not user assignment, not VMs) |
| Desktop Virtualization Reader | Auditors, monitoring | View everything, change nothing |
| Desktop Virtualization User | End users | Launch desktops and apps from an application group |
| Host Pool Contributor | Host pool admins | Manage host pool settings end to end |
| Host Pool Reader | Support, ops review | View host pool config |
| Application Group Contributor | App publishers | Manage app groups and published apps |
| Application Group Reader | Support | View app group config |
| Workspace Contributor | Workspace admins | Manage workspaces users subscribe to |
| Workspace Reader | Support | View workspaces |
| User Session Operator | Helpdesk | Message, disconnect, and log off user sessions |
| Session Host Operator | L2 ops | View and remove session hosts, set drain mode |
| Power On Contributor | AVD service principal | Lets the AVD service start VMs (Start VM on Connect) |
| Power On Off Contributor | AVD service principal | Lets the AVD service start and stop VMs (autoscale) |
| Virtual Machine Contributor (Desktop Virtualization) | AVD service principal | Full VM lifecycle for the AVD service (create, delete, update, start, stop) |
Notice that three of the 14 roles are not for humans at all. The Power On, Power On Off, and Desktop Virtualization Virtual Machine Contributor roles exist for the Azure Virtual Desktop service principal so the platform can manage session host power state for you.
π― Scenario Cheatsheet: "I Need Someone To..."
This is the table I wish existed during every AVD engagement:
| The job | Assign this | At this scope | Also needs |
|---|---|---|---|
| Log off or message stuck users (helpdesk) | User Session Operator | Host pool | Nothing else |
| Drain and remove session hosts | Session Host Operator | Host pool | VM roles if they also deallocate VMs |
| Publish and manage RemoteApps | Application Group Contributor | App group or RG | User Access Administrator to assign users |
| Assign users to desktops/apps | User Access Administrator | App group | Pairs with any Contributor role |
| Manage host pool settings (RDP props, load balancing) | Host Pool Contributor | Host pool or RG | VM Contributor if they build session hosts |
| Full AVD administration | Desktop Virtualization Contributor | Resource group | User Access Administrator + Virtual Machine Contributor |
| Let users actually connect | Desktop Virtualization User | Application group | Nothing else (this IS the end-user role) |
| Read-only audit of the whole estate | Desktop Virtualization Reader | Subscription or RG | Nothing else |
| Start VM on Connect | Power On Contributor | Subscription or RG with the VMs | Assigned to the Azure Virtual Desktop service principal |
| Autoscale via scaling plans | Power On Off Contributor | Subscription or RG with the VMs | Assigned to the Azure Virtual Desktop service principal |
The number one AVD permission mistake: assigning Desktop Virtualization Contributor and expecting it to do everything. It cannot assign users to application groups (that needs User Access Administrator) and it cannot create or manage the session host VMs (that needs Virtual Machine Contributor). AVD-object management and VM management are deliberately separate permission planes.
β‘ Assignment Commands
Assign a role to a helpdesk group at host pool scope:
# Get the host pool resource ID
HP_ID=$(az desktopvirtualization hostpool show \
--name hp-prod-canadacentral \
--resource-group rg-avd-prod \
--query id -o tsv)
# Helpdesk: session management only
az role assignment create \
--assignee-object-id <helpdesk-group-object-id> \
--assignee-principal-type Group \
--role "Desktop Virtualization User Session Operator" \
--scope $HP_IDLet end users launch their desktop (application group scope):
az role assignment create \
--assignee-object-id <users-group-object-id> \
--assignee-principal-type Group \
--role "Desktop Virtualization User" \
--scope $(az desktopvirtualization applicationgroup show \
--name ag-prod-desktop \
--resource-group rg-avd-prod \
--query id -o tsv)Grant the AVD service principal the power roles (Start VM on Connect and autoscale):
# Find the Azure Virtual Desktop service principal
AVD_SP=$(az ad sp list --display-name "Azure Virtual Desktop" \
--query "[?appDisplayName=='Azure Virtual Desktop'].id" -o tsv)
# Start VM on Connect needs start only
az role assignment create \
--assignee-object-id $AVD_SP \
--assignee-principal-type ServicePrincipal \
--role "Desktop Virtualization Power On Contributor" \
--scope /subscriptions/<sub-id>/resourceGroups/rg-avd-prod
# Scaling plans need start AND stop
az role assignment create \
--assignee-object-id $AVD_SP \
--assignee-principal-type ServicePrincipal \
--role "Desktop Virtualization Power On Off Contributor" \
--scope /subscriptions/<sub-id>/resourceGroups/rg-avd-prodScope these service principal assignments to the resource group holding your session host VMs, not the whole subscription, unless your VMs genuinely span resource groups. Autoscale failing with authorization errors is almost always this assignment missing or scoped to the wrong resource group.
π§ Scope Rules That Save You Later
- Assign to groups, never individuals. Helpdesk turnover shouldn't mean role assignment archaeology
- Host pool scope for session work, app group scope for user access. User Session Operator at subscription scope means helpdesk can log off the CFO in any environment including prod pilots. Keep blast radius small
- Readers first. Most "I need access to AVD" requests are satisfied by Desktop Virtualization Reader. Start there and upgrade on evidence
- Separate prod and dev by resource group so a single role assignment can't cross environments
π Roles Are Half the Story
RBAC controls who can manage and launch AVD. It does not control the conditions under which they connect. That's Conditional Access, and AVD has two separate authentication flows that policies need to handle correctly. I covered the full setup in Implementing Conditional Access for Azure Virtual Desktop, and there's a video walkthrough:
Implementing Conditional Access Policy for AVD
The two AVD authentication flows and how to build Conditional Access policies that secure both without locking users out.
π Official References
| Resource | What's There |
|---|---|
| Built-in Azure RBAC roles for AVD | Every role with its full permission list and role IDs |
| Assign RBAC roles to the AVD service principals | The service principal assignment walkthrough |
| Azure RBAC documentation | Scopes, deny assignments, and how role evaluation works |
Print the scenario table, pin it next to your host pool naming standard, and most AVD access requests become a two-minute job. π₯οΈ