See which VMs were powered on before ESXi host went down
Have you been in a situation before where you had a standalone host go down, maybe a lab host, and after bringing everything back up, you are not sure which VMs were powered on before the host went down? I know I have been there, mainly with lab hosts as in a vSphere cluster, HA takes over and will restart VMs that were powered on. However, if you have a lab host and have everything set to manual mode, let’s see how to see which VMs were powered on before ESXi host went down.
See which VMs were powered on before ESXi host went down
The solution that I have implemented for my lab environment is a proactive approach to finding this information. There are ways of parsing log files with PowerCLI after the fact to look at power events and other things to try to piece together which VMs were powered on, however, I found this to be a bit cumbersome for my purposes. Instead, I have just a few simple PowerCLI one-liners running on a management workstation. These take a look at which VMs are running on the ESXi hosts and dump these to text files which I can then easily feedback into a “power on” script to power the VMs back on.
Using this approach, I know exactly which VMs are powered on and there is no worry about missing something crucial in getting VMs powered back on. You may wonder, why wouldn’t you just set your VMs to power on automatically, on a standalone host. In my lab environments, I have so much churn of VMs and virtual resources that it would be more work to keep up with managing which VMs are powered on and that I want to power back on in case a host goes down that the proactive approach to gathering the information ahead of time for me makes more sense.
PowerCLI scripts to see which VMs were powered on
I wanted to break up the information in various levels of verbosity for my purposes. The first list that I pull is the entire list of VMs that are powered on with the name, powerstate, folder, and host they are running on. This list won’t be used for feeding into another script, however, it is a good “master list” of sorts of the powered on VMs in the lab infrastructure, showing the name, location, and which host they reside on. To do that, you can use a simple PowerCLI one liner as follows:
get-vm | where-object {$_.PowerState -eq "PoweredOn"} | select Name, PowerState, Folder, VMHost | sort Name | out-file c:\virtualinventory\runningVMsverbose.txt
This will give you an output that looks like this:
Then I am using another PowerCLI one-liner per host to separate these out into different text files which can be used to feed into a script to power all the VMs back on if needed. The following one-liners will show examples of how to do this per host. I am also filtering out the special vCLS VMs which are controlled automatically from the vSphere side.
Explanation of scripts from top to bottom:
- This returns all powered on VMs with just the names only sorted alphabetically
- This returns all powered on VMs with a specific host
- This returns all powered on VMs for another specific host
- This returns all powered on VMs on a vSAN cluster
get-vm | where-object {$_.PowerState -eq "PoweredOn" -and $_.Name -notlike "vCLS*"} | select -expandproperty Name | sort | out-file c:\virtualinventory\unningVMsall.txt
get-vm | where-object {$_.PowerState -eq "PoweredOn" -and $_.VMHost -like "10.1.149.13" -and $_.Name -notlike "vCLS*"} | select -expandproperty Name | sort | out-file c:\virtualinventory\runningVMs_10.1.149.13.txt
get-vm | where-object {$_.PowerState -eq "PoweredOn" -and $_.VMHost -like "10.1.149.17" -and $_.Name -notlike "vCLS*"} | select -expandproperty Name | sort | out-file c:\virtualinventory\runningVMs_10.1.149.17.txt
get-cluster vsancluster | get-vm | where-object {$_.PowerState -eq "PoweredOn" -and $_.Name -notlike "vCLS*"} | select -expandproperty Name | sort | out-file c:\virtualinventory\runningVMs_vsancluster.txt
Powering on Powered off VMs using PowerCLI
Let’s now see how you can easily take the text files produced and feed these into another PowerCLI script if needed to power all the VMs that were powered on, back on. Below is an example of taking one of the text files that is produced with the above scripts and feeding this into another simple PowerCLI script which will work its way through the list of VMs and power these on. You can also add the pause between each VM with the start-sleep command in the loop. The number, in this case, is in seconds.
$poweredonvms = get-content C:\virtualinventory\runningVMs_10.1.149.17.txt
foreach ($poweredonvm in $poweredonvms) {
Start-VM -vm $poweredonvm
Start-Sleep -s 30
}
PowerCLI Script for running the one-liners
The following is an example of how to place the one-liners in a monolithic PowerCLI script, such as the following:
Import-Module VMware.PowerCLI
connect-viserver vcsa.cloud.local -user <your user> -password <password>
get-vm | where-object {$_.PowerState -eq "PoweredOn"} | select Name, PowerState, Folder, VMHost | sort Name | out-file c:\virtualinventory\runningVMsverbose.txt
get-vm | where-object {$_.PowerState -eq "PoweredOn" -and $_.Name -notlike "vCLS*"} | select -expandproperty Name | sort | out-file c:\virtualinventory\runningVMsall.txt
get-vm | where-object {$_.PowerState -eq "PoweredOn" -and $_.VMHost -like "10.1.149.13" -and $_.Name -notlike "vCLS*"} | select -expandproperty Name | sort | out-file c:\virtualinventory\runningVMs_10.1.149.13.txt
get-vm | where-object {$_.PowerState -eq "PoweredOn" -and $_.VMHost -like "10.1.149.17" -and $_.Name -notlike "vCLS*"} | select -expandproperty Name | sort | out-file c:\virtualinventory\runningVMs_10.1.149.17.txt
get-cluster vsancluster | get-vm | where-object {$_.PowerState -eq "PoweredOn" -and $_.Name -notlike "vCLS*"} | select -expandproperty Name | sort | out-file c:\virtualinventory\runningVMs_vsancluster.txt
disconnect-viserver -confirm:$false
You can also consolidate this into a couple of loops which will probably be desirable and will take into account any additions or deletions from the environment automatically
Import-Module VMware.PowerCLI
connect-viserver vcsa.cloud.local -user <your user> -password <password>
$clusters = Get-Cluster | select -expandproperty Name | out-file "C:\virtualinventory\clusters.txt"
$standalones = Get-VMHost | where{$_.Parent.Name -eq 'host'} | select -expandproperty Name | out-file "C:\virtualinventory\standalones.txt"
$clusternames = get-content c:\virtualinventory\clusters.txt
$standalonenames = get-content c:\virtualinventory\standalones.txt
get-vm | where-object {$_.PowerState -eq "PoweredOn"} | select Name, PowerState, Folder, VMHost | sort Name | out-file c:\virtualinventory\runningVMsverbose.txt
foreach ($clustername in $clusternames) {
get-cluster $clustername | get-vm | where-object {$_.PowerState -eq "PoweredOn" -and $_.Name -notlike "vCLS*"} | select -expandproperty Name | sort | out-file "c:\virtualinventory\runningVMs_$clustername.txt"
}
foreach ($standalonename in $standalonenames) {
get-vm | where-object {$_.PowerState -eq "PoweredOn" -and $_.VMHost -like $standalonename -and $_.Name -notlike "vCLS*"} | select -expandproperty Name | sort | out-file c:\virtualinventoryrunningVMs_$standalonename.txt
}
disconnect-viserver -confirm:$false
Scheduled Task to run the Powered On VMs check
Now, all we need to complete the circle is a scheduled task that can run as often as you would like to run the PowerCLI monolithic script which pulls the powered on information. Setting up a PowerCLI script to run via a scheduled task is not too difficult to configure.
Below is the Create Basic Task Wizard screen. Here you configure the Program/script, Add arguments (optional) and Start in (optional). What is contained in these fields?
Program/script: C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe
Add arguments (optional): -command C:\<your path>\poweredonvms.ps1 -executionpolicy bypass
Start in (optional): C:\<your path>\scripts
Also, set the security options for the scheduled task.
Hopefully this topic will help any who are running lab environments with manual power states for VMs to have a way to easily see which VMs were powered in their environments.