How to get the Operating System (OS) of Virtual machines with PowerCLI

There have been numerous occasions where we were required to gather the list of VMs in the vCenter along with their OS, for audits, for support, to plan patching, etc… But its not always that easy.

The vCenter gets the OS details of the VM with the aid of VM Tools in the virtual machine. But what if the VM is powered off or doesn’t have tools installed? Then the OS is left as blank! But there is a workaround, we can fetch the OS info the VM was configured with – since that information is stored in the vCenter itself, we don’t have to rely on the VM tools running inside the VM to get this information.

This is in the $_.ExtensionData.Config.GuestFullName parameter in Get-VM

One Liner to get the list of all VMs and OS info in the vCenter

Get-VM | Select @{Label = "VM Name" ; Expression = {$_.Name} },@{Label = "Guest OS" ; Expression = {$_.ExtensionData.Config.GuestFullName} }| Export-CSV "vm_os_info.csv"

Its as simple as that. You will get a csv with two columns as “VM Name” and “Guest OS” with all the information in the vCenter wrapped in a neat little bow.

Hope this short and sweet post was useful to you!

It makes me feel validated & helps me out a lot if you share or leave a comment if you found this useful (no pressure 😉 ). Social media links are below!

And as always, Happy scripting!

How to check EVC Status of a Host Cluster with PowerCLI

Consider this part 2 of my vSphere Health Check with PowerCLI series. It’s taken its sweet time, I know, but hey – better late than never eh? 😉 Part 1 is found here (Checking for hosts with alarms disabled) .

In this post we’ll discuss how to check the EVC mode of each host cluster in the vCenter. EVC (Enhanced vMotion Capability) is a feature that is a form of standardization of vMotion compatibility in hosts in the cluster according to CPU generation. It sets a minimum feature set offered by CPUs in the cluster so that all hosts presents identical features so that things don’t go haywire when VMs migrate between them. Anyway this is not a lesson on EVC (if you want more info, refer the KB article), this is a lesson on checking on the EVC mode on a cluster by PowerCLI

We will first check whether EVC is enabled in the first place, and if its enabled, which EVC mode its enabled to. While this seems like a lot of complexity – its actually only a few lines of code.

Checking if EVC is enabled

EVCmode information is encapsulated in the Get-Cluster module. So let’s access Get-Cluster and check on the EVCmode parameter. If this EVC mode returns a null value then EVC is not enabled in that cluster. If EVC mode is enabled then it would return the EVC Mode (like Intel “Haswell”, Intel “Skylake”, Intel “Cascade Lake” etc…). Lets see how it comes in to play

$cluster = $Get-Cluster <cluster_name>
    
if($null -eq $cluster.EVCMode){
        $evc_status = "Status : Disabled"
    }

else{
        $evc_mode = $cluster.EVCMode

        $evc_status = "Status : Enabled EVC Mode : $evc_mode"

    }

One-Liner

Lets see how we can use the above principle to get a one-liner to export a csv with the EVC mode results

Get-Cluster |  Select @{N='Cluster';E={$_.Name}},@{N='EVC Mode';E={if($null -eq $_.EVCMode){"EVC not enabled"} else{$_.EVCMode}}} | Export-Csv 'cluster_evc.csv'

And that’s it! Its as simple as that!

It makes me feel validated & helps me out a lot if you share, comment if you found this useful (no pressure 😉 ). Social media links are below!

And as always, Happy scripting!

How to enable ESXi host alarms on the vCenter with PowerCLI (& how to automate it)

In a previous write-up I discussed how to check the Alarm status of ESX hosts in a cluster. Let’s take it a step further and check how we can enable the alarms on an ESX host in order to automate it – so that alarms will be enabled on ESX hosts for eternity, as a healthy environment should! No longer shall we be in doubt whether we forgot to enable alarms in a ESX host after working on it! This is actually very simple! Lets get to it!

Here I will be talking about enabling alarms on all hosts in the vCenter (not on a particular cluster). You can put this script on a task scheduler to keep it running on a schedule so that Alarms will be enabled periodically throughout the day.

Step 1: Getting the list of ESX hosts whose alarms are disabled

$alarm_disabled_hosts = Get-VMHost | Where-Object {$_.extensiondata.AlarmActionsEnabled -eq $false}

This was discussed in the previous post, so I won’t discuss this at length. Its a pretty self evident line anyway 😉 With Get-VMHost called raw and bare naked like that we loop through all hosts piped to the where-object clause which checks for the AlarmActionsEnabled extension data.

Step 2: Enable them alarms!

The Service Instance in charge of handling alarms in the vCenter is the Alarm manager. So lets get a view of that manager entity to call on its management capabilities.

$alarmMgr = Get-View AlarmManager

Now that we have called on the Alarm Manager to the $alarmMgr variable, we can also call on EnableAlarmActions to enable alarms from our list of hosts whose alarms are disabled

$alarmMgr.EnableAlarmActions(<host_name>.Extensiondata.MoRef,$true)

Above line enables the alarms on the host that we specify

Let’s see how we can put all this together in one full script:

Connect-VIServer <vCenter>

$alarm_disabled_hosts = Get-VMHost | Where-Object {$_.extensiondata.AlarmActionsEnabled -eq $false}

$alarmMgr = Get-View AlarmManager


ForEach ($hosts in $alarm_disabled_hosts){

    $alarmMgr.EnableAlarmActions($hosts.Extensiondata.MoRef,$true)
    
}

This would enable alarms on all ESX hosts whose alarms are currently disabled.

Extra Credit : Skip hosts in maintenance mode

If the host is in maintenance mode, chances are that you are working on some error on the host and you will have to keep those alarms disabled. So for extra credit let’s see how we can modify the script to skip the hosts in maintenance mode:

Connect-VIServer <vCenter>

$alarmMgr = Get-View AlarmManager


ForEach ($hosts in $alarm_disabled_hosts){

    if ($hosts.ConnectionState -eq "Maintenance"){
        Write-Host "$hosts in maintenance mode, alarms will remain disabled"
    }

    else{
        Write-Host "Enabling alarms in $hosts"
        $alarmMgr.EnableAlarmActions($hosts.Extensiondata.MoRef,$true)
    }

}

And thats it! Keep this running on a schedule and you can be sure your environment has constant monitoring enabled.

If you found this useful, it helps me out if you share, comment or just generally spread the word (no pressure 😉 ). Social media links are below!

And as always, Happy scripting!

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 = {$_.build}}

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:

Explanation:
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 = {$_.build}} | 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 = {$_.build}} , @{Label = "Build Match" ; Expression = {if($_.build -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($_.build -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!