Search code examples
powershellpowercli

PowerShell comparing numbers using -gt returning false results


I am querying some ESX Host statistics, and converting CPU time to CPU%, then using Where-Object -gt to only list those hosts where CPU is greater than 80.00 %. But my query is returning results where CPU is 9.00 because 9 is greater than 8, even though I have 80.00 in the query.

Here is my query:

Get-VMHost |
    Select Name, @{Name='CpuUsage';Expression={($_.CpuUsageMhz / $_.CpuTotalMhz).ToString('P')}},
        @{Name='MemoryUsage';Expression={($_.MemoryUsageGB / $_.MemoryTotalGB).ToString('P')}},
        @{N='NumVM';E={($_ | Get-VM).Count}} |
    Where-Object {$_.CpuUsage -gt 40}

And here is what is being returned. CPUUsage values are over 40 unless number begins with 5 or above. Like the last row which is only 8%, not 40%.

Name        CpuUsage MemoryUsage NumVM
----        -------- ----------- -----
server1.com 47.16 %  52.82 %        14
server2.com 50.07 %  45.75 %        13
server3.com 56.07 %  46.13 %        12
server4.com 48.56 %  48.24 %        13
server5.com 53.21 %  53.59 %        14
server6.com 66.01 %  44.20 %        11
server7.com 54.41 %  46.37 %        13
server8.com 8.08 %   9.18 %          2

Solution

  • The percentages in your calculated properties are formatted strings. Comparing them to an integer will do a string comparison, not a numeric comparison, because PowerShell will (try to) adjust the type of the second operand to match the first operand.

    Don't format values in calculated properties if you want to do further operations with the data. If you need formatted output you can pipe the output of the Where-Object filter to Format-Table and do the formatting there.

    Get-VMHost |
        Select Name, @{n='CpuUsage';e={$_.CpuUsageMhz / $_.CpuTotalMhz}},
            @{n='MemoryUsage';e={$_.MemoryUsageGB / $_.MemoryTotalGB}},
            @{n='NumVM';e={($_ | Get-VM).Count}} |
        Where-Object {$_.CpuUsage -gt 0.4} |
        Format-Table Name, @{n='CpuUsage';e={$_.CpuUsage.ToString('P')}},
            @{n='MemoryUsage';e={($_.MemoryUsage.ToString('P')}}, NumVM