Tell Me More: Expanding Objects and Properties in PowerShell

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:\work\running.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.