Hi guys,
Today we had a power outage and we were force to shutdown part of our virtual infrastructure to saved some power for our critical VMs, we spent quite some time in the shutdown process, my question is, how can I automatize this process using PowerCLI and at the same time work in other tasks??, I found a script for this but it shutdown the entire cluster (ESX and VMs), all that we need is a script that check each ESX Hosts (or Cluster) looking for the VMs defined in the script that I want to shutdown, it will do it one by one and checking that the VM is complete shutdown before start the process with the next in the list, if for some reason the VM hang a fail safe time where it just goes for it and shuts down the VM anyway, as a verification, will be nice to receive an email telling us the result.
Any ideas are welcome, we never experience this situation before so I'm open to suggestions in how approach this in the best way, I was reading online that this can be done using the VM priority settings defined in HA settings or creating folders for VMs and shutdown the folders based on the VMs priority assigned to the forders, at this point I'm very new in PowerCLI and all i have is LucD book.
Thanks in advance.
The script from AureusStone will work, but if you want the shutdown procedure a bit more advanced, you could do something like this.
The script will read the VM names from a CSV file that has this format
"vmName"
"vm1"
"vm2"
"vm3"
The script will find all powered on guests that are in the CSV file.
First it will try a guest shutdown, provided the VMware Tools are running.
The script will wait $maxWaitTime seconds for the completion.
If the guest is still powered on, the script will try a power off.
Again, the script will wait for $maxWaitTime seconds.
If the VM is still running, the script will try to kill it.
When all guests are done, the script will send an email
$sleepTime = 5
$maxWaitTime = 45
$report = @()
$vmNames = Import-Csv "C:\emergency-shutdown.csv" -UseCulture | %{$_.vmName} Get-VM -Name $vmNames | where {$_.PowerState -eq "PoweredOn"} | %{ # Guest shutdown
if($_.Extensiondata.Guest.ToolsRunningStatus -ne "guestToolsNotRunning"){ Shutdown-VMGuest -VM $_ -Confirm:$false
$waitTime = 0
while((Get-VM $_.Name).PowerState -ne "PoweredOff" -and $waitTime -lt $maxWaitTime){ sleep $sleepTime
$waitTime += $sleepTime
} $line = $_.Name + " guest shutdown"
} # Power off
if((Get-VM $_.Name).PowerState -ne "PoweredOff"){ Stop-VM -VM $_ -Confirm:$false
$waitTime = 0
while((Get-VM $_.Name).PowerState -ne "PoweredOff" -and $waitTime -lt $maxWaitTime){ sleep $sleepTime
$waitTime += $sleepTime
} $line = $_.Name + " powered off"
} # Kill
if((Get-VM $_.Name).PowerState -ne "PoweredOff"){ Stop-VM -VM $_ -Kill -Confirm:$false -RunAsync $line = $_.Name + " killed"
sleep $sleepTime
} # Problem guest
if((Get-VM $_.Name).PowerState -ne "PoweredOff"){ $line = $_.Name + " problematic shutdown"
} $report += $line } $from = "user@yourdomain.com"
$to = "user@yourdomain.com"
$subject = "Emergency shutdown report " + (Get-Date -Format "yyyy/MM/dd hh:mm") $body = $report
$smtpServer = "your smtp server" $smtp = new-object Net.Mail.SmtpClient($smtpServer) $smtp.Send($from, $to, $subject, $body)
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi. This isn't too hard.
First create a csv file with a heading called "name" and a list of VMs in order you want to shutdown.
Next in your script Connect-VIserver <servername>
Now you need to import your csv file
$inputCSV = Import-CSV <File Location>
Now you need to create a loop that will attempt to shutdown each VM
ForEach ($line in $inputCSV) {
Shutdown-VMGuest -VM $line.name -Confirm:$false
Write-Host $line.name
}
Make sure you have VMware tools installed and even better up to date.
The script from AureusStone will work, but if you want the shutdown procedure a bit more advanced, you could do something like this.
The script will read the VM names from a CSV file that has this format
"vmName"
"vm1"
"vm2"
"vm3"
The script will find all powered on guests that are in the CSV file.
First it will try a guest shutdown, provided the VMware Tools are running.
The script will wait $maxWaitTime seconds for the completion.
If the guest is still powered on, the script will try a power off.
Again, the script will wait for $maxWaitTime seconds.
If the VM is still running, the script will try to kill it.
When all guests are done, the script will send an email
$sleepTime = 5
$maxWaitTime = 45
$report = @()
$vmNames = Import-Csv "C:\emergency-shutdown.csv" -UseCulture | %{$_.vmName} Get-VM -Name $vmNames | where {$_.PowerState -eq "PoweredOn"} | %{ # Guest shutdown
if($_.Extensiondata.Guest.ToolsRunningStatus -ne "guestToolsNotRunning"){ Shutdown-VMGuest -VM $_ -Confirm:$false
$waitTime = 0
while((Get-VM $_.Name).PowerState -ne "PoweredOff" -and $waitTime -lt $maxWaitTime){ sleep $sleepTime
$waitTime += $sleepTime
} $line = $_.Name + " guest shutdown"
} # Power off
if((Get-VM $_.Name).PowerState -ne "PoweredOff"){ Stop-VM -VM $_ -Confirm:$false
$waitTime = 0
while((Get-VM $_.Name).PowerState -ne "PoweredOff" -and $waitTime -lt $maxWaitTime){ sleep $sleepTime
$waitTime += $sleepTime
} $line = $_.Name + " powered off"
} # Kill
if((Get-VM $_.Name).PowerState -ne "PoweredOff"){ Stop-VM -VM $_ -Kill -Confirm:$false -RunAsync $line = $_.Name + " killed"
sleep $sleepTime
} # Problem guest
if((Get-VM $_.Name).PowerState -ne "PoweredOff"){ $line = $_.Name + " problematic shutdown"
} $report += $line } $from = "user@yourdomain.com"
$to = "user@yourdomain.com"
$subject = "Emergency shutdown report " + (Get-Date -Format "yyyy/MM/dd hh:mm") $body = $report
$smtpServer = "your smtp server" $smtp = new-object Net.Mail.SmtpClient($smtpServer) $smtp.Send($from, $to, $subject, $body)
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
It looks like the Import-Csv cmdlet didn't return anything.
Is the filename correct ?
Is the content of the CSV file correct ?
Try running this
Import-Csv "C:\emergency-shutdown.csv" -UseCulture | %{$_.vmName}
It should display on screen the list of guests you specified in the CSV file.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD,
Yes it returned the vm names, but the script still is getting me the same error>
Thanks.
Strange, would you mind attaching (part of) the CSV file ?
Scramble the names if needed.
And does this return the same error ?
$vmNames = Import-Csv "C:\emergency-shutdown.csv" -UseCulture | %{$_.vmName}
Get-VM -Name $vmNames
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
The content of that CSV file was not correct, can you try the attached version.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD,
It worked, all the test VMs shutdown as expected.
One question, two of those VMs have win server 2003 and one of then 2008, the ones with 2003 were powered off and the one with 2008 was guest shutdown, any idea why the difference ??
Thanks.
That could be because the VMware Tools are not installed or not running, or because the Shutdown-VMGuest didn't work or because the shutdown wasn't completed within the maximum wait time.
In all those cases the script will try the Stop-VM cmdlet.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD,
All our VMs have the latest VMware tools installed, i tried the shutdown guest and both VMs with 2003 work, what i think is the time, not enough time to shutdown the guest and that is why the script kill them, any way to add to the script to check for OS and those VMs with 2003 give it more time to shutdown ??, if is possible of course.
Thanks in advance.
Yes, these are general warnings, annoying, but you can safely ignore them for now.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Perhaps you better first increase the $maxWaitTime value.
I set it to 45 seconds, but perhaps your environment needs a higher value.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD,
I was thinking on that but i wasn't sure, i'll try and get back to you.
Thanks.
LucD,
It works perfect, I changed 45 to 120 and now all VMs shutdown properly.
Thank you so much for all your help, really appreciate.