PowerShell: Getting Properties From Objects In Arrays

In PowerShell, I often run commands that return arrays I need to filter. Once I’ve filtered out object I’m looking for, I need to read a property off that object. There are a few ways to do this. Here are three.

These are also good examples if you’re new to PowerShell and trying to switch from the Linux mindset of parsing strings to the PowerShell mindset of manipulating objects.

For these examples we’ll be using an array filtered from Get-Process:

Get-Process | Where-Object ProcessName -Match "update"

 NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
 ------    -----      -----     ------      --  -- -----------
      0     0.00      10.32     380.46     733   1 SoftwareUpdateN

Method 1: Select-Object

Select-Object reads properties from objects. We can pipe it the object we’ve found:

Get-Process | Where-Object ProcessName -Match "update" | Select-Object cpu

       CPU
       ---
380.761615

In this case, Where-Object returns one object and Select-Object reads the property off of it, but this still works if we match multiple processes. Then, Where-Object returns an array that gets unpacked by PowerShell’s pipeline and sent to Select-Object one at a time.

This is basically a property filter. It still returns an array of Process objects, but those objects only have the one property you selected. We can see this with Get-Member:

Get-Process | Where-Object ProcessName -Match "update" | Select-Object cpu | Get-Member

   TypeName: Selected.System.Diagnostics.Process

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
CPU         NoteProperty System.Double CPU=19.3147851

Four methods, but only one property.

Method 2: Subexpression

If we capture the output of our match command into a subexpression, we can access the object’s properties using dotted notation like we would with any variable:

$(Get-Process | Where-Object ProcessName -Match "update").cpu
380.761615

This also works if our match returned multiple objects. The subexpression will contain an array and PowerShell will automatically get the cpu property from each object in that array.

Unlike the filter of Select-Object, this doesn’t return Process objects with a cpu property. Instead, it returns a double (number) with the actual value:

$(Get-Process | Where-Object ProcessName -Match "update").cpu.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Double                                   System.ValueType

Method 3: Loop

Like any output, we can pipe our match into a ForEach-Object loop and use the $_ variable to access properties of each item the loop sees:

Get-Process | Where-Object ProcessName -Match "update" | ForEach-Object {$_.cpu}
381.625785

The loop will of course work on multiple objects.

Just like the subexpression, this returns the actual value instead of an object with one property.

Happy automating!

Adam

Need more than just this article? We’re available to consult.

You might also want to check out these related articles: