Can someone help me on this script.
I am trying to shutdown all the vms and update after power state changes poweredoff for all vms.
There are certain conditions like Shutdown-VMGuest is initiated for vms where tools status ok but guest os is not responding to shutdown so in that condition I should do stop-vm.
so not clear till what time I should wait to do force shutdown
Is there any way to check the status the status of those vms (Like any change in vmtools status when Shutdown-VMGuest is initiated)
Get-VM | Where-Object { $_.powerstate -eq 'PoweredOn' -or $_.PowerState -eq 'suspended' }| ForEach-Object -Process {
if($_.ExtensionData.Guest.ToolsRunningStatus -eq "GuestToolsNotRunning"){
Stop-VM -VM $_ -Confirm:$false -RunAsync
}
else{
Shutdown-VMGuest -VM $_ -Confirm:$false
}
}
while(Get-VM | Where-Object { $_.powerstate -eq 'PoweredOn' -or $_.PowerState -eq 'suspended'}){
Start-Sleep 5
}
Write-Host "all vms shutdown completed"
Try something like this.
It will use a Shutdown-VMGuest when the VMware Tools are running otherwise it will do a Stop-VM.
If a Shutdown-VMGuest was done and a defined interval is passed, it will still do a Stop-VM.
Get-VM | Where-Object { $_.powerstate -eq 'PoweredOn' -or $_.PowerState -eq 'suspended' } |
ForEach-Object -Process {
$triedStop = $false
$triedGuest = $false
$now = Get-Date
while ($_.ExtensionData.Runtime.PowerState -ne [Vmware.Vim.VirtualMachinePowerState]::poweredOff -and -not $triedStop) {
if ($_.ExtensionData.Guest.ToolsRunningStatus -eq "GuestToolsRunning" -and -not $triedGuest) {
Shutdown-VMGuest -VM $_ -Confirm:$false
$triedGuest = $true
} else {
if (($triedGuest -and (New-TimeSpan -Start $now -End (Get-Date)).TotalSeconds -gt $maxTime) -or -not $triedStop) {
Stop-VM -VM $_ -Confirm:$false -RunAsync
$triedStop = $true
}
}
Start-Sleep 5
$_.ExtensionData.UpdateViewData()
}
}
Write-Host "all vms shutdown completed"
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Try something like this.
It will use a Shutdown-VMGuest when the VMware Tools are running otherwise it will do a Stop-VM.
If a Shutdown-VMGuest was done and a defined interval is passed, it will still do a Stop-VM.
Get-VM | Where-Object { $_.powerstate -eq 'PoweredOn' -or $_.PowerState -eq 'suspended' } |
ForEach-Object -Process {
$triedStop = $false
$triedGuest = $false
$now = Get-Date
while ($_.ExtensionData.Runtime.PowerState -ne [Vmware.Vim.VirtualMachinePowerState]::poweredOff -and -not $triedStop) {
if ($_.ExtensionData.Guest.ToolsRunningStatus -eq "GuestToolsRunning" -and -not $triedGuest) {
Shutdown-VMGuest -VM $_ -Confirm:$false
$triedGuest = $true
} else {
if (($triedGuest -and (New-TimeSpan -Start $now -End (Get-Date)).TotalSeconds -gt $maxTime) -or -not $triedStop) {
Stop-VM -VM $_ -Confirm:$false -RunAsync
$triedStop = $true
}
}
Start-Sleep 5
$_.ExtensionData.UpdateViewData()
}
}
Write-Host "all vms shutdown completed"
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Its worked I just tested by replacing $maxTime = 300 to 10. However when compared to my orginal script this execution time got increased.
Is it possible check the status once both stop-vm and Shutdown-VMGuest are initiated on first attempt and then wait for $maxTime = 300 then if still vm is in poweron state the we can do stop-vm.
That is exactly what the script is doing as I see it.
- is the VM powered on and did we not do a Stop-VM?
- yes
- are VMware tools running and did we not try a Shutdown-VMGuest yet?
- yes
- do a Shutdown-VMGuest
- wait for power off or time expired
- no
- did we try a Shutdown-VMGuest and did the interval expire OR did we not yet do a Stop-VM?
- yes
- do a Stop-VM
- wait for powered off
- no
- continue
The increase of the execution time might be because the script is trying to do a Shutdown-VMGuest, wait for the timeout and then try a Stop-VM.
In your original script that was not the case as far as I can see it.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks for your explanation LucD.
Right now I have tested on 1000 VMs (Powered on+Suspended)It taken appox 3hr 30mins. However with the earlier script it just taken 2hr appox. (Fortunately those vms which are having tools ok they are responded for Shutdown-VMGuest cmdlet). Don't know if it will be executed on much larger environment.
My idea is to first execute Shutdown-VMGuest(vmware tools active) & Stop-VM and wait for sometime and if any vms are still in poweron state even though Shutdown-VMGuest cmdlet executed on that vms then script should execute Stop-VM on those Vms. Why I am looking this way because I need to execute on 8000+ vms.
The long duration is partially explained since you are doing everything sequentially.
An option could be to run the script in parallel (via Start-Job), each instance for a specific number of VMs.
Is that an option?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Yeah That works for me. But how to give vc credentials every time from a credential file(.xml)
I will split the vms 500 each and execute multiple jobs.
Any possibility by using ForEach-Object -Parallel cmdlet?
In the current PowerCLI release the -Parallel switch is not supported.
The PowerCLI Dev team is working on it.
You can upvote the idea at Support for the PSv7 feature Foreach -Parallel
You can start multiple jobs from a main script.
If you make the connection in the main script, the background jobs can reuse that connection with the SessionId parameter.
See my Running a background job post.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Ok Thanks LucD.