Some useful tips for powering off VMs from ESXi Command Line

There might be occasions that you need to power off VMs from ESXi command line for some reason. knowing how to do it can save you time and effort from dealing with corrupted virtual disks and VMs. For instance an ESXi host loses all network connectivity due to a driver and firmware compatibility issue and you have to reboot the host but the VMs are still running with no network connectivity. In that case it will be safer if you gracefully shutdown the VMs and then put the host in maintenance mode and then reboot the ESXi host. Let’s see how to do it:

First of all you will need to grab Virtual Machines ID by running the below command:

vim-cmd vmsvc/getallvms

Below command returns the VM’s power state:

vim-cmd vmsvc/power.getstate VMID

Now you can try grcefully shutdown the VM. If the VM doesn’t respond to graceful shutdown in couple of minutes then you can forcefully power it off by the second command:

#For gracefull shutdown:
vim-cmd vmsvc/power.shutdown VMID
#For forcefully powering off the VM:
vim-cmd vmsvc/power.off VMID

The alternative way of doing the power off action is using ESXCLI command:

esxcli vms vm list
esxcli vms vm kill --type=[soft,hard,force] --world-id= WorldNumber

If neither of the above work then you will need to kill the VM process using below commands:

#find the VM World ID
esxcli vm process list

#Kill the VM process
esxcli vm process kill --type=[soft,hard,force] --world-id= WorldNumber

Note You can kill VM process using ps and kill commands similar to “esxcli vm process” if esxcli is not functioning.

Once you power off all you VMs then you can put the ESXi host in maintenance mode and power it off or reboot it using the following command:

#put the host in maintenance mode
esxcli system maintenanceMode set --enable true

#Power off the ESXi host
esxcli system shutdown [poweroff,reboot] --delay "seconds" --reason "description"

Compare Advanced Settings of two ESXi hosts

Of course you can use host profile templates to check compliance of ESXi host configuration against baseline configuration. But there might be some ad-hoc times that you need to compare Advanced Settings of two ESXi hosts and probably export a report out of it.

The below piece of PowerCLI code would be helpful for that purpose.

The credit for this code goes to Frederic Martin, the author of the code.

.SYNOPSIS 
    This script will compare all advanced settings between 2 ESXi servers
.DESCRIPTION 
    The script will compare each of all advanced settings between a source and a destination ESXi server and will display the difference
.NOTES 
    Author     : Frederic Martin - www.vmdude.fr
.LINK 
    http://www.vmdude.fr
.PARAMETER hostSourceName 
   Name of the host used for source compare
.PARAMETER hostDestinationName 
   Name of the host used for destination compare
.PARAMETER short 
   This switch allows you to bypass some advanced settings thanks to variable named $excludedSettings
.EXAMPLE 
	C:\foo> .\Compare-AdvancedSettings.ps1 -hostSourceName esx01.vmdude.fr -hostDestinationName esx02.vmdude.fr
	
	Description
	-----------
	Display all differences between advanced settings from host esx01.vmdude.fr and host esx02.vmdude.fr
.EXAMPLE 
	C:\foo> .\Compare-AdvancedSettings.ps1 -hostSourceName esx01.vmdude.fr -hostDestinationName esx02.vmdude.fr -short
	
	Description
	-----------
	Display differences (without those in $excludedSettings) between advanced settings from host esx01.vmdude.fr and host esx02.vmdude.fr
#> 

param (
	[Parameter(Mandatory=$True)]
	[string]$hostSourceName,
	[Parameter(Mandatory=$True)]
	[string]$hostDestinationName,
	[switch]$short
)

# Checking if source host exists
if (-Not ($hostSource = Get-VMHost $hostSourceName -ErrorAction SilentlyContinue)) {
	Write-Host -ForegroundColor Red "There is no source host available with name" $hostSourceName
	exit
}

# Checking if destination host exists
if (-Not ($hostDestination = Get-VMHost $hostDestinationName -ErrorAction SilentlyContinue)) {
	Write-Host -ForegroundColor Red "There is no destination host available with name" $hostDestinationName
	exit
}

$diffAdvancedSettings = @()
# Using hastable for easy and fast handle
$advancedSettingsSource = @{}
$advancedSettingsDestination = @{}
# You can filter unwanted advanced settings to be unchecked (regexp)
$excludedSettings = "ScratchConfig.CurrentScratchLocation|ScratchConfig.ConfiguredScratchLocation|Vpx.Vpxa.config.vpxa.|UserVars.ActiveDirectoryPreferredDomainControllers|Config.Defaults.cpuidMask|Mem.HostLocalSwapDir"

# Retrieving advanced settings
Get-AdvancedSetting -Entity $hostSource | %{$advancedSettingsSource.Add($_.Name,$_.Value)}
Get-AdvancedSetting -Entity $hostDestination | %{$advancedSettingsDestination.Add($_.Name,$_.Value)}

# Browsing advanced settings and check for mismatch
ForEach ($advancedSetting in $advancedSettingsSource.GetEnumerator()) {
	if ( ($short -And $advancedSetting.Name -notmatch $excludedSettings -And $advancedSetting.Value -ne $advancedSettingsDestination[$advancedSetting.Name]) -Or (-Not $short -And $advancedSetting.Value -ne $advancedSettingsDestination[$advancedSetting.Name]) ) {
		$line = "" | Select Settings, SourceValue, DestinationValue
		$line.Settings = $advancedSetting.Name
		$line.SourceValue = $advancedSetting.Value
		$line.DestinationValue = $advancedSettingsDestination[$advancedSetting.Name]
		$diffAdvancedSettings += $line
	}
}

# Displaying results
$diffAdvancedSettings

PowerCLI code to Find a datastore by NAA ID

There are times that you have a NAA ID of a LUN and need to find the corresponding datastore.

The below PowerCLI code is quite helpful that you can use to run to quickly find which datastore is attached to the NAA ID:


get-datastore |
Where-Object { $_.extensiondata.info.vmfs.extent.diskname -eq “NAA_ID of the Datastore”}

It returns the matching datastore name similar to this one:

get-datastore | Where-Object { $_.extensiondata.info.vmfs.extent.d
iskname -eq "naa.60060160f12335007e8600b99aeae211"}

Name                               FreeSpaceGB      CapacityGB
----                               -----------      ----------
DATASTORE_HIGH_0                       294.117       1,023.750

PowerCLI shortcode to find ESXi host using a Mac Address

There might be a situation that you need to look up an ESXi host with it’s Mac address especially when troubleshooting and tracing network connectivity issues.

Although you can use RVTools report to find the matching ESXi host but sometimes PowerCLI is just there and probably easier to run a single line code to grab the required information.

You can use the below single line PowerCLI to simply find which ESXi host owns the Mac address:

Get-VMHost | Get-VMHostNetworkAdapter | 
Where-Object {$_.Mac -eq "00:25:b5:01:00:1b"} | 
Select VMHost, Name, DeviceName, Mac

If there is an ESXi host in your vCenter environment that owns that Mac address then it will retrun the Hostname and the NIC name similar to the below:

VMHost                Name               Mac
------                ----               ---
ESXi01.mylab          vmnic9             00:25:b5:01:00:1b