connect-viserver vc -credential (import-clixml "c:\scripts\adm.cred") -force
$DC = read-host "Enter the Datacenter to patch"
$vmhost = get-vmhost -Location (Get-Datacenter $dc)
$VMs = get-datacenter $dc | get-vm | ?{$_.powerstate -eq "Poweredon"}
$baseline = get-baseline -server vc -Name *Critical*
foreach ($vm in $VMs) {
Shutdown-VMGuest -VM $vm -Confirm:$false
$counter = 0
while($vm.PowerState -eq 'PoweredOn'){
if ($counter -gt 180) {
$vm = Get-VM -Name $vm.Name
stop-vm -vm $vm -confirm:$false
} else {
sleep 5
$vm = Get-VM -Name $vm.Name
$counter+=5
}
}
}
set-vmhost -VMHost $vmhost -State Maintenance -Confirm:$false
$baseline | Attach-Baseline -entity $vmhost -Confirm:$false
Scan-Inventory -Entity $vmhost
#$baseline | Remediate-Inventory -Entity $vmhost -Confirm:$false -ErrorAction SilentlyContinue
#get-vmhost -name $vmhost | set-vmhost -state Connected -Confirm:$false
#$vm | start-vm -confirm:$false
$UpdateTask = Update-Entity -Baseline $baseline -Entity $vmhost -RunAsync -Confirm:$false -ErrorAction Stop
while ($UpdateTask.percentcomplete -ne 100) {
Write-Progress -Activity "Patching $vmhost" -PercentComplete $updatetask.PercentComplete -Status "$($UpdateTask.PercentComplete) %"
Start-Sleep 5
$Updatetask = Get-Task -Id $Updatetask.id
Write-Output $updatetask
}
get-vmhost -name $vmhost | set-vmhost -state Connected -Confirm:$false
$vms | start-vm -Confirm:$false
----------
All the VMs are shutdown a but the script keeps showing this
it it not putting the host in maintenance mode even after vms are all shutdown. stuck in the while loop or stop-vm
Can you try with this snippet?
Get-Datacenter $dc | Get-VM | Where { $_.powerstate -eq "Poweredon" } |
ForEach-Object -Process {
$vm = $_
$counter = 0
Shutdown-VMGuest -VM $_ -Confirm:$false
while ($vm.PowerState -eq 'PoweredOn' -and $counter -le 180){
sleep 5
$vm = Get-VM -Name $vm.Name
$counter += 5
}
if($counter -gt 180 -and $vm.PowerState -ne 'PoweredOff'){
Stop-VM -VM $vm -Confirm:$false
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
thanks Luc. Yes this works. I wonder why my script did not get out of while loop. Also Is it possible to shutdown all vms async?
I suspect that was because you were changing the foreach variable ($vm) inside the loop.
Afaik, the Shutdown-VMGuest (alias for Stop-VMGuest) doesn't allow a RunAsync.
But the cmdlet returns immediately after sending the shutdown request to the Guest OS.
You could send it to all VM, then in a loop, and for a certain time, wait till all VMs are powered down.
If the timeout expires, you could run the Stop-VM for all remaining VMs.
Something like this for example
Get-Datacenter $dc | Get-VM | Where { $_.powerstate -eq "Poweredon" } |
Shutdown-VMGuest -Confirm:$false
$counter = 0
while((Get-Datacenter $dc | Get-VM | Where { $_.powerstate -eq "Poweredon" }).Count -ne 0 -and $counter -le 180){
sleep 5
$counter += 5
}
Get-Datacenter $dc | Get-VM | Where { $_.powerstate -eq "Poweredon" } |
Stop-VM -Confirm:$false
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi Luc
I am trying to hosts on a cluster and here are the requirements
1. set the host in maintenance mode
2. make sure all vms are evacuated
3. Then manually power off one appliance vm which is pinned to the host
4. when that vm is shutdown, check if host in maintenance mode
5. then patch the host with lifecycle manager
6. wait for host to come back online and set it to exist maintenance mode
7. manually power on thast appliance vm
8. proceed with next host
Here is my script
Is there a question there?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference