PowerCLI Script to Shutdown My Home Lab

Ran across a PowerCLI script that can be used to shutdown your virtual infrastructure written by Alan Renouf and thought it would be pretty handy to use to automate shutting down my home lab.

The original script attempts to shutdown VMs “cleanly” using Shutdown-VMGuest. Shutdown-VMGuest attempts to shutdown the VMs OS and requires that VM Tools be installed and running. Most of the VMs in my lab are running Damn Small Linux (DSL) and do not have VM tools installed so this would not work and it would shutdown the host without shutting down the VMs first. Not really a big deal but I wanted to make the process just a bit cleaner.

I changed the script to first shutdown VMs that are powered on and have VM tools running. It then waits $waittime in seconds and uses Stop-VM to forcefully power off any remaining powered on VMs. As in the original script it then waits $waittime or until no VMs are powered on to shutdown the ESXi hosts.

Connect-VIServer MyVIServer

# Set the amount of time to wait before assuming the remaining powered on guests are stuck
$waittime = 60 #Seconds

# Get All the ESX Hosts
$ESXSRV = Get-VMHost

# For each of the powered on VMs with running VM Tools
Foreach ($VM in ($ESXSRV | Get-VM | Where {$_.PowerState -eq "poweredOn" -and $_.Guest.State -eq "Running"})){
    # Shutdown Guest
    write-host "Shutting down $VM"
    $VM | Shutdown-VMGuest -Confirm:$false
}

Write-host "Pausing for $waittime seconds to allow VMs to shutdown cleanly"
sleep $waittime

#Force Poweroff of any VMs still running
Foreach ($VM in ($ESXSRV | Get-VM | Where {$_.PowerState -eq "poweredOn"})){
      # Power off Guest 
      write-host "Powering off $VM"
      $VM | Stop-VM -Confirm:$false
}

$Time = (Get-Date).TimeofDay
do {
    # Wait for the VMs to poweroff
    sleep 1.0
    $timeleft = $waittime - ($Newtime.seconds)
    $numvms = ($ESXSRV | Get-VM | Where { $_.PowerState -eq "poweredOn" }).Count
    Write-host "Waiting for shutdown of $numvms VMs or until $timeleft seconds"
    $Newtime = (Get-Date).TimeofDay - $Time
    } until ((@($ESXSRV | Get-VM | Where { $_.PowerState -eq "poweredOn" }).Count) -eq 0 -or ($Newtime).Seconds -ge $waittime)

# Shutdown the ESX Hosts
Write-host "Shutting down hosts"
$ESXSRV | Foreach {Get-View $_.ID} | Foreach {$_.ShutdownHost_Task($TRUE)}

Write-Host "Shutdown Complete"

To use the script just change MyVIServer in line 1 to be the IP address or hostname of you vCenter server. Set $waittime at line 4 to be the number of seconds to wait before forcefully powering off VMs. The $waittime may need to be increased depending on the speed of your lab and the number of VMs that are shutting down. Run the script as you would any other PowerCLI script.

It is probably not completely necessary to force the shutdown of all VMs before shutting down the hosts. They will be shutdown when the host they are running on is shutdown. It just gave me some PowerCLI practice and it works.

Be EXTREMELY careful with this script. When you run it all VMs and Host managed by the vCenter you are connecting to will be shutdown!

DO NOT RUN THE SCRIPT AGAINST YOUR vCENTER SERVER IF YOU DO NOT WANT TO SHUTDOWN VMs!

Thanks again to Alan Renouf for the original script which can be found at http://www.virtu-al.net/2010/01/06/powercli-shutdown-your-virtual-infrastructure/.

If you found this script useful or have other ideas for improvements post to the comments.

4 thoughts on “PowerCLI Script to Shutdown My Home Lab

  • July 15, 2012 at 6:06 pm
    Permalink

    Does this script not make the assumption that the VC is not running on the server farm. If it were, as soon as you shutdown the guest VM, you end up with no connection to do the rest of the script?

    Reply
    • July 17, 2012 at 12:42 pm
      Permalink

      PJ,

      You are correct the script does assume that the VC is not a VM running on the environment you are shutting down. If your VC is running on one of the ESXi servers you would need to modify the script a bit to determine which host the VC is on and leave that host and VM running. Once the other VMs and hosts are should down you could then connect directly to the host and shutdown the VC VM and then the host.

      Hersey

      Reply
  • March 11, 2013 at 2:55 am
    Permalink

    I was looking for acript to shut down all the guest machines and then the esxi 5.1 host. I am new to scripting , it would be great if somebody can help me out in how to execute this script.

    I tried saving it as a .ps1 file and run , didnt work.
    I tried pasting the contents of the script to the vmware power cli and received an error “current licence or ESXi version prohibits execution of the requested operation”

    Reply
  • September 8, 2013 at 1:40 pm
    Permalink

    Great Post Hersey
    Thomas,
    PowerCLI can not run against the free version of ESXi. Unfortunately remote management tools are not supported on the free version. That is why you’re getting that error.

    PJ.
    In the event that you have vCenter running in the same cluster you could always put in a filter before the main filter.
    Get-VM | Where{$_.Name -ne “”} | Where {$_.PowerState……. }

    You could then change the count listed in line 34 to be 1 so that the vCenter is the last one.

    You could store the ESXi host list in an object and do individual connections to those to initiate their shutdown so you’re not dependent on vCenter. Definitely an interesting conundrum, especially for a homelab. Hope this provides some suggestions for providing the functionality you mentioned.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

twelve − two =