PowerShell Sort-Object gotcha’s

This week I’m again delivering a PowerShell workshop and during the use of the Sort-Object Cmdlet in the Pipeline we had a interesting discussion which I want to share with you.

You all probably know you can use the Sort-Object Cmdlet in the Pipeline to sort your objects. Let’s start with a simple Ascending sort for the objects from the Get-Service cmdlet on the Service Name property.

 1 Get-Service | Sort-Object -Property Name | Format-Table Name, Status -AutoSize

This gives us a nicely formatted overview from all Services sorted Ascending on Name:

image

We can also sort on Name Descending with the –Descending parameter Switch for the Sort-Object Cmdlet.

 1 Get-Service | Sort-Object -Property Name -Descending | Format-Table Name, Status -AutoSize

image

Simple right?

But what if we want to do the following? We want to sort on Status Ascending. So we want to see first the Running Services before the Stopped Services. The “R” is before the “S” in the Alphabet. Right?

 1 Get-Service | Sort-Object -Property Status | Format-Table Name, Status -AutoSize

image

Strange? We expect to see the Running Services before the Stopped Services. Right? No not completely because when you sort in ascending order by status value, "Stopped" services appear before "Running" services.

The Status property of a service is an enumerated value in which the names of the statuses represent integer values. The sort is based on the integer value, not the name. "Running" appears before "Stopped" because "Stopped" has a value of "1",

and "Running" has a value of "4"

And what if we want to sort on two properties but both have a different sorting order?

Let’s sort our Services with the names in ascending order and status in descending order. Now we need to use hashtables.

 1 get-service | sort-object -property @{Expression="Status";Descending=$true}, @{Expression="Name";Descending=$false} | 
2     format-table name, status –autosize

image

Again keep in mind that sorting on Status Descending is showing the Running (value=4) before the Stopped (value=1) services.

Have fun!