VMware Cloud Community
edelldieguez
Contributor
Contributor
Jump to solution

PowerCLI: Shutdown your Virtual Infrastructure

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.

Reply
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

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

View solution in original post

Reply
0 Kudos
16 Replies
AureusStone
Expert
Expert
Jump to solution

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.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

Reply
0 Kudos
edelldieguez
Contributor
Contributor
Jump to solution

LucD,

Thank you, i'll appreciate it.

I ran the script and i'm getting this error (see attached picture)

Any idea ??

Thanks again.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

Reply
0 Kudos
edelldieguez
Contributor
Contributor
Jump to solution

LucD,

Yes it returned the vm names, but the script still is getting me the same error>

Thanks.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

Reply
0 Kudos
edelldieguez
Contributor
Contributor
Jump to solution

LucD,

first command return the vm names, this one: "Get-VM -Name $vmNames" gave me the error attached.

Also attached is the CSV file>

Thanks.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

The content of that CSV file was not correct, can you try the attached version.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
edelldieguez
Contributor
Contributor
Jump to solution

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.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

Reply
0 Kudos
edelldieguez
Contributor
Contributor
Jump to solution

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.

Reply
0 Kudos
edelldieguez
Contributor
Contributor
Jump to solution

LucD,

When the script was running i got these warning: (See Attached pic), is this normal ??

Thanks

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Yes, these are general warnings, annoying, but you can safely ignore them for now.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

LucD
Leadership
Leadership
Jump to solution

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

edelldieguez
Contributor
Contributor
Jump to solution

LucD,

I was thinking on that but i wasn't sure, i'll try and get back to you.

Thanks.

Reply
0 Kudos
edelldieguez
Contributor
Contributor
Jump to solution

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.

Reply
0 Kudos