Working with Sort-Object Cmdlet

Working with Sort-Object Cmdlet

Rate This
  • Comments 4

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]

[Edit: Monad has now been renamed to Windows PowerShell. This script or discussion may require slight adjustments before it applies directly to newer builds.]

PSMDTAG:CMDLET:UTILITY: Sort-Object

PSMDTAG:FAQ: How do I do a multikey sort?

PSMDTAG:FAQ: How do I control the direction of sort?

PSMDTAG:FAQ: How do I sort on an expression?

Leave a Comment
  • Please add 5 and 7 and type the answer here:
  • Post
  • first I want to take a text file which is a table of numbers and sort them first descending by the first column and then ascending by the 3,4,5,6,7,8 and 9th columns in that order. There are 9 columns of data. By the way the second column is the binary equivalent of the first column.

  • How do you sort a single object's properties?  I have a cmdlet that outputs hundreds of properties and values and I cannot find any way to sort the output by the actual property values.

  • @Matthew McDondald at ION

    $hash | Sort-Object Value

    Try that.

  • @Alexander,  I was never notified of your response so was unable to respond.  At any rate, I tried what you suggested but that does not work.  

    [PS] C:\WINDOWS\system32>$hash | Sort-Object Value

    Name                           Value

    ----                           -----

    John                           100

    Henry                          90

    David                          80

    Tom                            90

    On a side note... I'm not particularly interested in sorting a custom hash.  My question was specifically regarding how to sort  any object by its properties.  For example:

    Get-Process System | fl *    

    The properties here are seemingly in a random order, with no apparent way to sort them.  I've found ways to do it by searching online, but they are very cumbersome.  I'm more interested in why the Powershell team did not include a means to sort properties natively.

Page 1 of 1 (4 items)