FunctionApp/Modules/SessionHostReplacer/functions/Remove-SHRSessionHost.ps1 (94 lines of code) (raw):

function Remove-SHRSessionHost { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] $SessionHostsPendingDelete, [Parameter()] [string] $ResourceGroupName = (Get-FunctionConfig _HostPoolResourceGroupName), [Parameter()] [string] $HostPoolName = (Get-FunctionConfig _HostPoolName), [Parameter()] [int] $DrainGracePeriodHours = (Get-FunctionConfig _DrainGracePeriodHours), [Parameter()] [string] $TagPendingDrainTimeStamp = (Get-FunctionConfig _Tag_PendingDrainTimestamp), [Parameter()] [string] $TagScalingPlanExclusionTag = (Get-FunctionConfig _Tag_ScalingPlanExclusionTag), [Parameter()] [bool] $RemoveEntraDevice, [Parameter()] [bool] $RemoveIntuneDevice ) foreach ($sessionHost in $SessionHostsPendingDelete) { # Does the session host currently have sessions? # No sessions => Delete + Remove from host pool # Is the session host in drain mode? # Yes => Is the drain grace period tag old? => Delete + Remove from host pool # NO => Set drain mode + Message users + Set tag $drainSessionHost = $false $deleteSessionHost = $false if ($sessionHost.Session -eq 0) { #Does the session host currently have sessions? # No sessions => Delete + Remove from host pool Write-PSFMessage -Level Host -Message 'Session host {0} has no sessions.' -StringValues $sessionHost.FQDN $deleteSessionHost = $true } else { Write-PSFMessage -Level Host -Message 'Session host {0} has {1} sessions.' -StringValues $sessionHost.FQDN, $sessionHost.Session if (-Not $sessionHost.AllowNewSession) { # Is the session host in drain mode? Write-PSFMessage -Level Host -Message 'Session host {0} is in drain mode.' -StringValues $sessionHost.FQDN if ($sessionHost.PendingDrainTimeStamp) { #Session host has a drain timestamp Write-PSFMessage -Level Host -Message 'Session Host {0} drain timestamp is {1}' -StringValues $sessionHost.FQDN, $sessionHost.PendingDrainTimeStamp $maxDrainGracePeriodDate = $sessionHost.PendingDrainTimeStamp.AddHours($DrainGracePeriodHours) Write-PSFMessage -Level Host -Message 'Session Host {0} can stay in grace period until {1}' -StringValues $sessionHost.FQDN, $maxDrainGracePeriodDate.ToUniversalTime().ToString('o') if ($maxDrainGracePeriodDate -lt (Get-Date)) { Write-PSFMessage -Level Host -Message 'Session Host {0} has exceeded the drain grace period.' -StringValues $sessionHost.FQDN $deleteSessionHost = $true } else { Write-PSFMessage -Level Host -Message 'Session Host {0} has not exceeded the drain grace period.' -StringValues $sessionHost.FQDN } } else { Write-PSFMessage -Level Host -Message 'Session Host {0} does not have a drain timestamp.' -StringValues $sessionHost.FQDN $drainSessionHost = $true } } else { Write-PSFMessage -Level Host -Message 'Session host {0} in not in drain mode. Turning on drain mode.' -StringValues $sessionHost.Name $drainSessionHost = $true } } if ($drainSessionHost) { Write-PSFMessage -Level Host -Message 'Turning on drain mode.' Update-AzWvdSessionHost -ResourceGroupName $ResourceGroupName -HostPoolName $HostPoolName -Name $sessionHost.FQDN -AllowNewSession:$false -ErrorAction Stop $drainTimestamp = (Get-Date).ToUniversalTime().ToString('o') Write-PSFMessage -Level Host -Message 'Setting drain timestamp on tag {0} to {1}.' -StringValues $TagPendingDrainTimeStamp, $drainTimestamp $null = Update-AzTag -ResourceId $sessionHost.ResourceId -Tag @{$TagPendingDrainTimeStamp = $drainTimestamp } -Operation Merge if ($TagScalingPlanExclusionTag -ne ' ') { # This is string with a single space. Write-PSFMessage -Level Host -Message 'Setting scaling plan exclusion tag {0} to {1}.' -StringValues $TagScalingPlanExclusionTag, $true $null = Update-AzTag -ResourceId $sessionHost.ResourceId -Tag @{$TagScalingPlanExclusionTag = $true } -Operation Merge } Write-PSFMessage -Level Host -Message 'Notifying Users' Send-SHRDrainNotification -SessionHostName ($sessionHost.FQDN) } if ($deleteSessionHost) { Write-PSFMessage -Level Host -Message 'Deleting session host {0}...' -StringValues $sessionHost.Name if ($RemoveEntraDevice) { Write-PSFMessage -Level Host -Message 'Deleting device from Entra ID' Remove-SHRSessionHostEntraDevice -VMName $sessionHost.VMName } if ($RemoveIntuneDevice) { Write-PSFMessage -Level Host -Message 'Deleting device from Intune' Remove-SHRSessionHostIntuneDevice -VMName $sessionHost.VMName } Write-PSFMessage -Level Host -Message 'Removing Session Host from Host Pool {0}' -StringValues $HostPoolName Remove-AzWvdSessionHost -ResourceGroupName $ResourceGroupName -HostPoolName $HostPoolName -Name $sessionHost.FQDN -Force -ErrorAction Stop Write-PSFMessage -Level Host -Message "Deleting VM: {0}..." -StringValues $sessionHost.ResourceId $null = Remove-AzVM -Id $sessionHost.ResourceId -ForceDeletion $true -Force -NoWait -ErrorAction Stop # We are not deleting Disk and NIC as the template should mark the delete option for these resources. } } }