Advanced Sorting (Part 4)

by Nov 9, 2021

In the previous parts we illustrated how you can use script blocks to gain more control over sorting. For example, you can use the “-as” operator to transform data to control the sort algorithm.

This way, you can “correct” the data type of incoming data, for example, in case some or all numeric data was submitted as string type. Take a look at the result of the first example, then the corrected result below:

 
PS> 1,2,"13",4,11,3,"2" | Sort-Object
1
13
2
3
4
11
2

PS> 1,2,"13",4,11,3,"2" | Sort-Object -Property { $_ -as [double] }
1
2
2
3
4
11
13   
 

Likewise, you can completely randomize lists, effectively creating simple random passwords:

 
PS> -join ('abcdefghkmnrstuvwxyz23456789*+#'.ToCharArray() | Get-Random -count 5 | Sort-Object -Property { Get-Random } )
m2v6u

PS> -join ('abcdefghkmnrstuvwxyz23456789*+#'.ToCharArray() | Get-Random -count 5 | Sort-Object -Property { Get-Random } )
b+g7t  
 

Or, you can sort based on calculated values. The example below sorts by file age, calculated by subtracting the last write time from the creation time:

Get-ChildItem -Path c:\windows -Filter *.log -Depth 1 -ErrorAction Ignore |
Sort-Object -Property { $_.LastWriteTime - $_.CreationTime } |
Select-Object -Property Name, LastWriteTime, CreationTime, @{Name='Age (Days)'={ [int]($_.LastWriteTime - $_.CreationTime).TotalDays }}

The result then looks similar to this:

 
Name                                 LastWriteTime       CreationTime        Age (Days)
----                                 -------------       ------------        ----------
setupapi.upgrade.log                 28.09.2020 15:04:56 28.09.2020 15:40:12          0
setuperr.log                         11.07.2021 14:37:51 11.07.2021 14:37:51          0
setupact.log                         16.10.2021 12:59:17 16.10.2021 12:59:17          0
setupapi.setup.log                   28.09.2020 17:48:22 28.09.2020 17:47:36          0
setupapi.offline.20191207_091437.log 07.12.2019 10:14:37 07.12.2019 10:13:02          0
setupapi.offline.log                 28.09.2020 15:40:12 28.09.2020 15:09:47          0
setupapi.dev.20201120_180252.log     20.11.2020 18:02:52 28.09.2020 17:51:43         53
setupapi.dev.20210514_095516.log     14.05.2021 09:55:16 27.02.2021 04:17:58         76
setupapi.dev.20210226_041725.log     26.02.2021 04:17:25 22.11.2020 04:18:58         96
lvcoinst.log                         23.10.2021 15:30:45 19.07.2021 08:46:48         96
PFRO.log                             25.10.2021 13:54:27 11.07.2021 14:41:28        106
WindowsUpdate.log                    26.10.2021 10:47:38 10.07.2021 15:05:05        108
setupapi.dev.20210710_201855.log     10.07.2021 20:18:55 27.02.2021 04:17:58        134
setupapi.dev.20210915_082529.log     15.09.2021 08:25:29 27.02.2021 04:17:58        200
NetSetup.LOG                         17.04.2020 15:19:26 26.08.2019 17:23:11        235
setupapi.dev.log                     26.10.2021 06:27:25 27.02.2021 04:17:58        241
mrt.log                              13.10.2021 08:30:39 12.11.2020 07:16:17        335
PASSWD.LOG                           25.10.2021 13:54:28 28.09.2020 17:47:22        392
ReportingEvents.log                  26.10.2021 09:37:23 03.09.2019 10:42:58        784
Gms.log                              25.10.2021 13:54:32 26.08.2019 17:27:50        791  
 

Note how you can use hash tables with Select-Object in a very similar way. In the example, the “Age (Days)” property was added to the output by submitting a hash table to Select-Object. Inside, the hash table defined the name of the new property and provided a script block to calculate the property value. This script block basically works like the script block discussed here: $_ represents the entire object, and you can use any PowerShell expression to transform or calculate the value.


Twitter This Tip! ReTweet this Tip!