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.
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.

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.

That didn’t work. However, this will:

Fortunately, all you need to do is tell PowerShell to expand that property.
$s | select -expandproperty RequiredServices

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.

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:

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.

You don’t even need a variable.

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:

Going back to my original scenario, we can combine all of these ideas. We can easily expand the required services property:

And take the next step to get just the displayname.

Once you get used to thinking in this object notation, you’ll be amazed at how much can do without a lot of effort.
To expand all properties recursively in PowerShell, you can use the Get-Member cmdlet combined with a recursive function that iterates through each property. This approach helps you explore deep object hierarchies and expand all properties automatically, including those that are several levels deep.
While both commands can show properties, Select-Object -ExpandProperty specifically extracts and expands a single property, whereas Format-List * displays all properties but doesn’t actually expand them. For complete functionality, Select-Object offers more precise control over property expansion.
Yes, you can export expanded properties to CSV by using Export-CSV with the -ExpandProperties parameter. This maintains the hierarchical structure and makes it easier to work with nested data in spreadsheet applications.
To safely expand properties that might be null, use the PowerShell expand all properties feature with error handling by implementing try-catch blocks and the -ErrorAction parameter. This prevents crashes when encountering null values during property expansion.
When working with large datasets, it’s recommended to use selective property expansion rather than expanding all properties at once. Implement pagination or filtering before expansion, and utilize memory-efficient techniques like pipeline processing to manage resource usage effectively.