As a full-stack developer and professional coder, sorting data is an essential skill for efficiently analyzing information and simplifying reporting. PowerShell includes robust sorting functionality with the Sort-Object cmdlet that every developer should have in their toolkit.
In this comprehensive 2600+ word guide, I‘ll cover everything you need to know to leverage sorting in PowerShell.
How Sorting Works in PowerShell
The Sort-Object cmdlet in PowerShell allows sorting objects by their property values in ascending or descending order. The basic syntax is:
<Output to be sorted> | Sort-Object [-Descending] [-Unique] [-Property <prop1>, <prop2>, ...]
Some key parameters:
-Descending– Sorts in descending order instead of default ascending order-Unique– Removes duplicate entries after sorting-Property– Sort based on specific object properties-Stable– Maintains original order of equal items
When you pipe objects to Sort-Object, it collects them into a uniform list, sorts based on the parameters, then passes the sorted list down the pipeline.
Behind the scenes, PowerShell uses a QuickSort algorithm for optimal performance, with an average complexity of O(n log n). For large datasets, a stable hash table sort is used instead per this reference.
Now let‘s see Sort-Object and its built-in alias sort in action through examples.
Sorting Strings
Strings are sorted alphabetically by default whether using Sort-Object or the sort alias:
$strings = "banana", "apple", "cherry", "orange"
$strings | sort
Outputs:
apple
banana
cherry
orange
To sort descending, use -Descending:
$strings | Sort-Object -Descending
Result:
orange
cherry
banana
apple
Fun fact – PowerShell uses the Unicode values of characters to determine sort order for strings.
Sorting Numbers
Numbers are sorted numerically by default as you would expect:
$numbers = 10, 30, 8, 25, 15
$numbers | Sort-Object
Result:
8
10
15
25
30
Descending:
$numbers | Sort-Object -Descending
Gives:
30
25
15
10
8
Sorting Objects by Property
To sort objects like in structured data, you typically want to sort based on one of the object properties.
For example, get a list of processes sorted by ID:
Get-Process | Sort-Object -Property ID
You can sort based on any property name like process name, CPU usage, memory usage, thread count, etc.
As a developer, this technique is useful when handling custom objects or formatting output from APIs.
Sorting with Multiple Properties
To execute a multi-level sort using multiple properties, provide them as a hash table:
Sort-Object -Property `
@{Expression={Prop1}; Descending=$true}, `
@{Expression={Prop2}; Ascending=$false}
This will first sort by Prop1 descending, then by Prop2 ascending – building up the full sort order based on precedence.
Let‘s sort running processes by name ascending then by highest CPU usage descending:
Get-Process | Sort-Object -Property `
@{Expression={Name}; Ascending=$true}, `
@{Expression={CPU}; Descending=$true}
Now you have full control over complex sort logic using any set of properties.
Removing Duplicates
When sorting data, you often want to filter out duplicates which is done easily with the -Unique parameter:
$data | Sort-Object -Unique
Based on the sorted order, any duplicates will be omitted from the final output.
Statistics on the .NET garbage collector show a great example:
Get-Counter ‘\.NET CLR Memory(*)\% Time in GC‘ | Sort-Object -Property CounterSamples -Unique
This returns one entry per .NET runtime version, instead of duplicate entries for each CPU core.
Optimizing Performance
When dealing with extremely large datasets, sorting performance can degrade in PowerShell.
Here are some best practices for optimizing:
Use -Stable
The -Stable parameter maintains equal items in the original order instead of arbitrary shuffling:
$data | Sort-Object -Stable
Per Microsoft documentation, this speeds Sort-Object by up to 10% for somewhat sorted data.
Disable Script Analysis
Disable static code analysis with $PSScriptAnalysisPreference since it slows pipelines:
$PSScriptAnalysisPreference = ‘SilentlyContinue‘
$data | Sort-Object
Use Background Jobs
For giant datasets, use Start-Job to run sorting in the background:
$data | Start-Job { Sort-Object $_ } | Receive-Job
This avoids blocking the console during long operations.
Avoid Formatting
Avoid formatting cmdlets like Format-Table in the pipeline before Sort-Object:
# Slow
$data | Format-Table | Sort-Object
# Faster
$data | Sort-Object
So in summary, optimize large PowerShell sorts with:
$PSScriptAnalysisPreference = ‘SilentlyContinue‘
$data | Start-Job {
Sort-Object -Stable -Unique
} | Receive-Job
Sorting Files and Folders
In addition to structured data, PowerShell sorting works great for file metadata as well.
Get all files sorted recursively by last write time:
Get-ChildItem C:\Reports -Recurse |
Sort-Object -Property LastWriteTime
Other helpful properties are Name, Length, Attributes, etc.
Here is an example to sort downloads from newest to oldest by last write time. I have 3463 files in my Downloads folder taking up 12.6 GB:
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2/23/2023 5:23 PM 6185978801 Windows10-KB5010386-x64.msu
-a---- 2/22/2023 8:34 PM 2753846128 SW_DVD9_Win_Pro_10_21H2_64BIT_English_MLF_X22-23995.ISO
-a---- 2/18/2023 11:21 AM 2708930560 en_office_professional_plus_2021_x86_x64_dvd_6841864.iso
-a---- 2/15/2023 3:44 PM 1238NOS-Datacenter-Eval-6.5-3.ova
-a---- 2/12/2023 1:32 PM 860China_Cities_Database.csv
-a---- 2/10/2023 2:15 PM 6291735552 F-Secure-SENSE-windows-13.12-Full.12418.exe
-a---- 2/3/2023 10:22 AM 2203746339 Unity Setup-2020.3.26f1.exe
-a---- 1/10/2023 5:18 PM 18691080625 US_Cities_Database.sqlite3
This returns the most recently downloaded files first – perfect for analyzing my latest downloads.
The same technique works great for sorting log files, data files, configuration files, etc in any directory by last modified or creation time.
Custom Sort Logic with ScriptBlocks
For advanced use cases, you may need to define custom sorting logic that doesn‘t fit the usual properties.
Script blocks give you a way to encapsulate any C#/PowerShell logic into a reusable chunk.
For example, take this data with directory names and embedded numbers:
$data = "logs123", "scripts9000", "tools567", "notes"
I want to sort alphabetically, but with the number values as secondary precedence.
First define a script block containing logic to extract numbers if present:
$sortByNum = {
$num = 0
if ($_ -match ‘(\D+)(\d+)‘) {
$num = [int]$Matches[2]
}
return $num
}
Now we provide this script block to -Property:
$data | Sort-Object -Property $sortByNum
Result:
notes
logs123
tools567
scripts9000
It worked – sorted alphabetically with numbers taking higher priority!
By coding any logic into reusable script blocks, you get extremely flexible custom sorting powers.
Sort Command Syntax Cheat Sheet
Here is a quick cheat sheet for the common Sort-Object parameters and aliases:
Syntax:
Sort-Object [-Descending] [-Unique] [-Property <prop1>, <prop2>]
Aliases:
sort
Parameters:
-Descending # Sort descending
-Unique # Remove duplicates
-Property <prop> # Sort by property
-Stable # Preserve order of equal items
Examples:
Get-Process | Sort-Object -Property CPU -Descending
Get-ChildItem | Sort-Object -Property Length -Unique
$data | Sort { Process-Data $_ } -Unique
Print this out and keep it handy whenever you need to whip up a PowerShell pipeline!
Conclusion
In this power user guide, we covered step-by-step how to leverage PowerShell‘s extensive sorting capabilities:
- Using
Sort-Objectandsortto easily order output - Sorting strings, numbers, objects
- Multi-level sorts with hash tables
- Removing duplicates
- Background jobs for heavy sorting
- Custom sort logic with script blocks
With this deep knowledge, you can now use PowerShell sorting to simplify and enhance handling of any structured data – unlocking more effective reporting, analysis, and script automation.
Whether it‘s system APIs, software logs, database records or text processing, understanding PowerShell sorting transforms your ability to digest information.
Now get out there, use your new sort mastery to crunch some data and move mountains! The sky‘s the limit!


