It’s always a challenge to ensure HA restarts Virtual Machines in case of a Hardware failure.
Had long discussions with VMware consultants and other specialists but at least the only suitable way is to enable admission control on the Cluster object and set proper resource reservation on each Virtual Machine.
As more hosts are within a cluster as higher is the risk that more hosts fail and that’s why I different between Clusters with more than 5 Host and increase the resource reservation for bigger clusters. You can change this value in row 8
Load Vi Toolkit in powershell
add-pssnapin VMware.VimAutomation.Core
Connact to one or more vCenter Server
Connect-VIServer "<VIServer1>","<VIServer2>" -wa 0 | out-null
Check if min one vCenter Server is connected
if ($global:DefaultVIServers.Count -gt 0){
Load only clusters who are HA and admission control enabled. This makes sense to control this script with the vCenter client. To exclude a Cluster simply disable AC
foreach($cluster in (get-view -viewtype "clustercomputeresource"|?{$_.configuration.dasconfig.admissioncontrolenabled -eq $true -and $_.configuration.dasconfig.enabled -eq $true})){
Count hosts within a cluster and calculate the correct percentage of reserved cluster resources as failover spare capacity. In this example a cluster with more than 5 hosts I calculate a failover spare capacity for two possible failing host
$amount_hosts=$cluster.host.count $currentCpuFailoverResourcesPercent=$cluster.configuration.dasconfig.admissioncontrolpolicy.cpufailoverresourcespercent $currentMemoryFailoverResourcesPercent=$cluster.configuration.dasconfig.admissioncontrolpolicy.memoryfailoverresourcespercent if ($amount_hosts -gt 0 -and $amount_hosts -lt 6){ $cpuFailoverResourcesPercent = [math]::round(100/$amount_hosts) $memoryFailoverResourcesPercent = [math]::round(100/$amount_hosts) }else{ $cpuFailoverResourcesPercent = [math]::round((200)/$amount_hosts) $memoryFailoverResourcesPercent = [math]::round((200)/$amount_hosts) }
Load Cluster objects and handover previously defined variables. Compare the current failover capacity values and apply the newly calculate values only if they doesn't match
$spec = New-Object VMware.Vim.ClusterConfigSpecEx $spec.vmSwapPlacement = "vmDirectory" $spec.dasconfig = New-Object VMware.Vim.ClusterDasConfigInfo $spec.dasconfig.admissioncontrolpolicy = New-Object VMware.Vim.ClusterFailoverResourcesAdmissionControlPolicy $spec.dasconfig.admissioncontrolpolicy.cpufailoverresourcespercent = $cpuFailoverResourcesPercent $spec.dasconfig.admissioncontrolpolicy.memoryfailoverresourcespercent = $memoryFailoverResourcesPercent if($currentCpuFailoverResourcesPercent -ne $cpuFailoverResourcesPercent -or $currentMemoryFailoverResourcesPercent -ne $memoryFailoverResourcesPercent){ $cluster.ReconfigureComputeResource_Task($spec, $true) }
At his point we are finished with the cluster configuration and continue in the same loop with the VMs within this cluster. The folowing query searchs for VMs within the previously checked or configured cluster that are NOT Fault Tolerance (FT) enabled and loads Virtual machine PS objects
foreach($vm in (get-view -viewtype "virtualmachine" -searchroot $cluster.moref|?{$_.Config.FtInfo -eq $null})){ $spec = New-Object VMware.Vim.VirtualMachineConfigSpec $spec.cpuAllocation = New-Object VMware.Vim.ResourceAllocationInfo $spec.memoryAllocation = New-Object VMware.Vim.ResourceAllocationInfo
If you make difference between more or less important VMs like Production and Development or Test VMs you have to identify them accordantly and set the proper reservation. In my case I'm looking for Production VMs and reserve 75% of the allocated memory. (VIEPAPPAT101)
if($vm.name.length -eq 12 -and $vm.name.substring(3,1)-eq "p"){ $MemReservationMB=$vm.config.hardware.memorymb*0.75 if($vm.config.memoryAllocation.Reservation -ne $MemReservationMB -and $vm.runtime.connectionstate -eq "connected"){ $spec.memoryAllocation.reservation = $MemReservationMB $vm.ReconfigVM_Task($spec) } }
Same for Development and UAT VMs but with only 50% memory reservation of the actual allocated memory (VIEDAPPAT101)
if($vm.name.length -eq 12 -and $vm.name.substring(3,1)-eq "d" -or $vm.name.substring(3,1)-eq "u"){ $MemReservationMB=$vm.config.hardware.memorymb*0.50 if($vm.config.memoryAllocation.reservation -ne $MemReservationMB -and $vm.runtime.connectionstate -eq "connected"){ $spec.memoryAllocation.reservation = $MemReservationMB $vm.ReconfigVM_Task($spec) } }
Close open brakets
} }
}