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: