Azure Virtual Desktop Auto Shutdown and Power On

Madhukar Mali 0 Reputation points
2024-06-03T06:49:38.01+00:00

Hello All,

We're currently managing a pool of 30-40 VMs, and to optimize our licensing costs with Microsoft, we're planning to shut down idle VDI VMs that haven't been used in over 8 hours. To automate this process, could you assist us with a PowerShell script to power off these unused VDI VMs?

Azure Virtual Machines
Azure Virtual Machines
An Azure service that is used to provision Windows and Linux virtual machines.
7,385 questions
Azure Automation
Azure Automation
An Azure service that is used to automate, configure, and install updates across hybrid environments.
1,160 questions
Azure Virtual Desktop
Azure Virtual Desktop
A Microsoft desktop and app virtualization service that runs on Azure. Previously known as Windows Virtual Desktop.
1,411 questions
PowerShell
PowerShell
A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
2,223 questions
0 comments No comments
{count} votes

3 answers

Sort by: Most helpful
  1. innovation gadget 155 Reputation points
    2024-06-03T09:06:35.8366667+00:00

    Hello

    To automate the process of shutting down idle VDI (Virtual Desktop Infrastructure) VMs that haven't been used in over 8 hours, you can use Azure PowerShell in combination with Azure Automation. Below is a PowerShell script that will help you achieve this. The script checks the idle time for each VM in the pool and powers off the VMs that have been idle for more than 8 hours.

    Steps to Implement the Solution

    1. Create an Azure Automation Account:
      • In the Azure portal, navigate to "Automation Accounts" and create a new Automation Account.
    2. Import Required Modules:
      • In the Automation Account, go to "Modules" and ensure you have the Az.Compute and Az.Accounts modules imported. If not, import them.
    3. Create a Runbook:
      • In the Automation Account, go to "Runbooks" and create a new PowerShell Runbook.
    4. Add the PowerShell Script to the Runbook:
      • Use the script provided below to check the idle time of each VM and shut down the ones that have been idle for more than 8 hours.
    # Import the required modules
    Import-Module Az.Compute
    Import-Module Az.Accounts
    
    # Authenticate to Azure
    # This script assumes you have set up a Run As account in your Azure Automation account
    $Connection = Get-AutomationConnection -Name "AzureRunAsConnection"
    Connect-AzAccount -ServicePrincipal -TenantId $Connection.TenantId -ApplicationId $Connection.ApplicationId -CertificateThumbprint $Connection.CertificateThumbprint
    
    # Define the resource group and the list of VMs
    $resourceGroupName = "YourResourceGroupName"
    $vmNames = @("VM1", "VM2", "VM3", ...) # Add all your VM names here
    
    # Function to get the last logon time of a VM
    function Get-LastLogonTime {
        param (
            [string]$vmName
        )
        # Get the diagnostics logs or performance metrics to determine the last logon time
        # For simplicity, this example uses a placeholder value
        # Replace this with the actual logic to get the last logon time
        $lastLogonTime = (Get-Date).AddHours(-($RANDOM % 24)) # Placeholder logic
        return $lastLogonTime
    }
    
    # Define the idle time threshold (8 hours)
    $idleTimeThreshold = 8
    
    foreach ($vmName in $vmNames) {
        try {
            $vm = Get-AzVM -ResourceGroupName $resourceGroupName -Name $vmName -Status
            $lastLogonTime = Get-LastLogonTime -vmName $vmName
    
            if ($vm.Statuses[1].Code -eq "PowerState/running") {
                $currentTime = Get-Date
                $idleTime = ($currentTime - $lastLogonTime).TotalHours
    
                if ($idleTime -gt $idleTimeThreshold) {
                    Write-Output "VM $vmName has been idle for $idleTime hours. Shutting down..."
                    Stop-AzVM -ResourceGroupName $resourceGroupName -Name $vmName -Force
                } else {
                    Write-Output "VM $vmName has been idle for $idleTime hours. No action required."
                }
            } else {
                Write-Output "VM $vmName is not running. No action required."
            }
        } catch {
            Write-Error "An error occurred while processing VM $vmName: $_"
        }
    }
    
    
    

    Explanation

    Authentication:

    • The script uses an Azure Automation Run As account for authentication. Make sure you have set up this account in your Automation Account.

    VM List and Resource Group:

      - Replace **`YourResourceGroupName`** with the name of your resource group.
      
         - List all your VMs in the **`$vmNames`** array.
         
         **Get Last Logon Time:**
         
            - The **`Get-LastLogonTime`** function is a placeholder. You need to replace the placeholder logic with actual logic to get the last logon time of a VM. This could involve querying logs or performance metrics.
            
            **Idle Time Check:**
            
               - The script checks if the VM has been running and compares the current time with the last logon time. If the idle time exceeds 8 hours, the VM is shut down.
               
               **Runbook Execution:**
               
                  - Save and publish the Runbook in Azure Automation. You can then schedule this Runbook to run at regular intervals, such as every hour.
                  
    

    Scheduling the Runbook

    1. In the Azure Automation Account, go to "Runbooks".
    2. Select the Runbook you created and click "Schedules".
    3. Add a new schedule to run the Runbook at your desired intervals (e.g., every hour).

    By following these steps and customizing the provided script, you can automate the shutdown of idle VDI VMs in Azure, optimizing your licensing costs effectively.


  2. Udayashankar K.N 0 Reputation points Microsoft Employee
    2024-06-05T12:39:47.3533333+00:00

    Hi there are 2 ways to do it one to shutdown the VM based on the usage and the state of it present and also powering off the VM during the non business hours

    https://learn.microsoft.com/en-us/azure/virtual-machines/auto-shutdown-vm?tabs=portal

    Poweirng off the VM based on the usage.

    https://learn.microsoft.com/en-us/answers/questions/1180844/how-to-automate-avd-vm-shutdown-based-on-usage-and

    0 comments No comments

  3. Prrudram-MSFT 22,921 Reputation points
    2024-06-10T11:21:48.0666667+00:00

    Hi @Madhukar MaliIf you are looking to save the deployment costs with, check out Autoscale feature for AVD. Autoscale lets you scale your session host virtual machines (VMs) in a host pool up or down according to schedule to optimize deployment costs.

    Reference: https://learn.microsoft.com/en-us/azure/virtual-desktop/autoscale-scenarios

    Important: For scaling plan schedule, make sure you understand usage patterns before defining your schedule. You'll need to schedule around the following times of day:

    • Ramp-up: the start of the day, when usage picks up.
    • Peak hours: the time of day when usage is expected to be at its highest.
    • Ramp-down: when usage tapers off. This is usually when you shut down your VMs to save costs.
    • Off-peak hours: the time of the day when usage is expected to be at its lowest.

    Also, I would like to know how starting/stopping VMs would saves the licensing costs for AVD?

    If I have answered your query, please click "Accept as answer" as a token of appreciation

    0 comments No comments