Making Sort-Object Smarter with Hash Tables

Posted
Comments None

Some months back I was trying to sort some Active Directory accounts so they looked nice in a report, but finding it a bit tedious using my usual methods. Consider the following fictitious accounts:

$list
GivenName Surname SamAccountName Enabled
--------- ------- -------------- -------
Steve     Jones   J3921             True
Will      Spencer S1134            False
Mary      Smith   S4498             True
Juanita   Galvez  G2059            False
Henry     Chang   C1209             True

Suppose I want to sort the list so enabled accounts appear at the top. That’s not terribly difficult.

$list | Sort-Object -Property Enabled -Descending
GivenName Surname SamAccountName Enabled
--------- ------- -------------- -------
Mary      Smith   S4498             True
Henry     Chang   C1209             True
Steve     Jones   J3921             True
Will      Spencer S1134            False
Juanita   Galvez  G2059            False

As you can see, it defaults to listing the disabled accounts first (I’m assuming this is because “F” comes before “T”), so I have to use the -Descending switch to reverse the sort. But what if I then want to sort by the last name?

$list | Sort-Object -Property Enabled,Surname -Descending
GivenName Surname SamAccountName Enabled
--------- ------- -------------- -------
Mary      Smith   S4498             True
Steve     Jones   J3921             True
Henry     Chang   C1209             True
Will      Spencer S1134            False
Juanita   Galvez  G2059            False

Well, it did sort on the Surname property… only it sorted backwards! My instinct for dealing with this dilemma was to break the list out with Group-Object or create a new property using Select-Object used solely for sorting. But that is undeniably clunky and if you’re suspecting there is a more elegant way to sort our list then you are correct correct—PowerShell lets us provide one or more hash tables to Sort-Object that utilize additional logic.

The correct way to sort the list above is really quite straightforward

$list | Sort-Object -Property @{expression='Enabled';Descending=$true},Surname
GivenName Surname SamAccountName Enabled
--------- ------- -------------- -------
Henry     Chang   C1209             True
Steve     Jones   J3921             True
Mary      Smith   S4498             True
Juanita   Galvez  G2059            False
Will      Spencer S1134            False

The only available keys we can use in the hash table are ‘Ascending,’ ‘Descending’ and ‘Expression.’ The Expression can be the name of a property, or a script block that applies some intelligent sorting. To help get the creative juices flowing, see if you can solve the “puzzles” below by figuring out how our list would be sorted.

$list | Sort-Object -Property @{expression={!$_.Enabled}},Surname
$list | Sort-Object -Property @{expression={($_.GivenName + $_.Surname).length};descending=$true},Surname
$list | Sort-Object -Property @{expression={[int]($_.SamAccountName.SubString(1,4))}}

Solutions below!

1. Does the same sort as our example in this post. Enabled accounts first, then alphabetically sorts the last name.
2. Reverse sorts by total name length, then alphabetically by Surname.
3. Sorts based on the 4-digit number in the SamAccountName. Note: this assumes that all SamAccountNames follow this pattern.

Author

Comments

There are currently no comments on this article.

Comment

Enter your comment below. Fields marked * are required. You must preview your comment before submitting it.





← Older Newer →