Table of Contents
We can organize displayed data to make it easier to scan using the Sort-Object cmdlet. Sort-Object takes the name of one or more properties to sort on, and returns data sorted by the values of those properties.
Basic sorting
Consider the problem of listing subdirectories and files in the current directory. If we want to sort by LastWriteTime and then by Name, we can do it by typing:
Get-ChildItem |
Sort-Object -Property LastWriteTime, Name | Format-Table -Property LastWriteTime, Name
LastWriteTime Name
------------- ----
8/9/2023 10:05:19 PM Program Files
8/4/2023 6:56:44 PM Windows
7/1/2023 2:07:54 PM Program Files (x86)
6/24/2023 5:32:20 PM sysinternals
6/2/2023 12:49:57 AM DumpStack.log
4/8/2023 6:45:30 AM PhSp_CS2_UE_Ret
4/6/2023 4:52:58 PM Users
5/7/2022 12:24:50 PM PerfLogs
You can also sort the objects in reverse order by specifying the Descending switch parameter.
Get-ChildItem |
Sort-Object -Property LastWriteTime, Name -Descending |
Format-Table -Property LastWriteTime, Name
LastWriteTime Name
------------- ----
8/9/2023 10:05:19 PM Program Files
8/4/2023 6:56:44 PM Windows
7/1/2023 2:07:54 PM Program Files (x86)
6/24/2023 5:32:20 PM sysinternals
6/2/2023 12:49:57 AM DumpStack.log
4/8/2023 6:45:30 AM PhSp_CS2_UE_Ret
4/6/2023 4:52:58 PM Users
5/7/2022 12:24:50 PM PerfLogs
Using hash tables
You can sort different properties in different orders using hash tables in an array. Each hash table uses an Expression key to specify the property name as string and an Ascending or Descending key to specify the sort order by $true or $false.
The Expression key is mandatory. The Ascending or Descending key is optional.
The following example sorts objects in descending LastWriteTime order and ascending Name order.
Get-ChildItem |
Sort-Object -Property @{ Expression = 'LastWriteTime'; Descending = $true },
@{ Expression = 'Name'; Ascending = $true } |
Format-Table -Property LastWriteTime, Name
LastWriteTime Name
------------- ----
8/9/2023 10:05:19 PM Program Files
8/4/2023 6:56:44 PM Windows
7/1/2023 2:07:54 PM Program Files (x86)
6/24/2023 5:32:20 PM sysinternals
6/2/2023 12:49:57 AM DumpStack.log
4/8/2023 6:45:30 AM PhSp_CS2_UE_Ret
4/6/2023 4:52:58 PM Users
5/7/2022 12:24:50 PM PerfLogs
You can also set a scriptblock to the Expression key. When running the Sort-Object cmdlet, the scriptblock is executed and the result is used for sorting. The following example sorts objects in descending order by the time span between CreationTime and LastWriteTime.
Get-ChildItem |
Sort-Object -Property @{ Exp = { $_.LastWriteTime - $_.CreationTime }; Desc = $true } |
Format-Table -Property Name, LastWriteTime, CreationTime
Name LastWriteTime CreationTime
---- ------------- ------------
Program Files 8/9/2023 10:05:19 PM 5/7/2022 12:24:50 PM
Windows 8/4/2023 6:56:44 PM 5/7/2022 12:17:22 PM
Program Files (x86) 7/1/2023 2:07:54 PM 5/7/2022 12:24:50 PM
Users 4/6/2023 4:52:58 PM 5/7/2022 12:17:22 PM
DumpStack.log 6/2/2023 12:49:57 AM 4/7/2023 6:42:25 AM
sysinternals 6/24/2023 5:32:20 PM 6/24/2023 5:21:07 PM
PhSp_CS2_UE_Ret 4/8/2023 6:45:30 AM 4/8/2023 6:45:22 AM
PerfLogs 5/7/2022 12:24:50 PM 5/7/2022 12:24:50 PM
Tips and tricks
You can omit the Property parameter name as following:
Sort-Object LastWriteTime, Name
Besides, you can refer to Sort-Object by its built-in alias, sort:
sort LastWriteTime, Name
The keys in the hash tables for sorting can be abbreviated as below. In this example, the e stands for Expression, the d stands for Descending, and the a stands for Ascending.
Sort-Object @{ e = 'LastWriteTime'; d = $true }, @{ e = 'Name'; a = $true }
To improve readability, you can place the hash tables into a separate variable:
$order = @(
@{ Expression = 'LastWriteTime'; Descending = $true }
@{ Expression = 'Name'; Ascending = $true }
)
Get-ChildItem |
Sort-Object $order |
Format-Table LastWriteTime, Name