Logoff Sessions Pending Image in Horizon

I recently received a request from a follower, asking if it is possible to script logoffs for any Instant Clone desktops that are pending an image update. Currently they have to manually go through the admin portal and log them all off, not a quick task when dealing with thousands of sessions.

We can certainly do this with a script, using PowerCLI and the VMware.HV.Helper modules. Note that those are prerequisites for this script. I also added a 10 and 1 minute warning message prior to the logoff, as well as the ability to do logoffs in chunks using the Split-Array function. This may be required because logoffs do consume CPU resources, so you don’t want to go overboard on the amount of simultaneous logoffs. To adjust this, simply change the “parts” variable. I currently have it set to 2, so it will send message to half the desktops pending an image change, wait 10 minutes, log them off, and repeat for the second half.

Just set your CS FQDN and how many parts you want to split your logoffs in. For example, if we have 9 sessions to logoff with 3 parts, it will do 3+3+3 with 10 minute waits prior to logoff, so 30 minutes total runtime.

Here is the script – hopefully you find it helpful. If you have any feedback or want to see any other scripts, please let me know at nick@nicksitblog.com!

####### VARIABLES #######
# Input a CS FQDN here:
$ConnectionServer = "CS.FQDN"

# How many sections do you want to split the logoff? Each section will take around 10 minutes to complete to ensure we give adequate warning to the user. This also ensures we do not consume too much CPU with logoffs.
$parts = 2

####### END VARIABLES #######

Connect-HVServer $ConnectionServer

# Calculate how long script will take based on logoff parts and output total time. 
$ScriptTime = $parts*10

Write-Host -ForegroundColor Green "This script will take around $ScriptTime minutes to complete!"

#Get machines with push image task
$pendingImageMachines = Get-HVMachine | where-object {$_.ManagedMachineData.ViewComposerData.Operation -eq "PUSH_IMAGE"}
# Get session IDs from these pending image machines
$PendingImagesessionIDs = $pendingImageMachines.base.Session
# Populate hvservices with extension data
$hvservices = $global:DefaultHVServers.ExtensionData


# Create an array of arrays to use for logoff chunks. Using this excellent function:
# https://gallery.technet.microsoft.com/scriptcenter/Split-an-array-into-parts-4357dcc1

Function Split-Array {
 
 param($inArray,[int]$parts,[int]$size)
 
  if ($parts) {
    $PartSize = [Math]::Ceiling($inArray.count / $parts)
  }
  if ($size) {
    $PartSize = $size
    $parts = [Math]::Ceiling($inArray.count / $size)
  }

  $outArray = @()
  for ($i=1; $i -le $parts; $i++) {
    $start = (($i-1)*$PartSize)
    $end = (($i)*$PartSize) - 1
    if ($end -ge $inArray.count) {$end = $inArray.count}
    $outArray+=,@($inArray[$start..$end])
  }
  return ,$outArray

  }

$chunkSessions = Split-Array -inArray $PendingImagesessionIDs -parts $parts

Foreach ($chunkSession in $chunkSessions)
{
$hvservices.session.session_SendMessages($chunkSession,"INFO","Your desktop is scheduled for maintenance! Please logoff and back in now or you will be logged off in 10 minutes! Thank you!")
Write-Host -ForegroundColor Green "Sending message to" $chunksession.count "sessions! Waiting 10 minutes until logoff..."
Start-sleep -Seconds 540
Write-Host -ForegroundColor Green "Sending 1 minute warning message to" $chunksession.count "sessions!"
$hvservices.session.session_SendMessages($chunkSession,"INFO","Your desktop is scheduled for maintenance! Please logoff and back in now or you will be logged off in 1 minute! Thank you!")
Start-sleep -seconds 60
Write-Host -ForegroundColor Green "Logging off" $chunksession.count "sessions!"
$hvservices.session.Session_LogoffSessions($chunkSession)
}
Write-Host "All done! We sent logoffs to" $PendingImagesessionIDs.count "sessions!"
Disconnect-HVServer * -Confirm:$false