Hi,
I am trying shutdown VM based on ESXi hosts and want to exclude few Infra Servers based on the exclude VM file list.
Let me know, if this good or needs any modification
$list = Import-Csv ".\myexclude.csv"
$maxTime = 10
$maxRun = 5
$vms = [System.Collections.ArrayList]@()
foreach ($entry in $list) {[string[]]$exclude+= Get-VM -Name $entry.Name}
Get-VMHost "myhost" | Get-VM | Where-Object {$_.powerstate -eq 'PoweredOn' -and $exclude -notcontains $_.Name} |
ForEach-Object -Process {
$vms.Add($_.Name)
$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()
}
while ($vms.Count -ge $maxRun) {
Get-VM -Name $vms | where { $_.PowerState -eq 'PoweredOff' } | ForEach-Object {
$vms.Remove($_.Name)
}
Start-Sleep 5
}
}
Write-Host "all vms shutdown completed"
Assuming the myexclude.csv contains a column named Name, you can add a -notcontains to the Where-clause.
Something like this for example
$list = Import-Csv -Path ".\myexclude.csv" -UseCulture
$maxTime = 10
$maxRun = 5
$vms = [System.Collections.ArrayList]@()
Get-VMHost "myhost" | Get-VM | Where-Object { $_.powerstate -eq 'PoweredOn' -and $list.Name -notcontains $_.Name } |
ForEach-Object -Process {
$vms.Add($_.Name)
$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()
}
while ($vms.Count -ge $maxRun) {
Get-VM -Name $vms | where { $_.PowerState -eq 'PoweredOff' } | ForEach-Object {
$vms.Remove($_.Name)
}
Start-Sleep 5
}
}
Write-Host "all vms shutdown completed"
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Assuming the myexclude.csv contains a column named Name, you can add a -notcontains to the Where-clause.
Something like this for example
$list = Import-Csv -Path ".\myexclude.csv" -UseCulture
$maxTime = 10
$maxRun = 5
$vms = [System.Collections.ArrayList]@()
Get-VMHost "myhost" | Get-VM | Where-Object { $_.powerstate -eq 'PoweredOn' -and $list.Name -notcontains $_.Name } |
ForEach-Object -Process {
$vms.Add($_.Name)
$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()
}
while ($vms.Count -ge $maxRun) {
Get-VM -Name $vms | where { $_.PowerState -eq 'PoweredOff' } | ForEach-Object {
$vms.Remove($_.Name)
}
Start-Sleep 5
}
}
Write-Host "all vms shutdown completed"
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD,
What is this purpose of below Add and Remove does ?
ForEach-Object -Process { $vms.Add($_.Name)
while ($vms.Count -ge $maxRun) { Get-VM -Name $vms | where { $_.PowerState -eq 'PoweredOff' } | ForEach-Object { $vms.Remove($_.Name)
That is to keep track of the VMs that are being stopped and shutdown.
The last While loop checks those VMs in a loop till they are effectively powered off.
If they are, they are removed from the list.
The number of items (VM names) in the list is used to limit the number of VMs that are bing powered off or shutdown
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thank you very much LucD. I will try this tomorrow and update you 🙂