FunctionApp/Modules/SessionHostReplacer/functions/Get-SHRHostPoolDecision.ps1 (102 lines of code) (raw):

function Get-SHRHostPoolDecision { <# .SYNOPSIS This function will decide how many session hosts to deploy and if we should decommission any session hosts. #> [CmdletBinding()] param ( # Session hosts to consider [Parameter()] [array] $SessionHosts = @(), # Running deployments [Parameter()] $RunningDeployments, # Target age of session hosts in days - after this many days we consider a session host for replacement. [Parameter()] [int] $TargetVMAgeDays = (Get-FunctionConfig _TargetVMAgeDays), # Target number of session hosts in the host pool. If we have more than or equal to this number of session hosts we will decommission some. [Parameter()] [int] $TargetSessionHostCount = (Get-FunctionConfig _TargetSessionHostCount), [Parameter()] [int] $TargetSessionHostBuffer = (Get-FunctionConfig _TargetSessionHostBuffer), # Latest image version [Parameter()] [PSCustomObject] $LatestImageVersion, # Should we replace session hosts on new image version [Parameter()] [bool] $ReplaceSessionHostOnNewImageVersion = (Get-FunctionConfig _ReplaceSessionHostOnNewImageVersion), # Delay days before replacing session hosts on new image version [Parameter()] [int] $ReplaceSessionHostOnNewImageVersionDelayDays = (Get-FunctionConfig _ReplaceSessionHostOnNewImageVersionDelayDays) ) # Basic Info Write-PSFMessage -Level Host -Message "We have {0} session hosts (included in Automation)" -StringValues $SessionHosts.Count # Identify Session hosts that should be replaced if ($TargetVMAgeDays -gt 0) { $targetReplacementDate = (Get-Date).AddDays(-$TargetVMAgeDays) [array] $sessionHostsOldAge = $SessionHosts | Where-Object { $_.DeployTimestamp -lt $targetReplacementDate } Write-PSFMessage -Level Host -Message "Found {0} session hosts to replace due to old age. {1}" -StringValues $sessionHostsOldAge.Count, ($sessionHostsOldAge.VMName -join ',') } if ($ReplaceSessionHostOnNewImageVersion) { $latestImageAge = (New-TimeSpan -Start $LatestImageVersion.Date -End (Get-Date -AsUTC)).TotalDays Write-PSFMessage -Level Host -Message "Latest Image {0} is {1:N0} days old." -StringValues $LatestImageVersion.Version, $latestImageAge if ($latestImageAge -ge $ReplaceSessionHostOnNewImageVersionDelayDays) { Write-PSFMessage -Level Host -Message "Latest Image age is older than (or equal) New Image Delay value {0}" -StringValues $ReplaceSessionHostOnNewImageVersionDelayDays [array] $sessionHostsOldVersion = $sessionHosts | Where-Object { $_.ImageVersion -ne $LatestImageVersion.Version } Write-PSFMessage -Level Host -Message "Found {0} session hosts to replace due to new image version. {1}" -StringValues $sessionHostsOldVersion.Count, ($sessionHostsOldVersion.VMName -Join ',') } } [array] $sessionHostsToReplace = ($sessionHostsOldAge + $sessionHostsOldVersion) | Select-Object -Property * -Unique Write-PSFMessage -Level Host -Message "Found {0} session hosts to replace in total. {1}" -StringValues $sessionHostsToReplace.Count, ($sessionHostsToReplace.VMName -join ',') # Good Session Hosts $goodSessionHosts = $SessionHosts | Where-Object { $_.VMName -notin $sessionHostsToReplace.VMName } $sessionHostsCurrentTotal = ([array]$goodSessionHosts.VMName + [array]$runningDeployments.SessionHostNames ) | Select-Object -Unique Write-PSFMessage -Level Host -Message "We have {0} good session hosts including {1} session hosts being deployed" -StringValues $sessionHostsCurrentTotal.Count, $runningDeployments.SessionHostNames.Count Write-PSFMessage -Level Host -Message "We target having {0} session hosts in good shape" -StringValues $TargetSessionHostCount Write-PSFMessage -Level Host -Message "We have a buffer of {0} session hosts more than the target." -StringValues $TargetSessionHostBuffer $weCanDeployUpTo = $TargetSessionHostCount + $TargetSessionHostBuffer - $SessionHosts.count - $RunningDeployments.SessionHostNames.Count if ($weCanDeployUpTo -ge 0) { Write-PSFMessage -Level Host -Message "We can deploy up to {0} session hosts" -StringValues $weCanDeployUpTo $weNeedToDeploy = $TargetSessionHostCount - $sessionHostsCurrentTotal.Count if ($weNeedToDeploy -gt 0) { Write-PSFMessage -Level Host -Message "We need to deploy {0} new session hosts" -StringValues $weNeedToDeploy $weCanDeploy = if ($weNeedToDeploy -gt $weCanDeployUpTo) { $weCanDeployUpTo } else { $weNeedToDeploy } # If we need to deploy 10 machines, and we can deploy 5, we should only deploy 5. Write-PSFMessage -Level Host -Message "Buffer allows deploying {0} session hosts" -StringValues $weCanDeploy } else { $weCanDeploy = 0 Write-PSFMessage -Level Host -Message "We have enough session hosts in good shape." } } else { Write-PSFMessage -Level Host -Message "Buffer is full. We can not deploy more session hosts" $weCanDeploy = 0 } $weCanDelete = $SessionHosts.Count - $TargetSessionHostCount if ($weCanDelete -gt 0) { Write-PSFMessage -Level Host -Message "We need to delete {0} session hosts" -StringValues $weCanDelete if ($weCanDelete -gt $sessionHostsToReplace.Count) { Write-PSFMessage -Level Host -Message "Host pool is over populated" $goodSessionHostsToDeleteCount = $weCanDelete - $sessionHostsToReplace.Count Write-PSFMessage -Level Host -Message "We will delete {0} good session hosts" -StringValues $goodSessionHostsToDeleteCount $selectedGoodHostsTotDelete = [array] ($goodSessionHosts | Sort-Object -Property Session | Select-Object -First $goodSessionHostsToDeleteCount) Write-PSFMessage -Level Host -Message "Selected the following good session hosts to delete: {0}" -StringValues ($selectedGoodHostsTotDelete.VMName -join ',') } else { $selectedGoodHostsTotDelete = @() Write-PSFMessage -Level Host -Message "Host pool is not over populated" } $sessionHostsPendingDelete = ($sessionHostsToReplace + $selectedGoodHostsTotDelete) | Select-Object -First $weCanDelete Write-PSFMessage -Level Host -Message "The following Session Hosts are now pending delete: {0}" -StringValues ($SessionHostsPendingDelete.VMName -join ',') } elseif ($sessionHostsToReplace.Count -gt 0) { Write-PSFMessage -Level Host -Message "We need to delete {0} session hosts but we don't have enough session hosts in the host pool." -StringValues ($sessionHostsToReplace.Count) } else { Write-PSFMessage -Level Host -Message "We do not need to delete any session hosts" } [PSCustomObject]@{ PossibleDeploymentsCount = $weCanDeploy PossibleSessionHostDeleteCount = $weCanDelete SessionHostsPendingDelete = $sessionHostsPendingDelete ExistingSessionHostVMNames = ([array]$SessionHosts.VMName + [array]$runningDeployments.SessionHostNames) | Select-Object -Unique } }