22

I want to return an object from an array who's property has the highest value. Currently I am doing the following

Get-VM | Sort-Object -Property ProvisionedSpaceGB | Select-Object -Last 1

This works but is inefficient. I don't need the entire array sorted, I just need the object with largest value. Ideally I would use something like

Get-VM | Measure-Object -Property ProvisionedSpaceGB -Maximum

but this only returns the value of the object property, not the entire object. Is there a way to have measure-object return the base object?

2 Answers 2

21

Not directly. Measure-Object is intended to be an easy way to grab such values, not their input objects. You could get the maximum from Measure-Object and then compare against the array, but it takes a few steps:

$array = Get-VM
$max = ($array | measure-object -Property ProvisionedSpaceGB -maximum).maximum
$array | ? { $_.ProvisionedSpaceGB -eq $max}

You could also forgo Measure-Object entirely and iterate through the set, replacing the maximum and output as you go.

$max = 0
$array | Foreach-Object 
{ 
    if($max -le $_.ProvisionedSpaceGB)
    { 
        $output = $_ 
        $max = $_.ProvisionedSpaceGB
    } 
}
$output

This is a little dirtier so as to always return a single value. It would need a minor adjustment if you were to reuse it in a case where there may be multiple values that have the same maximum (filesize lengths when using Get-ChildItem, for example). It will replace $output with the latter iterate in a case where two or more objects have the same value for ProvisionedSpaceGB. You could turn $output into a collection easily enough to fix that.

I prefer the former solution myself, but I wanted to offer a different way to think about the problem.

Sign up to request clarification or add additional context in comments.

1 Comment

If you re-wrote $array | ? { $_.ProvisionedSpaceGB -eq $max} as @($array | ? { $_.ProvisionedSpaceGB -eq $max})[0] that might return a single value for you, but as Hyper Anthony noted, not always be the one you wanted.
15

You can use this:

$array = Get-VM | Sort-Object  -Property ProvisionedSpaceGB -Descending
$array[0]

1 Comment

This is exactly what the OP is doing, only in one line.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.