##################################################################################### # ShutdownDataCenter.ps1 # # Author: Eric Wright # # www.discoposse.com # # # # This script is designed to shut down a virtual data center. It was built for a # # configuration with one vCenter running as a virtual machine on a cluster # # # # It requires you to use the commandline as follows: # # PowerShell.exe ShutdownDataCenter.ps1 MyKeyword # # Where the MyKeyword parameter is the $Args[0] definition that sets $RunMode # # With nothing, or the wrong parameter it runs in WhatIf mode and won't shut # # shut anything down # ##################################################################################### # Set the vCenter instance $myvCenter = "YOUR VCENTER SERVER HERE" # Read the command line for the keyword to confirm shutdown. You decide the keyword. Mine is FRUNKUS. # If the $RunMode is FALSE then this is treated as a test run only $CLParameter = $Args[0] $MyKeyword = "FRUNKUS" If ($CLParameter -ne $MyKeyword) { $RunMode = $FALSE } Else { $RunMode = $TRUE } # Connect to VIServer Connect-VIServer $myvCenter # Export the list of VM guests which are Powered On just in case we don't have the automatic startup and shutdown configured Get-VM | where-object {$_.PowerState -eq "PoweredOn" } | Select Name | Export-CSV PowereredOnVMGuests.csv # Set the cluster(s) DRS settings to MANUAL If ($RunMode -eq $TRUE) { Get-Cluster | Set-Cluster -DrsAutomation Manual -confirm:$false } Else { Get-Cluster | Set-Cluster -DrsAutomation Manual -confirm:$false -WhatIf } # Disable HA on the cluster(s) If ($RunMode -eq $TRUE) { Get-Cluster | Set-Cluster -HAEnabled:$true -confirm:$false } Else { Get-Cluster | Set-Cluster -HAEnabled:$true -confirm:$false -WhatIf } # Find the VMHost running vCenter $vCenterHost = (Get-VM $myvCenter).host # Find the list of host servers which arent running your vCenter instance $notvCenterHosts = Get-VMHost | Where-Object { $_.name -ne $vCenterHost } ForEach ( $notvCenterHost in $notvCenterHosts ) { $vmHostName = $notvCenterhost.name # Find powered on guest vms $vmGuests = Get-VMHost -name $vmHostName | Get-VM | Where { $_.PowerState -eq "PoweredOn" } # Send the clean shutdown command to the guests ForEach ( $vmGuest in $vmGuests ) { # If VM tools aren't running we force power down $vmInfo = Get-View -Id $vmGuest.id if ( $vminfo.config.Tools.ToolsVersion -eq 0 ) { Write-Host "Hard Power down for $vmGuest" If ($RunMode -eq $TRUE) { Stop-VM $vmGuest -confirm:$false -RunAsync } Else { Stop-VM $vmGuest -confirm:$false -RunAsync -WhatIf } } else { Write-Host "Cleanly shutting down $vmGuest" If ($RunMode -eq $TRUE) { Shutdown-VMGuest -VM $vmGuest -confirm:$false } Else { Shutdown-VMGuest -VM $vmGuest -confirm:$false -WhatIf } } } # We wait for the machines to shut down and then we get aggressive Sleep 45 # Query for powered on guests again $vmGuests = Get-VMHost -name $vmHostName | Get-VM | Where { $_.PowerState -eq "PoweredOn" } # Send the forced shutdown command to the guests ForEach ( $vmGuest in $vmGuests ) { # Sending the Stop-VM to any remaining powered machines Write-Host "Hard Power down for $vmGuest" If ($RunMode -eq $TRUE) { Stop-VM $vmGuest -confirm:$false -RunAsync } Else { Stop-VM $vmGuest -confirm:$false -RunAsync -WhatIf } } # Wait before going into maintenance mode Sleep 45 # Set into maintenance mode Write-Host "Putting $vmHostName into Maintenance Mode" If ($RunMode -eq $TRUE) { Set-VMHost -VMHost $vmHostName -State Maintenance } Else { Set-VMHost -VMHost $vmHostName -State Maintenance -Whatif } # Now we send the shutdown to the hosts Write-Host "Time to shut down $vmHostName" If ($RunMode -eq $TRUE) { Write-Host "SIMULATION MODE: Shutting down $vCenterHost" } Else { $vCenterHost | ForEach { Get-View $_.ID } | ForEach { $_.ShutdownHost_Task($TRUE)} } } ######################################################################################## # This is the last host to be handled because it is running our virtual vCenter server # ######################################################################################## # Now shut down all VMs on the vCenter Host except our vCenter server $vmGuests = Get-VMHost -name $vCenterHost | Get-VM | Where { ($_.PowerState -eq "PoweredOn") -and ($_.name -ne $myvCenter) } # Send the clean shutdown command to the guests ForEach ( $vmGuest in $vmGuests ) { # If VM tools aren't running we force power down $vmInfo = Get-View -Id $vmGuest.id if ( $vminfo.config.Tools.ToolsVersion -eq 0 ) { Write-Host "Hard Power down needed for $vmGuest" If ($RunMode -eq $TRUE) { Stop-VM $vmGuest -confirm:$false -RunAsync } Else { Stop-VM $vmGuest -confirm:$false -RunAsync -WhatIf } } else { Write-Host "Cleanly shutting down $vmGuest" If ($RunMode -eq $TRUE) { Shutdown-VMGuest -VM $vmGuest -confirm:$false } Else { Shutdown-VMGuest -VM $vmGuest -confirm:$false -WhatIf } } } # We wait for the machines to shut down and then we get aggressive Sleep 45 # Query for powered on guests again $vmGuests = Get-VMHost -name $vCenterHost | Get-VM | Where { ($_.PowerState -eq "PoweredOn") -and ($_.name -ne $myvCenter) } # Send the forced shutdown command to the guests ForEach ( $vmGuest in $vmGuests ) { # Sending the Stop-VM to any remaining powered machines Write-Host "Hard Power down for $vmGuest" If ($RunMode -eq $TRUE) { Stop-VM $vmGuest -confirm:$false -RunAsync } Else { Stop-VM $vmGuest -confirm:$false -RunAsync -WhatIf } } # Set into maintenance mode Write-Host "Putting $vmHostName into Maintenance Mode" If $RunMode = { Set-VMHost -VMHost $vmHostName -State Maintenance } Else { Set-VMHost -VMHost $vmHostName -State Maintenance -Whatif } # Now we send the shutdown to the host which will force the shutdown of the vCenter virtual server Write-Host "Time to shut down $vmHostName" If ($RunMode -eq $TRUE) { Write-Host "SIMULATION MODE: Shutting down $vCenterHost" } else { $vCenterHost | ForEach { Get-View $_.ID } | ForEach { $_.ShutdownHost_Task($TRUE)} } Write-Host "Daisy, daisy, give me your answer do... "