Working with Sort-Object Cmdlet


In this blog I will try to explain different features of sort-object(Sort) cmdlet. For the purpose of this blog, I assume the following objects exist:


 


MSH C:\temp\monad> $a,$b,$c,$d


 


                                  Score Name


                                  —– —-


                                    100 John


                                     90 Henry


                                     90 Tom


                                     80 David


 


 


From the definition Sort looks like:


 


MSH C:\temp\monad> (get-command sort-object).Definition


sort-object [[-Property] Object[]] [-Descending] [-Unique] [-InputObject MshObj


ect] [-Culture String] [-CaseSensitive] [-Verbose] [-Debug] [-ErrorAction Actio


nPreference] [-ErrorVariable String] [-OutVariable String] [-OutBuffer Int32]


 


The basic usage looks like:


 


<expression> | sort <property>


 


Sort works on a collection of input objects possibly coming over from a pipeline. Sort will collect all the input objects from the pipeline and then sorts the objects based on other parameters like Property, Descending, Unique etc.


 


Example: To sort objects based on Score


 


MSH C:\temp\monad> $a,$b,$c,$d | sort score


 


                                  Score Name


                                  —– —-


                                     80 David


                                     90 Tom


                                     90 Henry


                                    100 John


 


Example: To sort objects based on Name


 


MSH C:\temp\monad> $a,$b,$c,$d | sort Name


 


                                  Score Name


                                  —– —-


                                     80 David


                                     90 Henry


                                    100 John


                                     90 Tom


 


Example: To sort objects in descending order based on Score


 


MSH C:\temp\monad> $a,$b,$c,$d | sort Score -Descending


 


                                  Score Name


                                  —– —-


                                    100 John


                                     90 Tom


                                     90 Henry


                                     80 David


 


Ok, this is all simple and you might yourself have already explored all this. Let us get into some tricky stuff. How to sort on Score (descending order) and Name (ascending order)


 


Example: sort on Score descending and then Name ascending


 


 


MSH C:\temp\monad> $a,$b,$c,$d | sort @{expression=”Score”;Descending=$true},@{e


xpression=”Name”;Ascending=$true}


 


                                  Score Name


                                  —– —-


                                    100 John


                                     90 Henry


                                     90 Tom


                                     80 David


 


Notice the use of @{expression=…}. If you notice the definition of sort-object, the parameter Property takes in a object[].  Property parameter can take entries of form <string> or hashtable (notice @). If the input is a hashtable, then Sort cmdlet specifically looks for “expression”,”ascending”,”descending” keys. Ascending and Descending can take only Booleans ( i.e., $true or $false ). Using expression you can do many things.


 


For example, lets say Henry is very punctual and very dedicated and you wanted to give some additional marks (lets say 2 marks) to encourage him.


 


Example:


 


MSH C:\temp\monad> $a,$b,$c,$d | sort @{expression={if ($_.Name -eq “Henry”) { $


_.Score += 2 }}},Score -Descending


 


                                  Score Name


                                  —– —-


                                    100 John


                                     92 Henry


                                     90 Tom


                                     80 David


 


Notice the use of Script for expression. In the above example, I changed the original object itself by using $_ and then sorted on Score


 


MSH C:\temp\monad> $b


 


                                  Score Name


                                  —– —-


                                     92 Henry


 


Using Script block you can do many things like computing Grades and then sorting on Grade.


 


MSH C:\temp\monad> $a,$b,$c,$d | sort Grade,@{expression={if ($_.Score -gt 91) {


$Grade=”A” } else {$Grade=”B” }; add-member noteproperty “Grade” $Grade -InputOb


ject $_}} -Descending


 


                     Score Name                       Grade


                     —– —-                       —–


                        90 Tom                        B


                        80 David                      B


                       100 John                       A


                        92 Henry                      A


 


Sort in its simplest form is very useful. Using expressions effectively makes it more powerful.


 


One last thing, a number of you has asked how to sort a hashtable using Sort-Object cmdlet.


 


MSH C:\temp\monad> $hash=@{“Tom”=90;”Henry”=90;”David”=80;”John”=100}


MSH C:\temp\monad> $hash | sort value -descending


 


Name                           Value


—-                           —–


Henry                          90


Tom                            90


David                          80


John                           100


This will not work as there is only one object on the pipeline and sort-object does not have anything to sort. However use GetEnumerator() on HashTable to write all the hash entries to the pipeline and then use sort.


 


MSH C:\temp\monad> $hash.GetEnumerator() | sort value -descending


 


Name                           Value


—-                           —–


John                           100


Tom                            90


Henry                          90


David                          80


 


-Krishna[MSFT]


Comments (1)

  1. Bruce says:

    Shoot, *now* you tell me I can sort by multiple properties!  That could have saved me a bit of code in my WTT script.

    Seriously, thanks for the info!  Very useful.

Skip to main content