With the help of the Select-Object cmdlet, you can add a calculated property to the output of a PowerShell command. This allows you to enrich the displayed information.

You probably know PowerShell is all about objects. Objects are what make PowerShell great! By nature, all objects have properties, and we can read those properties by various means. The native objects we get back from commands like Get-Process, Get-Service, and a plethora of other commands are usually just fine. But sometimes the properties returned on an object need to change a little bit.

Perhaps you're building a report and need to display a few extra properties to export them correctly. Or maybe you need to tweak an existing property ever so slightly to get it in the format you'd like to see. For these reasons, we have calculated properties in PowerShell.

We can use the calculated properties feature with the Select-Object cmdlet to change or even add additional object properties as PowerShell returns them. Select-Object is a common cmdlet typically used in PowerShell either to show all properties on an object or to limit the default properties shown.

For example, by default, Get-Service will only show a limited number of properties.

Properties that Get-Service returns

Properties that Get-Service returns

If we pipe that same output to Select-Object using the Property parameter, we can show all objects, for example.

Service properties

Service properties

Using Select-Object with the Property parameter allows us to choose which properties to show. However, what if we want to add a custom property to the output or modify an existing property's value? For these situations, we can use calculated properties.

Instead of simple strings like Name, DisplayName, and such, PowerShell represents calculated properties with a hash table containing the name of the property to return and an expression. A script block represents the latter and contains the code to execute and generate the value. For a comparison, here's how we'd display the Name property that Get-Service returns:

Get-Service | Select-Object -Property Name

Here's how we could do the same but by using a calculated property:

Get-Service | Select-Object -Property @{Name = 'Name'; Expression = {$_.Name}}

The example above doesn't make a whole lot of sense because we wouldn't need a calculated property if just displaying the Name property. The example does show how to structure the hash table.

Notice a script block is inside of the Expression key. Inside of that script block, we can reference each object coming from Get-Service with the pipeline variable. For that matter, any object property or method is available for use.

To show a good example of calculated properties, take a look at the default output of Get-Service displayed in the screenshot above. Notice it does not show the path to the EXE the service is controlling. The EXE path is not a property that Get-Service returns natively. But by using calculated properties, we can "add" this property to the output by grabbing that value for each service that comes down the pipeline.

First, we need to figure out where to get the EXE path for each service. To do this, we can dip into the Win32_Service WMI class and gather it using Get-CimInstance. Below, I'm only returning the path for all services and assigning them to a variable. I grab all services ahead of time because if not, I would have had to issue a WMI query for every service, which would be inefficient coding.

$wmiServices = Get-CimInstance -ClassName win32_service -Property Name,PathName

Now that we have all the paths for each service safely stored in a variable, we can now add the code necessary to find the path for each service inside of the Expression script block.

Get-Service | Select-Object -Property *,@{Name = 'PathName'; Expression = { $serviceName = $_.Name; (@($wmiServices).where({ $_.Name -eq $serviceName })).PathName }}

Notice also that I had to still include the * as an element passed to the Property parameter since I still wanted to see all the other properties as well.

Subscribe to 4sysops newsletter!

Calculated properties

Calculated properties

Calculated properties are a great way to manipulate the properties that a command returns. By piping output from commands to Select-Object and using a hash table instead of a string for the Property parameter argument, you're able to return just about any object property you desire!