Simultaneously reboot all vApps in a vSphere datacenter

If you manage a large number of vApps in a vSphere datacenter and have to reboot them on a scheduled basis, you might not want to do it manually. This script helps you schedule the task easily.
BIG WARNING: This script is designed to run with no interaction so that it runs in the middle of the night without you having to acknowledge anything. However, the downside to doing things this way is that you can reboot all your vApps if you decide to test this on your production systems in the middle of the day.

Here’s the script:

cls

# Define Log File
$log = "C:\Scripts\vAppReboot\RebootLog-$(Get-Date -f "yyyy-MM-dd").log"

# Send Email To
 $EmailTo = "email@domain.com"
# Send Email From
 $EmailFrom = "vAppReboots@vAppReboots.com"
# EMail Server
 $SMTPSRV = "localhost"


# Connect to VCenter Server
"$(Get-Date -f "yyyy-MM-dd HH:mm:ss") Connecting to VCenter Server" | %{write-host $_; out-file -filepath $log -inputobject $_ -append}
connect-viserver localhost  -WarningAction SilentlyContinue |out-null

# Grab a list of all running Vapps
$AllRunningVapps = get-vapp | Where { $_.Status -eq "Started" }

# Loop through the vapp list
Remove-Item AllRunningVapps.txt
foreach ($ClientName in $AllRunningVapps) {$ClientName.Name >> AllRunningVapps.txt}

# #### VAPP REBOOT SCRIPT BLOCK START ####

Get-Content AllRunningVapps.txt | %{

  $ScriptBlock = {
    # accept the loop variable across the job-context barrier
    param($name)
    
	# Define Log File
    $log = "C:\Scripts\vAppReboot\RebootLog-$(Get-Date -f "yyyy-MM-dd").log"

    #Load the VMWare PS Snapin
    "$(Get-Date -f "yyyy-MM-dd HH:mm:ss") $name	: Loading VMWare PS Snapin" | %{write-host $_; out-file -filepath $log -inputobject $_ -append}
    add-pssnapin VMware.VimAutomation.Core |out-null

    # Connect to VCenter Server
    "$(Get-Date -f "yyyy-MM-dd HH:mm:ss") $name	: Connecting to VCenter Server" | %{write-host $_; out-file -filepath $log -inputobject $_ -append}
    connect-viserver localhost  -WarningAction SilentlyContinue |out-null
 
   # Delay loop to wait until Vapp stop command is processed.
   # Error handling to ensure a shutdown command is re-sent if the Vapp fails to stop.
    do {
      $StoppingVapp = get-VApp $name
	  # Power on VApp as soon as it stops.
      if ($StoppingVapp.Status -eq "Started") {
         "$(Get-Date -f "yyyy-MM-dd HH:mm:ss") $StoppingVapp	: Initiating Shutdown" | %{write-host $_; out-file -filepath $log -inputobject $_ -append}
         Stop-VApp $name -Confirm:$false -RunAsync |out-null
         }
	  Start-Sleep -s 60
	$StoppingVappStatus = $StoppingVapp.Status
      "$(Get-Date -f "yyyy-MM-dd HH:mm:ss") $StoppingVapp	: $StoppingVappStatus"  | %{write-host $_; out-file -filepath $log -inputobject $_ -append}
    }
    until ($StoppingVapp.Status -eq "Stopped")

   # Delay loop to wait until VApp is stopped.
   # Power on VApp after it has been stopped.
    do {
      $StoppedVapp = get-VApp $name
    # Power on VApp as soon as it stops.
      if ($StoppedVapp.Status -eq "Stopped") {
         "$(Get-Date -f "yyyy-MM-dd HH:mm:ss") $StoppedVapp	: Initiating Power On" | %{write-host $_; out-file -filepath $log -inputobject $_ -append}
         start-vapp $StoppedVapp -Confirm:$false -RunAsync |out-null
         }
      Start-Sleep -s 60
	$StoppedVappStatus = $StoppedVapp.Status
      "$(Get-Date -f "yyyy-MM-dd HH:mm:ss") $StoppedVapp	: $StoppedVappStatus" | %{write-host $_; out-file -filepath $log -inputobject $_ -append}
    }
    until ($StoppedVapp.Status -eq "Started")
  }

# #### VAPP REBOOT SCRIPT BLOCK END ####

  # Show the loop variable here is correct
  "$(Get-Date -f "yyyy-MM-dd HH:mm:ss") Processing $_..." | %{write-host $_; out-file -filepath $log -inputobject $_ -append}

  # pass the loop variable across the job-context barrier
  Start-Job -ScriptBlock $ScriptBlock -ArgumentList $_  |out-null
}

# Wait for all to complete
While (Get-Job -State "Running") { 
Start-Sleep 5
# Display output from all jobs
Get-Job | Receive-Job
}

# Cleanup
Remove-Job *

# Send Log as email
send-mailmessage -to $EmailTo -from $EmailFrom -subject "vApp Reboot Log - $(Get-Date -f "yyyy-MM-dd")" -smtpserver $SMTPSRV -body $(Get-Content $log | out-string)

Future improvements: Option to opt out vApps from the script.




2 Comments

Hi There, thanks for the awesome script.
I’m very new to scripting, is there any chance you could give me some pointers on how to modify it to only shutdown a single vApp??

Leave a Reply

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

*