{"id":11521,"date":"2012-01-10T00:01:00","date_gmt":"2012-01-10T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2012\/01\/10\/order-your-output-by-easily-sorting-objects-in-powershell\/"},"modified":"2012-01-10T00:01:00","modified_gmt":"2012-01-10T00:01:00","slug":"order-your-output-by-easily-sorting-objects-in-powershell","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/order-your-output-by-easily-sorting-objects-in-powershell\/","title":{"rendered":"Order Your Output by Easily Sorting Objects in PowerShell"},"content":{"rendered":"<p><b>Summary<\/b>: Much of the time, there is no guarantee to the order in which Windows PowerShell returns objects. This blog explains how to fix that issue.<\/p>\n<p><span><span><span><span><span><span><span><span><img decoding=\"async\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\" \/><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>Hey, Scripting Guy! I have a problem with Windows PowerShell. It seems that it deliberately randomizes the output. I mean, there seems to be no rhyme or reason to the way that information is returned from a cmdlet. Am I alone in this frustration, or is there some secret sauce that I am missing? Windows PowerShell is cool, but if I always have to put data into an Excel spreadsheet just to sort it, then it is not much better than VBScript in my mind. Help me, oh fount of Windows PowerShell wisdom.<\/p>\n<p>&mdash;CD<\/p>\n<p><span><span><span><span><span><span><span><span><img decoding=\"async\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\" \/><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span>Hello CD,<\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. The other day, the Scripting Wife and I were at the first ever Windows PowerShell User Group meeting in Charlotte, North Carolina. It was really cool. We love being able to interact with people who love Windows PowerShell as much as we do. Next month, we are having a script-club type of meeting; we encourage people to show up with the Windows PowerShell scripts they are working on, so it will be a show-and-tell type of meeting.<\/p>\n<h2>Use Sort-Object to organize output<\/h2>\n<p>Anyway, after the user group meeting, when we were all standing around, one of the attendees came up to me and asked me in what order Windows PowerShell returns information. The answer is that there is no guarantee of return order in most cases. The secret sauce is to use the built-in sorting mechanism from Windows PowerShell itself. In the image that follows, the results from the <b>Get-Process <\/b>cmdlet appear to sort on the <strong>ProcessName <\/strong>property.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1803.HSG-01-10-12-01.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1803.HSG-01-10-12-01.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>One could make a good argument that the processes should sort on the process ID (PID) or on the amount of CPU time consumed, or on the amount of memory utilized. In fact, it is entirely possible that for each property supplied by the <b>Process<\/b><i> <\/i>object, someone has a good argument for sorting on that particular property. Luckily, custom sorting is easy to accomplish in Windows PowerShell. To sort returned objects in Windows PowerShell, pipe the output from one cmdlet to the <b>Sort-Object <\/b>cmdlet. This technique is shown here where the <b>Sort-Object <\/b>cmdlet sorts the <b>Process<\/b><i> <\/i>objects that are returned by the <b>Get-Process <\/b>cmdlet.<\/p>\n<p style=\"padding-left: 30px\">Get-Process | Sort-Object id<\/p>\n<p>The command to sort the <b>Process<\/b><i> <\/i>objects on the <b>ID <\/b>property and the output associated with that command are shown in the image that follows.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0513.HSG-01-10-12-02.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0513.HSG-01-10-12-02.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<h2>Reversing the sort order<\/h2>\n<p>By default, the <b>Sort-Object <\/b>cmdlet performs an ascending sort&mdash;the numbers range from small to large. To perform a descending sort requires utilizing the <b>Descending<\/b><i> <\/i>switch.<\/p>\n<p><b>Note<\/b>:&nbsp; There is no <b>Ascending<\/b><i> <\/i>switch for the <b>Sort-Object <\/b>cmdlet because that is the default behavior.<\/p>\n<p>To arrange the output from the <b>Get-Process <\/b>cmdlet such that the <b>Process<\/b><i> <\/i>objects appear from largest process ID to the smallest (the smallest PID is always 0&mdash;the Idle process), choose the <b>ID<\/b><i>&nbsp;<\/i>property to sort on, and use the <b>Descending<\/b><i> <\/i>switch as shown here:<\/p>\n<p style=\"padding-left: 30px\">Get-Process | Sort-Object id &ndash;Descending<\/p>\n<p>The command to perform a descending sort of processes based on the process ID, and the output associated with that command are shown in the image that follows.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/3364.HSG-01-10-12-03.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/3364.HSG-01-10-12-03.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>When you use the <b>Sort-Object <\/b>cmdlet to sort output, keep in mind that the first position argument is the property or properties upon which to sort. Because <b>Property<\/b><i> <\/i>is the default means that using the name <b>Property<\/b><i> <\/i>in the command is optional. Therefore, the following commands are equivalent:<\/p>\n<p style=\"padding-left: 30px\">Get-Process | Sort-Object id &ndash;Descending<\/p>\n<p style=\"padding-left: 30px\">Get-Process | Sort-Object -property id &ndash;Descending<\/p>\n<p>In addition to using the default first position for the <b>Property<\/b><i> <\/i>argument, the <b>Sort-Object <\/b>cmdlet is aliased by <b>sort<\/b>. By<b> <\/b>using <b>gps<\/b><i> <\/i>as an alias for the <b>Get-Process <\/b>cmdlet, <b>sort<\/b><i> <\/i>as an alias for <b>Sort-Object, <\/b>and a partial parameter of <b>des<\/b><i> <\/i>for <b>Descending<\/b>, the syntax of the command is very short. This short version of the command is shown here.<i><\/i><\/p>\n<p style=\"padding-left: 30px\">gps | sort id &ndash;des<\/p>\n<h2>Sorting multiple properties at once<\/h2>\n<p>The <b>Property<\/b><i> <\/i>parameter of the <b>Sort-Object <\/b>cmdlet accepts an array (more than one) of properties upon which to sort. This means that I can sort on the process name, and then sort on the working set of memory that is utilized by each process (for example). When supplying multiple property names, the first property sorts, then the second property sorts.<\/p>\n<p>The resulting output may not always meet expectations, and therefore, may require a bit of experimentation. For example, the command that follows sorts the process names in a descending order. When that sort completes, the command does an additional sort on the <b>WorkingSet<\/b> (<b>ws<\/b> is the alias) property. However, this second sort is only useful when there happen to be multiple processes with the same name (such as the <b>svchost<\/b><i> <\/i>process). The command that is shown here is an example of sorting on multiple properties.<\/p>\n<p style=\"padding-left: 30px\">Get-Process | Sort-Object -Property name, ws &ndash;Descending<\/p>\n<p>The figure that is shown here illustrates the output from the command to sort <b>Process<\/b><i> <\/i>objects based on <b>name<\/b> and <b>ws<\/b><i> <\/i>properties.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2046.HSG-01-10-12-04.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2046.HSG-01-10-12-04.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>When the <b>name<\/b> and <b>ws<\/b><i> <\/i>properties reverse order in the command, the resulting output is not very useful because the only sorting of the <b>name<\/b><i> <\/i>property happens when multiple processes have an identical working set of memory. The command that is shown here reverses the order of the <b>WorkingSet<\/b> and the process <b>name<\/b> properties.<\/p>\n<p style=\"padding-left: 30px\">Get-Process | Sort-Object -Property ws, name &ndash;Descending<\/p>\n<p>The output that is shown here shows that there is very little grouping of process names. In this example, adding the <b>name<\/b><i> <\/i>property does not add much value to the command.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/4718.HSG-01-10-12-05.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/4718.HSG-01-10-12-05.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<h2>Sorting and returning unique items<\/h2>\n<p>At times, I might want to see how many different processes are running on a system. To do this, I can filter duplicate process names by using the <b>Unique<\/b><i> <\/i>switch. To count the number of unique processes that are running on a system, I pipe the results from the <b>Sort-Object <\/b>cmdlet to the <b>Measure-Object <\/b>cmdlet. This command is shown here.<\/p>\n<p style=\"padding-left: 30px\">Get-Process | Sort-Object -Property name -Descending -Unique | measure-object<\/p>\n<p>To obtain a baseline that enables me to determine the number of duplicate processes, I drop the <b>Unique<\/b><i> <\/i>switch. This command is shown here.<\/p>\n<p style=\"padding-left: 30px\">Get-Process | Sort-Object -Property name -Descending | measure-object<\/p>\n<h2>Performing a case sensitive sort<\/h2>\n<p>One last thing to discuss when sorting items is the <b>CaseSensitive<\/b><i> <\/i>switch. When used, the <b>CaseSensitive<\/b><i> <\/i>switch sorts lowercase letters first, then uppercase. The following commands illustrate this.<\/p>\n<p style=\"padding-left: 30px\">$a = &#8220;Alpha&#8221;,&#8221;alpha&#8221;,&#8221;bravo&#8221;,&#8221;Bravo&#8221;,&#8221;Charlie&#8221;,&#8221;charlie&#8221;,&#8221;delta&#8221;,&#8221;Delta&#8221;<\/p>\n<p style=\"padding-left: 30px\">$a | Sort-Object &ndash;CaseSensitive<\/p>\n<p>When the two previous commands run, the output places the lowercase version of the word prior to the uppercase version. This output appears in the figure that follows.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1512.HSG-01-10-12-06.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1512.HSG-01-10-12-06.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>CD, that is all there is to sorting with Windows PowerShell. Pipeline Week will continue tomorrow when I will talk about grouping things with Windows PowerShell.<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><b>Ed Wilson, Microsoft Scripting Guy<\/b>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Much of the time, there is no guarantee to the order in which Windows PowerShell returns objects. This blog explains how to fix that issue. Hey, Scripting Guy! I have a problem with Windows PowerShell. It seems that it deliberately randomizes the output. I mean, there seems to be no rhyme or reason to [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[51,3,4,45],"class_list":["post-11521","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-getting-started","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Much of the time, there is no guarantee to the order in which Windows PowerShell returns objects. This blog explains how to fix that issue. Hey, Scripting Guy! I have a problem with Windows PowerShell. It seems that it deliberately randomizes the output. I mean, there seems to be no rhyme or reason to [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/11521","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=11521"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/11521\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=11521"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=11521"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=11521"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}