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
- Create an Azure Automation Account:
- In the Azure portal, navigate to "Automation Accounts" and create a new Automation Account.
- Import Required Modules:
- In the Automation Account, go to "Modules" and ensure you have the
Az.Compute
andAz.Accounts
modules imported. If not, import them.
- In the Automation Account, go to "Modules" and ensure you have the
- Create a Runbook:
- In the Automation Account, go to "Runbooks" and create a new PowerShell Runbook.
- 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
- In the Azure Automation Account, go to "Runbooks".
- Select the Runbook you created and click "Schedules".
- 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.