Skip to content

Instantly share code, notes, and snippets.

@biacz
Created January 22, 2022 15:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save biacz/56ff10d892935170cc450da608faf0b7 to your computer and use it in GitHub Desktop.
Save biacz/56ff10d892935170cc450da608faf0b7 to your computer and use it in GitHub Desktop.
AzureFunction - Turn off inactive AVD SessionHosts
<#
.SYNOPSIS
Automated process to stop unused session hosts in a Azure Virtual Desktop (AVD) personal host pool.
.DESCRIPTION
This script is intended to automatically stop personal host pool session hosts in a Azure Virtual Desktop
host pool. The script will evaluate session hosts in a host pool and create a list of session hosts with
active connections. The script will then compare all session hosts in the personal host pool that are
powered on and not in drain mode. The script will shut down the session hosts that have no active connections.
.NOTES
Script is offered as-is with no warranty, expressed or implied.
Test it before you trust it
Author : Travis Roberts, Ciraltos llc
Website : www.ciraltos.com
update : Vikas - modified for multiple pools)
update : Niko - modified for multiple subscriptions as well as only selecting machines with a certain tag
ErrorCodes:
- 1 : General issue
- 2 : Not able to gather AVD pools
- 3 : Issue within the host pool cycle
- 4 : Issue with the session host cycle
#>
# Init / Declaration of variables
param($Timer)
$ErrorActionPreference = "Stop"
$AVDPools = @()
try {
# Cycling through all subscriptions that are enabled and have either wvdi or avd in the name.
# Change this according to your needs.
Get-AzSubscription | Where-Object { $_.State -eq "Enabled" -and $_.Name -match "wvdi" -or $_.Name -match "avd" } | foreach-object {
# Setting current subscription as context
set-azcontext -Subscription $_
# Gathering all AVDPools that are personal and cycle through them
try {
$AVDPools = Get-AzWvdHostPool | Where-Object { $_.HostPoolType -eq "Personal" }
}
catch {
Write-Error ("Not able to gather host pools:" + $_.Exception.message)
Exit 2
}
try {
foreach ($Pool in $AVDPools) {
# Init/Declare/Reset variables
$personalHP = $personalHPRG = $sessionHost = $null
$personalHP = $Pool.Name
# Extracting host pool resource group
$personalHPRG = ($Pool.Id).Split("/")[4]
Write-Host "RG: $personalHPRG PPool:$personalHP"
# Get the session hosts that have no session, allow login and are available
$inactiveSHs = (Get-AzWvdSessionHost -HostPoolName $personalHP -ResourceGroupName $personalHPRG `
| Where-Object { $_.AllowNewSession -eq $true -and $_.Session -ne 1 -and $_.Status -eq "Available"})
write-output "All SessionHosts that allow login and have no session"
$inactiveSHs.Name
# Cycling through each applicable session host and check for appropriate tags
foreach ($sessionHost in $inactiveSHs) {
# Extracting session host name for outputs
$sessionHostName = (($sessionHost).Name -split { $_ -eq '.' -or $_ -eq '/' })[1]
try {
# Stop the VM if its tagged as powermanaged
if ($(Get-AzResource -ResourceId $sessionHost.ResourceId).Tags["powermanaged"] -match "yes") {
write-verbose -message "Machine $sessionHostName is power managed, hence turning it off" -verbose
#Stop-AzVM -ErrorAction Stop -id $sessionHost.ResourceId -Force -NoWait
}
else {
# If its not power manged just continue
write-verbose -message "Machine $sessionHostName is not power managed, hence skipping it" -verbose
}
}
catch {
Write-Error ("Issue with the SessionHost cycle:" + $_.Exception.message)
Exit 4
}
}
}
}
catch {
Write-Error ("Issue with the HostPool cycle:" + $_.Exception.message)
Exit 3
}
}
}
catch {
Write-Error ("General error occured:" + $_.Exception.message)
Exit 1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment