My notes and ramblings, normally about automation

PowerCLI - Accurately Sorting VMTool Versions

· Read in about 2 min · (329 Words)
PowerCLI PowerShell VMware

Keeping a VM’s VMware Tools up-to-date is an important role to anyone whom administers a VMware environment. VMware Tools provide the latest and greatest drivers and provides easy access in order to interact with the underlying guest OS, like performing power options gracefully. However, there was also a recent security issue announced through the VMware Security Advisories page under Advisory ID: VMSA-2019-0009 More information about this advisory can be found in the following blog post: Security Issue with VMware Tools: VMSA-2019-0009

The above, plus a number of other reasons, lead us to the possibility of needing to create a report of VMs and their associated VMware Tools version. If you’ve ever tried doing this before, a simple Sort-Object -Property ToolsVersion will not work in the way you think. This is because the ToolsVersion property is of String type. We can overcome this by using PowerShell’s number format operator by adding a leading zero to the version output (where necessary). Once converted, we can sort the ToolsVersion property like normal!

Here’s the snippet which allows it all to happen:

# Create array to store output
$conversionOutput = @()
# Gather VMs into a variable
$vms = Get-VM | Where-Object {$_.PowerState -eq "PoweredOn"} 
# Loop to address each object in the $vms array
foreach ($vm in $vms) {
    # Conversion of the ToolsVersion property to add the leading zero
    $tempTools = $vm.Guest.ToolsVersion
    if ($tempTools) {
        $updatedTools = ("{0:00}" -f [int]$tempTools.Split('.')[0]) + "." + ("{0:00}" -f [int]$tempTools.Split('.')[1]) + "." + ("{0:00}" -f [int]$tempTools.Split('.')[2])
    } else {$updatedTools = $null}
    # Populate a temporary object to add to the output array
    $tempObj = New-Object -TypeName PSObject
    $tempObj | Add-Member -MemberType NoteProperty -Name Name -Value $vm.Name
    $tempObj | Add-Member -MemberType NoteProperty -Name ToolsVersion -Value $updatedTools
    $conversionOutput += $tempObj
}
# Prints the output array to the screen
$conversionOutput

Comparison of the Output: Example: Disk Information from vSphere Object

With the above said, there’s several ways to achieve the desired outcome. This is just the one that has worked best for me.