Shutdown full VMware datacenter on UPS failure

To shutdown a VMware datacenter on UPS failure i found a PowerShell script, which i modified:

The script will shutdown the desired VMware datacenter, but it will ask you first, if you are sure. If you like to run the script in silent mode, you can run it with parameter yes.

You have to define the hostname of your VirtualCenter and the name of the datacenter. To run the script, you will need, to have VMware PowerCLI installed.

You can dowload the script shutdownESX.ps1 (right-click -> Save As) or copy/paste it from here:

# ===========================================================================================
#
#  Script Information
#
#  Title:              shutdownESX.ps1
#  Author:             Josh Burkard
#  Date:               11.07.2011
#  Requirements:       Windows Powershell and the VI Toolkit
#  Usage:              .\shutdownESX.ps1
#                      .\shutdownESX.ps1 yes   -->   shutdown the datacenter
#					                                 without any question
#
#  Description:        - Shutdown the defined VMware Datacenter
#                      - you have to set this variables:
#                          - VirtualCenter
#                          - DataCenter
#
#  The script will not run well, if the VirtualCenter server is running as VM in the same
#  data center.
#
#  I’m sure I don’t need to tell you that you need to be extremely careful when testing
#  this script as one false move could shut down everything !
#  Please test this to make sure it works first !
#
#===========================================================================================

$VirtualCenter = "HostName of VirtualCenter"
$DataCenter    = "Test"

# Add the VI-Snapin if it isn't loaded already
if ((Get-PSSnapin -Name "VMware.VimAutomation.Core" -ErrorAction SilentlyContinue) -eq $null )
{
	Add-PSSnapin -Name "VMware.VimAutomation.Core"
}

Connect-VIServer $VirtualCenter
clear
if ($args[0] -ne "yes")
{
	Write-Host "Connected to " $VirtualCenter
	Write-Host
	Write-Host "==============================================================================="
	Write-Host "===                                                                         ==="
	Write-Host "===       WARNING!     WARNING!     WARNING!     WARNING!     WARNING!      ==="
	Write-Host "===                                                                         ==="
	Write-Host "==============================================================================="
	Write-Host
	Write-Host "  This script is designed to power off all virtual machines and the ESX host."
	Write-Host
	Write-Host
	$input = Read-Host "  TYPE 'YES' TO CONTINUE THIS SCRIPT AND SHUTDOWN ESX HOSTS NOW."
	if ($input -ne "yes")
	{
		Write-Host
		Write-Host "==============================================================================="
		Write-Host "===               THE SHUTDOWN PROCESS HAS BEEN CANCELLED.                  ==="
		Write-Host "==============================================================================="
		exit
	}
}
Write-Host
Write-Host "==============================================================================="
Write-Host "===                    THE SHUTDOWN PROCESS WILL RESUME.                    ==="
Write-Host "==============================================================================="

# Get All the ESX Hosts for the desired DataCenter
$ESXSRV = Get-DataCenter "Test" | Get-VMHost
Write ""
Write "available VM's:"
Write "==============="

# For each of the VMs on the DataCenter hosts
Foreach ($VM in ($ESXSRV | Get-VM))
{
    # Shutdown the guest cleanly
    If ($VM.Name -ne $VC)
    {
		$VMName = $VM.Name
		$VMState = $VM.PowerState
		Write "$VMName : $VMState"
		if ($VM.PowerState -eq "poweredOn")
		{
			$VM | Shutdown-VMGuest -Confirm:$false
		}
    }
}

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

# Wait for the VMs to be Shutdown cleanly
$vms = Get-DataCenter $DataCenter | Get-VM
$numvms = ($vms.count - ($vms | where {$_.PowerState -eq "PoweredOff"}).Count)
Write-Host "Powered on VM's: $numvms "

$Time = (Get-Date).TimeofDay
do
{
	sleep 1.0
	$timeleft = $waittime - ($Newtime.seconds)
	$vms = Get-DataCenter $DataCenter | Get-VM
	$numvms = ($vms.count - ($vms | where {$_.PowerState -eq "PoweredOff"}).Count)
	Write-Host "Waiting for shutdown of $numvms VMs or until $timeleft seconds"
	$Newtime = (Get-Date).TimeofDay - $Time
} until ($numvms -eq 0 -or ($Newtime).Seconds -ge $waittime)

# Force VMs off
Foreach ($VM in ($ESXSRV | Get-VM | Where { $_.PowerState -ne “poweredOff” } ))
{
	$VM | Stop-VM -Confirm:$false | Out-Null
	Write-Host
	Write-Host $VM "has been forced to powering Off"
}

# Place ESX hosts in Maintenance Mode
$ESXSRV | Set-VMHost -State Maintenance | Out-Null
Write-Host
Write-Host "DataCenter" $DataCenter " is in Maintenance Mode"

# Shutdown the ESX Hosts
$ESXSRV | Foreach {Get-View $_.ID} | Foreach {$_.ShutdownHost_Task($TRUE)} | Out-Null
Write-Host
Write-Host "==============================================================================="
Write-Host "===                  THE SHUTDOWN PROCESS HAS COMPLETED.                    ==="
Write-Host "==============================================================================="

# Disconnect from the ESX Server
Write-Host
Disconnect-VIServer -Server $VirtualCenter -Confirm:$False
Write-Host "Disconnected from " $VirtualCenter

I’m sure I don’t need to tell you that you need to be extremely careful when testing this script as one false move could shut down everything ! – Please test this to make sure it works first !

Just to mention, this will obviously not work if your virtual center is a VM, for that you will need to do some funky connecting to each host etc, let me know if you desperately need that.