$IPAddresses = @(
'10.11.12.13' '10.11.102.3' '10.11.10.26' '10.11.10.252' ) $IPAddresses | Sort |
10.11.10.252
10.11.10.26 10.11.102.3 10.11.12.13 |
If they are [ipaddress] objects, they do the same thing. The [ipaddress] does not have the built in methods that PowerShell would use to sort it, so PowerShell converts it to a string, and then sorts it typographically.
$IPAddresses = @(
[System.Net.IPAddress]'10.11.12.13' [System.Net.IPAddress]'10.11.102.3' [System.Net.IPAddress]'10.11.10.26' [System.Net.IPAddress]'10.11.10.252' ) $IPAddresses | Sort | Select IPAddressToString |
IPAddressToString
----------------- 10.11.10.252 10.11.10.26 10.11.102.3 10.11.12.13 |
I have in the past come up with a variety of complex ways to do it. Here’s one.
# Function to convert dotted decimal notation to integer64 (e.g. - "255.255.255.0" to 4294967040)
function ConvertDottedDecimalToInt64 ( $DottedDecimal ) { $DecimalParts = $DottedDecimal.Split( "." ) $Result = [int64]0 0..3 | ForEach { $Result += [int64]$DecimalParts[$_] * [math]::pow( 256, 3 - $_ ) } return $Result } $IPAddresses = @( '10.11.12.13' '10.11.102.3' '10.11.10.26' '10.11.10.252' ) $IPAddresses | Sort { ConvertDottedDecimalToInt64 $_ } |
10.11.10.26
10.11.10.252 10.11.12.13 10.11.102.3 |
There is an easier way
There is an object which can look like an IP address, which needs to be sorted like an IP address, and whose creators had the foresight to endow it with a .CompareTo() method, which is what PowerShell uses when it sorts things. The [System.Version] object is used to represent file and application versions, and we can leverage it to sort IP addresses simply. We sort on a custom calculation, converting the IP addresses to version objects. The conversion is just for sorting purposes. The output is the original input objects.
$IPAddresses = @(
'10.11.12.13' '10.11.102.3' '10.11.10.26' '10.11.10.252' ) $IPAddresses | Sort { [System.Version]$_ } |
10.11.10.26
10.11.10.252 10.11.12.13 10.11.102.3 |
The System namespace is the default namespace PowerShell searches for things, so we can leave that out and write it more simply.
$IPAddresses | Sort { [version]$_ }
|
Or if we want to go the other way, and avoid aliases and positional parameters, we can say it this way.
$IPAddresses | Sort-Object -Property { [System.Version]$_ }
|
Brilliant!
ReplyDeleteDamn, this is a great solution! Awesome!
ReplyDeleteIngenious!
ReplyDeleteVery helpful, thanks.
ReplyDeleteI searched for a way to do this and this site came up. Very nice, thank you.
ReplyDeleteOMFG! Awesome!!!
ReplyDeleteWow. Very clever.
ReplyDeletenice...
ReplyDeleteAwesome
ReplyDeleteGold!
ReplyDeleteAwesome!
ReplyDeleteNow I wonder if this is part 1, where are the other parts ? ;-)
Very smart
ReplyDeleteJust came to this page, brilliant that System.Version, but.. it's failing for me (multidimensional array, from uncontrolled source) when I happen to get devices without an IP Address, get this error, understandably so, but thought you might appreciate the feedback:
ReplyDeleteSort-Object : Cannot convert value "" to type "System.Version". Error: "Version string portion was too short or too long."
So I resorted to using your function, that did the trick, thanks!!