Tell Me More: Expanding Objects and Properties in PowerShell

Last Update: Sep 04, 2024 | Published: Nov 05, 2015

SHARE ARTICLE

One of the problems many PowerShell beginners have is getting their heads around the idea of objects in the pipeline. They see the output of a command and try to finagle something from the text they see on the screen.

This becomes tricky with object properties that contain a nested object or a collection of objects. You might start with a command like this:

$s = get-service bits

You’ll then look at $s.

A service object with nested objects (Image Credit: Jeff Hicks)
A service object with nested objects (Image Credit: Jeff Hicks)

If you look at the RequiredService property, then you should notice that the value is wrapped in curly brackets. This lets you know that the value is a collection of objects. You might try to look at those properties.
Selecting a property of nested objects (Image Credit: Jeff Hicks)
Selecting a property of nested objects (Image Credit: Jeff Hicks)

You still have an object, but it has a single property, and the value is still a collection. If you want to get at those objects, your might think you need to use ForEach-Object.
Attempting to expand nested objects (Image Credit: Jeff Hicks)
Attempting to expand nested objects (Image Credit: Jeff Hicks)

That didn’t work. However, this will:
Using ForEach to expand nested objects (Image Credit: Jeff Hicks)
Using ForEach to expand nested objects (Image Credit: Jeff Hicks)

Fortunately, all you need to do is tell PowerShell to expand that property.

$s | select -expandproperty RequiredServices

The easy way to expand a property (Image Credit: Jeff Hicks)
The easy way to expand a property (Image Credit: Jeff Hicks)

The only caveat is that you can only expand a single property. But you can also use this parameter if you simply want a list of values. For example, I often see people struggle with this concept, where they might run a command like this:

get-service | where {$_.status -eq 'running'} | Select name | out-file c:workrunning.txt

In their heads and perhaps based on experience with command-line tools, they are expecting a text file of only service names. But what they have really done is direct the output of a single property object to text file something that looks like this:

Name
----
Appinfo
AudioEndpointBuilder
Audiosrv
BcmBtRSupport
BFE
BITS
Bluetooth Device Monitor

The proper way is to expand the property so that all you get is the value.

Expanding a single property (Image Credit: Jeff Hicks)
Expanding a single property (Image Credit: Jeff Hicks)

Over time PowerShell has also gotten smarter. Let’s say that you have a variable with a collection of objects.

$running = get-service | where {$_.status -eq 'running'}

Let’s assume that all you need is the service name. In earlier versions of PowerShell, we used commands like this:

Using Foreach to list single property values (Image Credit: Jeff Hicks)
Using Foreach to list single property values (Image Credit: Jeff Hicks)

Of course, you now know you could use Select-Object.

$running | select -ExpandProperty Name

But you can also simply treat the variable as a single object and specify a property name.

Expanding a variable (Image Credit: Jeff Hicks)
Expanding a variable (Image Credit: Jeff Hicks)

You don’t even need a variable.
Expanding a property from an expression (Image Credit: Jeff Hicks)
Expanding a property from an expression (Image Credit: Jeff Hicks)

By wrapping the expression in parentheses, you are telling PowerShell, “run this command and treat the result as a variable.” Here’s one more example:
Another example of expanding a single property from a command (Image Credit: Jeff Hicks)
Another example of expanding a single property from a command (Image Credit: Jeff Hicks)

Going back to my original scenario, we can combine all of these ideas. We can easily expand the required services property:
Expanding nested service properties (Image Credit: Jeff Hicks)
Expanding nested service properties (Image Credit: Jeff Hicks)

And take the next step to get just the displayname.
Displaying a single property value from a collection of nested objects
Displaying a single property value from a collection of nested objects (Image Credit: Jeff Hicks)


Once you get used to thinking in this object notation, you’ll be amazed at how much can do without a lot of effort.

SHARE ARTICLE