How to automate AVD VM shutdown based on usage and disconnected state?

Alex 0 Reputation points

Hi folks. I am pretty new to Azure platform and I would really appreciate if someone could give me some tips on accomplishing the following objective in Azure Virtual Desktop: if a user has disconnected or logged out from a VM (Windows 10) and there is no business application or process running on the machine in disconnected state (the first thing that I can think of is to check if CPU/memory usage is below certain threshold), we (my team and I) want the VM to be shut down (stopped "deallocated" so it does not accrue cost if running idle) after let's say 30 minutes. We are most likely not the first ones to think of this to control the costs, so I would assume that there may be some already made solutions either by Microsoft or a third-party? We are currently testing with 1 machine, but I would assume this could be applied to a pool of AVD VMs?

I asked my friend ChatGPT to help with this objective, and this is what it said. How valid is this solution?

Here are the high-level steps to implement the PowerShell script to automatically shut down a VM in Azure Virtual Desktop if there are no connected users and CPU usage is low:

(1) Create an Azure Automation account: An Azure Automation account is required to run the PowerShell script. To create an Automation account, go to the Azure portal, navigate to the subscription where your Azure Virtual Desktop environment is, and click the "Create a resource" button. Search for "Automation" and follow the prompts to create an Automation account.

(2) Create a Runbook: Inside the Azure Automation account, create a new Runbook and give it a name.

(3) Paste the PowerShell script into the Runbook: Paste the PowerShell script we provided earlier into the Runbook's code editor.

(4) Save and publish the Runbook: After pasting the script into the Runbook, save it and then publish it. Publishing a Runbook makes it available to be executed.

(5) Create a schedule: Once the Runbook is published, it can be scheduled to run automatically. Click the "Schedules" option and create a new schedule that determines when the Runbook should run. For example, you can schedule it to run every 5 minutes or every hour, depending on your needs.

(6) Test the Runbook: After you've created the schedule, you can test the Runbook to make sure it's working properly. To test the Runbook, click the "Test pane" option, fill in the required parameters, and then run the test.

(7) Monitor the Runbook: Once the Runbook is scheduled to run, you can monitor its execution history and troubleshoot any issues if it fails to run.

That's it! Once the Runbook is scheduled and running, it will automatically shut down any Azure Virtual Desktop VMs that meet the specified conditions.

The script:

# Set the Azure subscription ID, resource group name, and VM name
$subscriptionId = "your_subscription_id"
$resourceGroupName = "your_resource_group_name"
$vmName = "your_vm_name"

# Authenticate to Azure

# Get the VM object
$vm = Get-AzVM -ResourceGroupName $resourceGroupName -Name $vmName

# Get the current CPU usage and connected user count
$cpuUsage = Get-AzMetric -ResourceId $vm.Id `
    -TimeGrain 00:01:00 `
    -MetricName Percentage CPU `
    -StartTime (Get-Date).AddMinutes(-5) `
    -EndTime (Get-Date) `
    | Select-Object -ExpandProperty Data |
    Select-Object -ExpandProperty Average |
    Measure-Object -Average |
    Select-Object -ExpandProperty Average
$connectedUserCount = Get-AzWvdSessionHost -ResourceGroupName $resourceGroupName `
    -WorkspaceName "your_workspace_name" `
    -HostPoolName "your_host_pool_name" `
    -Name $vmName `
    | Select-Object -ExpandProperty UserSession |
    Measure-Object |
    Select-Object -ExpandProperty Count

# Check if the conditions are met
if ($connectedUserCount -eq 0 -and $cpuUsage -lt 7) {
    # If both conditions are true, deallocate the VM
    Stop-AzVM -ResourceGroupName $resourceGroupName -Name $vmName -Force

Azure Virtual Desktop
Azure Virtual Desktop
A Microsoft desktop and app virtualization service that runs on Azure. Previously known as Windows Virtual Desktop.
1,389 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Johan Vanneuville 161 Reputation points MVP

    You can use the scaling plans from Microsoft in the Azure portal or you can leverage Nerdio. Nerdio has several options to do the scaling.

    I hope this helps you. Mark it as Accepted answer if it does.

    0 comments No comments

  2. Prrudram-MSFT 22,576 Reputation points

    Hi @Alex

    Assuming this is personal hosts that you're considering running it on, you could look at this solution: Deallocate VM on user logoff - Microsoft Community Hub. It's old but still gives you a good basis to facilitate the deallocate action. The challenge will be the determination of what's considered idle as you understand. 

    Realistically it's not going to be practical to detect the idle state to make the decision, you're best to either specifically build it to check the desired process and whether it's running or the you are better off having a host either log disconnected users off after a timeout (can be done via GPO/Intune) or have pools split to handle users who may be required to operate long running processes when disconnected (or decide which is more important, user inconvenience or better user education and cost savings). 

    If you're just wanting to reduce cost, and can remove the running process check, we have the ability to perform autoscaling today as part of the service (pooled hosts), with backlog work for personal scaling still in planning stages.
    If you're blocked by this, please let us know.

    Hope this helps!

    If this response has answered your query, please 'Accept as Answer' and upvote using "Thumbs-up" so that the relevancy of this post will improve when anyone in the community search for a similar query.