EvacuateHosts.ps1

Applies To: Virtual Machine Manager 2008, Virtual Machine Manager 2008 R2, Virtual Machine Manager 2008 R2 SP1

When you want to perform maintenance activities, such as patching, on a clustered host, you can update its placement status by using the AvailableForPlacement parameter of the Set-VMHost cmdlet. When AvailableForPlacement is set to $FALSE, the host is no longer eligible as a possible location on which to deploy virtual machines. To minimize the disruption of service of the running virtual machines while you perform maintenance on the clustered host, you can move the running virtual machines to another host in the cluster prior to performing maintenance on the host. This is known as evacuating the host.

With System Center Virtual Machine Manager (VMM) 2008 R2, you can use the Disable-VMHost and Enable-VMHost cmdlets to place your clustered hosts into maintenance mode. For a script demonstrating how to use maintenance mode, see MaintenanceModeInCluster.ps1.

The following script uses quick migration to move all running virtual machines from a clustered host to other hosts in the cluster, based on host ratings. The script then sets the host as not available for placement. After a pause for maintenance activities, the script makes the host available for placement and performs the same tasks on the other hosts in the cluster.

Disclaimer

# Filename:      EvacuateHosts.ps1
# Description:   Uses quick migration to move all running virtual machines
#                off a host in a cluster, and then removes the host from
#                service. The script then returns the host to service and
#                performs the same tasks on the other hosts in the cluster.

# Connect to the VMM server.
$VMMServer = Get-VMMServer -ComputerName "VMMServer01.Contoso.com"

# Get the hosts in the cluster.
# The script assumes that there are at least two nodes in the cluster.
$Cluster = Get-VMHostcluster -Name "CLUSTER01.Contoso.com"
$VMHosts = Get-VMHost -VMHostCluster $Cluster
$VMHostGroup = Get-VMHostGroup | Where {$_.Path -eq "All Hosts\Cluster"}

# Loop through each host in the cluster, and use quick migration to move
# the running virtual machines to another host in the cluster.

Foreach ($VMHost in $VMHosts)
{
   $VMs = Get-VM -VMHost $VMHost  
   Foreach ($VM in $VMs)
   {
      If ($VM.Status -eq "Running")
      {
         Write-Host "Moving all running virtual machines to other hosts in the cluster."
         # The script assumes there is only one cluster in the host group.
         $HostRatings = @(Get-VMHostRating -VM $VM -VMHostGroup $VMHostGroup -IsMigration | where { $_.Rating -gt 0 } | Sort-Object -property Rating -descending)

         If($HostRatings.Count -eq "0") { throw "No hosts meet the requirements." }

         # If the highest rated host is not the same as the host on which
         # the virtual machine is currently deployed, move the virtual
         # machine to the highest rated host.

         If ($HostRatings[0].VMHost -ne $VMHost)
         {
            $VMRatedHost = $HostRatings[0].VMHost

            # Move the virtual machine.
            # In VMM 2008 R2, use the -UseCluster parameter to force a transfer of
            # the virtual machines by using quick migration.

            Write-Host "Moving $VM to $VMRatedHost"
            Move-VM -VM $VM -VMHost $VMRatedHost 
         }

         # If the highest rated host is the same as the host on which
         # the virtual machine is currently deployed, move the virtual
         # machine to the second-highest rated host.

         Else 
         {
            $VMRatedHost = $HostRatings[1].VMHost
            Write-Host "Moving $VM to $VMRatedHost"
            Move-VM -VM $VM -VMHost $VMRatedHost 
         }
      }
   }

   # Set the host as not available for placement.
   # If you are using VMM 2008 R2, you can use the Disable-VMHost 
   # cmdlet to set the host as unavailable for placement.
   Write-Host "Removing host" $VMHost "from service."
   Set-VMHost -VMHost $VMHost -AvailableForPlacement $FALSE

   # Pause for maintenance activities. This command pauses the script
   # for one minute. You can change this amount of time to suit your
   # maintenance window.
   Start-Sleep "60"

   # Set the host as available for placement.
   # If you are using VMM 2008 R2, you can use the Enable-VMHost 
   # cmdlet to set the host as available for placement.
   Write-Host "Placing host $VMHost back into service."
   Set-VMHost -VMHost $VMHost -AvailableForPlacement $TRUE
}