We have several clients who have standalone VMware ESXi hosts (that are not part of any vCenter) without any option for vMotion or Storage vMotion. This can make it difficult for us to keep those hosts current with patches, updates, and BIOS / firmware because it means we need to manually shut the hosts’ guest down, and then restart the host – none of which can be done during normal business hours – and I’m getting too old to work all night.
Fortunately, VMware provides us a way to use PowerShell to shutdown a ESXi host’s guest, and then force a reboot. This means we can apply patches and updates late in the day to the ESXi host, then schedule the host to reboot early in the morning after the daily backup completes. Then when we come into the office in the morning (usually an hour or two before the clients arrive at their offices), it is simply a matter of checking the host to ensure it is back up along with all it’s guests.
To schedule a standalone VMware Host reboot, the current VMware PowerCLI client needs to be installed on the machine that will be running the scheduled reboot.
Once the VMware PowerCLI is installed, you need to create 3 files:
- C:\WINDOWS\VMWARE_ROOT.PWD – encrypted file that contains the root user’s password
- C:\WINDOWS\VMWARE_HOST_REBOOT.CMD – the wrapper that will call PowerShell from TaskScheduler
- C:\WINDOWS\VMWARE_HOST_REBOOT.PS1 – the actual PowerShell script that executes the reboot
To create the file C:\WINDOWS\VMWARE_ROOT.PWD, open PowerShell and run the following command:
read-host -assecurestring "Enter Password" | convertfrom-securestring | out-file C:\WINDOWS\VMWARE_ROOT.PWD
At the “Enter Password” prompt, enter the password of the root user account for the ESXi host you want to reboot.
You also need to set the PowerShell Execution Policy to support remote signed scripts such as C:\WINDOWS\VMWARE_HOST_REBOOT.PS1. To do this, in PowerShell run the following command and select Yes when prompted:
We need to schedule a time for VMWARE_HOST_REBOOT.CMD to run. I’ve set 4:15 am local time on March 22, 2015 in the example shown below, but you can adjust as required. In an administrative command prompt, run this (***note – this will create the scheduled task to run as the currently logged in user***):
schtasks /create /tn "VMware Host Reboot" /tr C:\WINDOWS\VMWARE_HOST_REBOOT.CMD /sc once /st 04:15:00 /sd 03/22/2015 /rp "*" /ru "%userdomain%\%username%"
Now we need to create C:\WINDOWS\VMWARE_HOST_REBOOT.CMD, which is the batch file task scheduler uses to launch our PowerShell script.
rem --- begin cut and paste of notepad C:\WINDOWS\VMWARE_HOST_REBOOT.CMD
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy RemoteSigned -noprofile -File C:\WINDOWS\VMWARE_HOST_REBOOT.PS1
rem --- end cut and paste of C:\WINDOWS\VMWARE_HOST_REBOOT.CMD ---
Lastly, we need to create C:\WINDOWS\VMWARE_HOST_REBOOT.PS1, adjusting the variable for $server to the host you wish to reboot (all variables are all defined at the top of the script) and adjust wait time ($waittime) before force rebooting after you issue a graceful gust shutdown command.
###--- begin cut and paste of notepad C:\WINDOWS\VMWARE_HOST_REBOOT.PS1
### @deancolpitts – http://blog.jbgeek.net
### This script will attempt to perform a graceful VM restart via the VMware Tools inside the guest.
### Variables - please only adjust server, user, and waittime. Any other variables should not be touched.
### Server is the vCenter server or ESXi host's FQDN, while user is the vCenter user or ESXi user account.
$server = "VMWARE.FQDN.DOMAIN_OR_IPADDRESS"
$user = "root"
$waittime = "300"
$credentialFile = "C:\WINDOWS\VMWARE_ROOT.PWD"
$pass = cat $credentialFile | convertto-securestring
$credentials = new-object -typename System.Management.Automation.PSCredential -argumentlist $user,$pass
add-pssnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue -WarningAction SilentlyContinue | Out-Null
if ( $DefaultVIServers.Length -lt 1 )
Connect-VIServer -Server $server -Protocol https -credential $credentials -WarningAction SilentlyContinue | Out-Null
Get-VM | Shutdown-VMGuest -confirm:$false -WarningAction SilentlyContinue
### Wait x number of seconds for all the VM's to gracefully shutdown before a forced kill occurs
Start-Sleep -s $waittime
Restart-VMHost -VMHost $server -force -confirm:$false
###--- end cut and paste of C:\WINDOWS\VMWARE_HOST_REBOOT.PS1 ---
All that is left do now is wait for C:\WINDOWS\VMWARE_HOST_REBOOT.CMD to run at your scheduled time.
As always – Use any tips, tricks, or scripts I post at your own risk.