How to check ESX host version and build number with PowerCLI

Are you planning an ESXi upgrade? or in the middle of a cluster ESXi upgrade and couldn’t track which ones you upgraded and which ones you didn’t? (which is what happened to me ๐Ÿ˜‰ )

So I made a script that would output the build number and version number of ESXi hosts in a cluster

The One-liner

If you’re in a pinch and you just need to check the status of hosts with minimal effort, you can use this one-liner

Get-Cluster "<cluster_name>" | Get-VMHost | Select @{Label = "Host"; Expression = {$_.Name}} , @{Label = "ESX Version"; Expression = {$_.version}}, @{Label = "ESX Build" ; Expression = {$}}

Keep in mind that you need to be logged in to the vCenter with PowerCLI before executing this (obviously). This will ouput something like this:

The mechanism behind this is quite simple. Get-VMHost cmdlet contains parameters called “build” and “version” built in to it. What we are simply doing is outputting the values of those specific parameters.

Script to Output to a CSV

Need something fancier to share with your team or your superiors? Let’s see how we can expand from the one-liner to a proper script that is expandable and versatile that can output to a csv.

$vcenter = "<vcenter_name>"

$cluster_name = "<cluster_name>"

Connect-VIServer $vcenter 

Get-Cluster $cluster_name | Get-VMHost | Select @{Label = "Host"; Expression = {$_.Name}} , @{Label = "ESX Version"; Expression = {$_.version}}, @{Label = "ESX Build" ; Expression = {$}} | Export-csv "cluster_host_build_info.csv"

Disconnect-VIServer -Confirm:$false

What’s different with the one-liner is the pipe to “Export-csv” which will create the CSV file. Please note that this CSV file will be created on the folder where the script is located.

We have also parameterized the vCenter name and Cluster name for better versatility. Pretty neat huh? What – you want more? Let’s see how we can expand this further to match a build level that you want.

Script to check whether a host is in the build level you want

I hear you… You’re in the middle of upgrading an ESX cluster and you want to check which hosts are left to upgrade – while you can judge for yourself from the above script, here’s a small addition to our script above that makes our lives muuuuch easier

$vcenter = "<vCenter_name>"

$cluster_name = "<cluster_name>"
$expected_build = <expected_build_number>

Connect-VIServer $vcenter 

Get-Cluster $cluster_name | Get-VMHost | Select @{Label = "Host"; Expression = {$_.Name}} , @{Label = "ESX Version"; Expression = {$_.version}}, @{Label = "ESX Build" ; Expression = {$}} , @{Label = "Build Match" ; Expression = {if($ -eq $expected_build){"Yes"} else{"No"}}} | Export-csv "cluster_host_build_info.csv"

Disconnect-VIServer -Confirm:$false

The only difference is this line

@{Label = "Build Match" ; Expression = {if($ -eq $expected_build){"Yes"} else{"No"}}

Where we check with an IF condition whether the ESX host’s build matches our expected build version that we defined in $expected_build variable above. It will return a “Yes” or a “No”.

In the example below $expected_build = 15169789 and the output will be similar to the screenshot

And that is it! Hope this was as useful to you as it was for me!

It makes me feel validated & boosts my ego if you share, comment if you found this useful (no pressureย ๐Ÿ˜‰ย ). Social media links are below!

And as always, Happy scripting!

Enable and Disable ESXi Host SSH with PowerCLI | VMHostService Cmdlet

Maybe you’re upgrading your hosts, maybe you’re trying to run a command on multiple ESXi Hosts, any which way one thing which you will have to do is enable SSH from the vCenter, and disable when you’re done – because annoying as it is, security is important! ๐Ÿ˜‰ It would be especially annoying if you have to do that for dozens of ESXi hosts at a time.

So here I’ll show you guys a simple script you can run to enable and then disable SSH on multiple ESXi hosts so that you can go ahead and do your main task instead of being distracted by side quests!

Enable SSH on ESX host

$host_list = Get-Content "host_list.txt"

Connect-VIServer $vcenter 

foreach($hosts in $host_list){
	Get-VMHostService -VMHost $hosts | Where-Object {$_.Key -eq "TSM-SSH" } | Start-VMHostService -confirm:$false 

Disconnect-VIServer * -confirm:$false 

If you’ve followed the blog you will know I like to follow the Get-Content method to get a list of things (in this case list of ESXi Hosts) from a simple text file (separated by new lines). You can follow how to use Get-Content here

The real star of the show is this guy right here:

Get-VMHostService -VMHost $hosts | Where-Object {$_.Key -eq "TSM-SSH" } | Start-VMHostService -confirm:$false 

We use the Get-VMHostService cmdlet to output the list of services that is available on the ESX host. From there we pipe that list and search for “TSM-SSH” service. Once that is filtered we pipe that service over to the Start-VMHostService cmdlet which will enable SSH on the host. This usually triggers a “Are you sure?” on the shell but since we need things as automated as possible we disable that with -confirm:$false

That’s it! Simples!

Disable SSH on ESX host

$host_list = Get-Content "host_list.txt"

Connect-VIServer $vcenter 

foreach($hosts in $host_list){
	Get-VMHostService -VMHost $hosts | Where-Object {$_.Key -eq "TSM-SSH" } | Stop-VMHostService -confirm:$false 

Disconnect-VIServer * -confirm:$false 

This is exactly the same as above except that instead of piping the filtered SSH service to “Start-VMHostService” cmdlet, we pipe it to “Stop-VMHostService” cmdlet. Self explanatory really (works out because I’m lazy to type at this point xD)

And that is it! It makes me feel validated if you like, share, comment if you found this useful (no pressure ๐Ÿ˜‰ )! Social Media Links are below

Happy Scripting!

Getting the DNS Servers associated with an ESXi Host | PowerCLI | One-Liner

We recently had to check for discrepancies in configurations of ESXi hosts in a datacenter. While they should be identical, we have had issues with DNS working on some hosts while some don’t. So I developed a script that outputs the DNS servers configured on every host of the entire vCenter to a CSV file. (Note: This outputs the IPs of the DNS servers)

Its a one-liner so its not difficult to execute, check it out :

$vcenter = "vcenter_name"

Connect-VIServer $vcenter 

Get-VMHost | Select Name, @{N='DNS Server(s)';E={$_.Extensiondata.Config.Network.DnsConfig.Address -join ' , '}} | Export-Csv 'esx_dns_info.csv' 

Code breakdown:

Basically what we are doing is getting the data that is hidden inside the data that is pulled by the Get-VMHost module -in this case it’s under extension data/config/Network/DNSConfig/Address – which fetches the IP’s of these servers.

Why I used the -join ‘,’ is that a single ESXi host may have multiple DNS servers configured for redundancy, but this will not be outputted properly with CSV. So what I’m doing is joining the list of IPs to a single line separated by a comma.

Then finally pipe all that data in to the Export-CSV module that will export it to a CSV file I’ve named “esx_dns_info.csv”

And that is it – simple as that. Hope that was a easy and clear guide to getting the DNS servers associated with an ESX host.

If you liked it, please share the news! Happy Scripting!


Get the list of Virtual Machines on a ESXi Host with Get-VMHost | PowerCLI

Recently I needed to create a script to get a list of all virtual machines in a specific ESXi host. Surprisingly I had to search high and low on the internet to figure this out.

This is perplexing I mean its very straightforward to get the VMs in a datastore with

Get-VM -Datastore <datastore_name>

you would think getting all the virtual machines on a ESXi host would be more important than that! Work on this VMware – give us a Get-VM -VMHost!

But I digress – this is how you get the list of virtual machines on a ESXi host… I mean I was ranting up there but it’s really not that difficult, just that there’s no proper documentation on it

Get-VMHost -Name <Host_name> | Get-VM

And that’s all there is to it. But it’s not that intuitive, you wouldn’t think piping through the host name to Get-VM would do anything right? Anyways this one-liner saved my bacon, and I hope it would be useful to you as well!

Till the next time – happy scripting!

Checking for and Setting Maintenance mode on an ESXi Host via PowerCLI

Say you have to do a configuration change on an ESXi host – you know you can script that stuff out and put your feet up while it does it’s thang… Buuut you’re unsure about whether the host is in maintenance mode… what if its not on maintenance mode? What if it screws it up! Well in this post I’ll cover how you can check for as well as set maintenance mode effectively via PowerCLI.

Checking whether ESXi host is in Maintenance mode

The Get-VMHost cmdlet get the connection state of the ESXi host as well whether its connected, disconnected or in maintenance mode.

$host = "esx_host1" 
#Use the fqdn of the host

if($host.ConnectionState -eq "Maintenance"){
	write-host "The host is in maintenance mode"
	#Your configuration change code can go here

Setting ESXi host to Maintenance mode

$host = "esx_host1" 
#Use the fqdn of the host

#Set host to maintenance mode
Get-VMHost -Name $hosts | set-vmhost -State Maintenance

	$host_info = Get-VMHost $hosts
	$count = $count + 1
	#check if 5 minutes had passed, if so exit 
	if ($count -gt 15){
		$failed = 1
		$msg = "Waiting for maintenance mode timed out. Please check the status from the vCenter"
		sleep 20
}until($host_info.ConnectionState -eq "Maintenance" )

This script issues the command to set the host to maintenance mode. Then checks every 20 seconds for 5 minutes whether the host is in maintenance mode. If not it will get a timeout error (say if one stubborn Virtual machine refuses to leave the host).