
In modern enterprise environments, efficient management of virtual desktop resources is critical to controlling costs while maintaining consistent service levels. Workloads in Azure Virtual Desktop typically follow variable usage patterns throughout the day and week, making static scaling models inefficient. Please see Azure Virtual Desktop: How to set Up Azure Virtual Desktop Insights Monitoring [Part 03], and Azure Virtual Desktop: Connect to Session Hosts Using Entra ID [Part 04].
This guide focuses on implementing and monitoring session host autoscaling using Azure scaling plans. The goal is to dynamically adjust capacity based on demand, reducing unnecessary provisioning and improving overall cost efficiency.
The configuration and monitoring tasks are performed through the Azure portal. By the end of this guide, you will be able to implement and evaluate autoscaling for Azure Virtual Desktop, with a focus on cost optimization and operational efficiency.
Deploy and Configure Autoscale Scaling Plans in Azure Virtual Desktop
Assign RBAC to Azure Virtual Desktop service principal, and stop and deallocate session hosts
- Update host pool settings
- Create scaling plan Test autoscaling
- Disable autoscaling
Note: Autoscale requires granting the Azure Virtual Desktop service principal the Desktop Virtualization Power On Off Contributor RBAC role at the subscription scope to manage session host VM power states. Assigning the role at a lower scope (resource group, host pool, or VM) will break autoscale functionality.
Please see Azure Virtual Desktop: Deploy host pools and session hosts in the Azure [Part 01], and Azure Virtual Desktop: Manage Azure Virtual Desktop host pools and session hosts using the Azure portal [Part 02].
Assign the required RBAC role to an Azure Virtual Desktop service principal
This role is different from Desktop Virtualization Power On Contributor, which is used for Start VM on Connect.
Start a PowerShell session in Azure Cloud Shell, select the correct subscription if prompted, then retrieve the subscription ID and store it in $subId using (Get-AzSubscription).Id.
$subId = (Get-AzSubscription).Id
Create a $parameters hash table containing the RBAC role Desktop Virtualization Power On Off Contributor, the Azure Virtual Desktop service principal Application ID, and the subscription scope.
$parameters = @{ RoleDefinitionName = "Desktop Virtualization Power On Off Contributor" ApplicationId = "3*********************************7" Scope = "/subscriptions/$subId"}
Create the RBAC role assignment using the $parameters hash table with New-AzRoleAssignment.
New-AzRoleAssignment @parameters

Please see how to Fix an error occurred while attempting to start selected VM on Hyper-V, Failed to Upgrade VIHR Component: Failed to open deployer Service Management Port, and The Backup Was Safe: The Data Center Was not: A Real-World Lesson About Hidden Data Center Risks and Governance Failures.
Deallocate and Stop All Session Hosts
To evaluate autoscaling, all Azure Virtual Desktop session hosts will be stopped and deallocated. From the Azure portal, navigate to Azure Virtual Desktop, open Host pools, select XXXXX-hp1, go to Session hosts, select all session hosts, and stop them confirming the action.
The Stop button may be under the ellipsis (…) menu. Do not wait for session hosts to fully stop and deallocate, as the process can take about 2 minutes. Proceed to the next task immediately.




Configure Host Pool Settings
For pooled host pools, autoscale requires a configured MaxSessionLimit. In this guide, it is intentionally set low to demonstrate autoscaling behavior.
In the Azure portal, open the host pool XXXXX-hp1, go to Properties, set Max session limit to 1, and save the configuration.

Configure a Scaling Plan for Autoscale
In the Azure portal, go to Azure Virtual Desktop, open Scaling plans, then select + Create to start creating a new scaling plan.

On the Basics tab of the Create a scaling plan page, configure the required settings and proceed by selecting Next: Schedules.
| Setting | Value |
| Subscription | XXX-XXXX-XXXX |
| Resource group | RG-XXXX |
| Scaling plan name | scalingplan-XXXX |
| Region | Nome della regione di Azure in cui è stato distribuito l’ambiente Azure Virtual Desktop |
| Friendly name | scalingplan-XXXX |
| Time zone | Fuso orario locale della regione di Azure in cui è stato distribuito l’ambiente Azure Virtual Desktop |
| Host pool type | Pooled |
| Scaling method | Power management autoscaling |
Leave the Exclusion tag field empty; this can be used to exclude VMs with specific tags from autoscaling.


On the Schedule tab, add a schedule. Schedules define ramp-up, peak, ramp-down, and off-peak periods per day and are required for at least one weekday in a scaling plan.
| Phase | Description | Purpose in autoscaling |
|---|---|---|
| Ramp-up | Period when users start connecting and demand increases | Gradually powers on additional session hosts to handle rising load |
| Peak | Highest usage period with maximum active users | Keeps sufficient session hosts running to ensure performance and capacity |
| Ramp-down | Period when user activity decreases | Scales down unused session hosts to reduce cost while maintaining availability |
| Off-peak | Low or no usage period (often overnight/weekends) | Minimizes running session hosts, shutting down or deallocating most VMs to save costs |

On the General tab of the Add a schedule pane, modify the default settings as specified and proceed by selecting Next.
| Setting | Value |
| Time zone | the local time zone of your Azure Virtual Desktop environment (based on the region you selected earlier in this task) |
| Schedule name | week_schedule |
| Repeat on | 7 selected (select all days of the week) |
Note: The schedule applies to all days of the week, making it easier to evaluate autoscaling behavior.

On the Ramp-up tab of the Add a schedule pane, update the default settings as specified and select Next.
| Setting | Value |
| Start time (12 hour system) | your current time minus 1 hour |
| Load balancing algorithm | Breadth-first |
| Minimum percentage of hosts (%) | 30 |
| Capacity threshold (%) | 60 |
For pooled host pools, autoscale overrides the existing load-balancing settings and uses schedule-based balancing instead.
The Minimum percentage of hosts defines the minimum portion of session hosts that must be running during ramp-up and peak (values are rounded up to the nearest whole number).
The Capacity threshold determines when additional hosts are started or stopped based on utilization; for example, if set to 60%, new hosts are started once utilization exceeds that threshold.

On the Peak hours tab of the Add a schedule pane, update the default settings as specified and select Next.
| Setting | Value |
| Start time (12 hour system) | your current time plus 1 hour |
| Load balancing algorithm | Depth-first |
| Capacity threshold (%) | 60 |
Add a scheudle as shown below

The Capacity threshold (%) is shared across both Ramp-up and Peak hours configurations.
On the Ramp-down tab of the Add a schedule pane, update the default settings as specified and select Next.
| Setting | Value |
| Start time (12 hour system) | your current time plus 2 hours |
| Load balancing algorithm | Depth-first |
| Minimum percentage of active hosts (%) | 10 |
| Capacity threshold (%) | 80 |
| Force logoff users | No |
| Stop VMs when | VMs have no active or disconnected sessions |
During ramp-down and off-peak, Minimum percentage of active hosts defines the minimum number of session hosts kept running (rounded up).
The Capacity threshold (%) controls when VMs are turned off based on utilization—for example, excess hosts are deallocated when usage falls below the threshold.
Autoscale stops and deallocates session hosts when capacity is below the threshold and turning off VMs does not exceed it. It only shuts down hosts without active sessions (unless forced logoff is enabled during ramp-down) and never turns off hosts during ramp-up.

On the Off-peak hours tab of the Add a schedule pane, update the default settings as specified and select Add.
| Setting | Value |
| Start time (12 hour system) | your current time plus 3 hours |
| Load balancing algorithm | Depth-first |
| Capacity threshold (%) | 80 |
The Capacity threshold is shared between Ramp-down and Off-peak hours settings.

Return to the Schedule tab and select Next: Host pool assignments.

On the Host pool assignments tab, select az140-21-hp1, ensure Enable autoscale is enabled, then choose Review + create.

On the Review + Create page, select Create. Wait a few seconds for the autoscale configuration to complete.


Please see Enterprise Tape Library Administration: Control Path, Firmware, Media Management and Tape Operations, how to Repair a Corrupt SQL Server Database Without Data Loss, and Azure Application Gateway: Practical Configuration Guide.
Validate Autoscaling Operation
In the Azure portal, open host pool XXXXX-hp1, go to Session hosts, and verify that at least one session host shows Running in the Power state column. It may take a few minutes for the first session hosts to reach the Running state.
This behavior is expected because the scaling plan’s Ramp-up configuration ensures that at least one session host is always online. At this stage, host pool capacity is 1 (one running host), while used capacity remains 0% since there are no active user sessions.
Next, a single user session will be launched to evaluate the Ramp-up and Peak hours capacity threshold settings. This can be tested outside the Peak hours window because both phases share the same capacity threshold.

In the Windows App client, select Sign In and authenticate when prompted.

In the Windows App, go to Apps, then open Command Prompt by double-clicking its icon. When prompted, authenticate in the Windows Security dialog using your Microsoft Entra user account password.



A Command Prompt window should open shortly. At this point, host pool usage reaches 100%, exceeding the 60% capacity threshold, so autoscale should start an additional session host, reducing utilization to 50%. The third host remains stopped/deallocated since capacity is now below the threshold.
Next, the Ramp-down capacity threshold will be evaluated by adjusting its time window.

In the Azure portal, open the scaling plan XXXXX-scalingplan412e, go to Schedules → week_schedule, then in the Ramp-down tab adjust the Start time to a value between the Peak hours start time and the current time.
You may need to adjust the Peak hours start time as well to ensure the Ramp-down window fits correctly within the schedule.

In week_schedule, go to the Off-peak hours tab and select Save. Then return to the Command Prompt session connected to the host pool and run the provided command.

In the week_schedule pane, go to the Off-peak hours tab and click Save.
Switch to the Command Prompt window for the only RDP session connected to the host pool, and at the prompt, type the specified command and press Enter.
logoff

On the Azure Virtual Desktop | Host pools page, select the host pool XXXXx-hp1 from the list. In the Manage section of the left-hand menu, go to Session hosts. On the XXXXX-hp1 | Session hosts page, check the Power state of the session hosts and confirm that only one is currently shown as Running.

Please see Azure Managing Subscriptions with PowerShell: From Login-AzAccount to Resource Control and Private Endpoint Verification for Azure File Share”, and Azure Arc for SQL Server PAYG: Installation, Connectivity Requirements and Operational Best Practices.
Turn off autoscaling for a host pool
On the XXXX-scalingplan-LinkState page, go to Host pool assignments under the Manage section.
Select the host pool XXXXX-hp1, choose Unassign, and confirm the action in the dialog box.


This concludes the fourth part of the guide to Azure Virtual Desktop. Let’s now move on to the fifth part for the next steps.
I hope you have found this guide on “Azure Virtual Desktop: Implementing and Monitoring Session Hosts for Autoscaling – Part 05” very useful. Please feel free to leave a comment below. 🙂