A Better Script to Perform Horizon Instant Clone Maintenance using PowerCLI

I have long loathed the somewhat archaic method you have to use to put hosts into maintenance mode when being used by Horizon and especially Instant Clones. It’s not intuitive, it’s difficult to find, and there’s no GUI option.

In a lab setting such as mine, it can be especially annoying because I have to spin things up and down often since I’m rebuilding things regularly and keeping on top of the latest releases.

In order to properly shut down a cluster for instant clones, you have to do a few things to make it happen:

  • Disable the pool
  • Disable provisioning of the pool
  • Remove all machines
  • Put the host into Instant Clone maintenance mode
  • Put the host into regular maintenance mode

Then to undo things, you naturally have to do the same in reverse. I’m going to break down a few things I’ve written and learned about how to do this in a series of posts on using PowerCLI, VMware.Hv.Helper, and hopefully it will help some some who are trying to do this, or the multitude of other tasks that can be handled by VMware.Hv.Helper.

First up, connecting to vSphere and Horizon

$VIConnection = Connect-VIServer -Server <vc server> -User administrator@vsphere.local -Password <password>
$HZConnection = Connect-HVServer -server <hz server> -user Administrator -password <password> -domain <DOMAIN>

This will establish a connection to both vSphere for using the PowerCLI and Horizon to use the VMware.Hv.Helper utilities and the Horizon API.

Next, we need to disable the pool. We also need to disable provisioning, and then remove any desktops that are associated with that pool. This portion is using functions from the Hv.Helper project.

Function ICPool-Disable {
  [CmdletBinding()] 
  Param
  (
    [Parameter(Mandatory=$true, Position=0)]
    [string]$HZpool
  )
  Write-Host "Disabling Pool $($HZpool)..."
  Set-HVPool -PoolName $HZpool -Disable
  Set-HVPool -PoolName $HZpool -Stop
  Write-Host "$($HZpool) disabled!"
  foreach ($desktop in Get-HVMachine -PoolName $HZpool) {
    try {
      Reset-HVMachine -MachineName $desktop.base.Name
      Write-Host "$($desktop.base.Name) will be marked for deletion"
    }
    catch { Write-Host "Error deleting $($desktop.base.Name)" }
  }
}

Next, here’s a function to actually enable Instant Clone Maintenance. This can be done on the Connection Broker with a cmdline utility, but I always just did it manually. This makes things much faster:

Function ICMaint-Start {
  [CmdletBinding()]
  Param
  (
    [Parameter(Mandatory=$true, Position=0)]
    [string]$VMhost
  )
  #Check to see if Instant Clone maintenance mode is disabled (or exists)
  if ((Get-Annotation -Entity (Get-VMHost -Name $VMhost) -CustomAttribute "InstantClone.Maintenance").Value -eq ""){
    #Enter Instant Clone maintenance mode
    Set-Annotation -Entity (Get-VMHost -Name $VMhost) -CustomAttribute "InstantClone.Maintenance" -Value "1" | Out-Null
  }
  #If Instant Clone Maintenance Mode hasn't equaled 2 yet, Instant clones are still present
  while ((Get-Annotation -Entity (Get-VMHost -Name $VMhost) -CustomAttribute "InstantClone.Maintenance").Value -ne "2") {
    Start-Sleep -Seconds 15
    Write-Host "...Waiting for Instant Clones Maintenance"
  }
  Write-Host "Finished Instant Clone Maintenance!"
}

Finally, we’ll call the functions so the script execution is neat and clean.

ICPool-Disable Win10
ICMaint-Start esx1.labdomain.net

Putting it all together, the script will look something like this:

Function ICPool-Disable {
[CmdletBinding()] 
Param
(
[Parameter(Mandatory=$true, Position=0)]
[string]$HZpool
)
Write-Host "Disabling Pool $($HZpool)..."
Set-HVPool -PoolName $HZpool -Disable
Set-HVPool -PoolName $HZpool -Stop
Write-Host "$($HZpool) disabled!"
foreach ($desktop in Get-HVMachine -PoolName $HZpool) {
try {
Reset-HVMachine -MachineName $desktop.base.Name
Write-Host "$($desktop.base.Name) will be marked for deletion"
}
catch { Write-Host "Error deleting $($desktop.base.Name)" }
}
}
Function ICMaint-Start {
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true, Position=0)]
[string]$VMhost
)
#Check to see if Instant Clone maintenance mode is disabled (or exists)
if ((Get-Annotation -Entity (Get-VMHost -Name $VMhost) -CustomAttribute "InstantClone.Maintenance").Value -eq ""){
#Enter Instant Clone maintenance mode
Set-Annotation -Entity (Get-VMHost -Name $VMhost) -CustomAttribute "InstantClone.Maintenance" -Value "1" | Out-Null
}
#If Instant Clone Maintenance Mode hasn't equaled 2 yet, Instant clones are still present
while ((Get-Annotation -Entity (Get-VMHost -Name $VMhost) -CustomAttribute "InstantClone.Maintenance").Value -ne "2") {
Start-Sleep -Seconds 15
Write-Host "...Waiting for Instant Clones Maintenance"
}
Write-Host "Finished Instant Clone Maintenance!"
}

##SCRIPT EXECUTION STARTS HERE
$VIConnection = Connect-VIServer -Server <vc server> -User administrator@vsphere.local -Password <password>
$HZConnection = Connect-HVServer -server <hz server> -user Administrator -password <password> -domain <DOMAIN>
ICPool-Disable Win10
ICMaint-Start esx1.labdomain.net

That’s it for now! In upcoming posts I’ll discuss the process to take things out of instant clone maintenance, RDS pools, and some other interesting things about working with the Horizon API. Please comment and let me know if you find these types of scripts helpful. I generally find a lack of knowledge on this topic across the internet, so I’ll try to develop more if there are asks for it!

Advertisements
%d bloggers like this:
search previous next tag category expand menu location phone mail time cart zoom edit close