I have seen come up against this in my own work and have seen the question come up a few times on the PowerShell Reddit community.  When you are sorting objects with the Sort-Object pipeline cmdlet based on a string property that contains a number it does not always work quite as expected.

In most cases sort object will work with no problems, for example if you are sorting based on strings with no numbers you will get:

"ESX-C", "ESX-A", "ESX-D", "ESX-B" | Sort-Object

ESX-A
ESX-B
ESX-C
ESX-D

This is working as you would expect a sort to work, the same is true for just numbers as they will be treated as Integers instead of Strings and sorted correctly.

However if you have a string that contains numbers you can now get problems:

"ESX-10", "ESX-2", "ESX-24", "ESX-5" | Sort-Object

ESX-10
ESX-2
ESX-24
ESX-5

This now sorts incorrectly because in the double digit numbers it sorts by each digit individually putting 10 before 2, because 1 comes before 2.

Now there is a solution for this, if you are getting this same problem it can be fixed using some clever RegEx.

"ESX-10", "ESX-2", "ESX-24", "ESX-5" | sort-object -Property {$_-replace '[\d]'},{$_-replace '[a-zA-Z\p{P}]'-as [int]} 

ESX-2
ESX-5
ESX-10
ESX-24

So what this now does is sorts on two fields, first off the RegEx removes all the numbers and then sorts the list based on just the letters and punctuation, next the second RegEx removes all letters and punctuation leaving just the numbers, then casts the numbers to an Integer and sorts again.  This results in the list being correctly sorted.

Comments