The method I use, is simply stripping off the host name - which I define as anything before the first dot (plus the first dot, but that doesn't really matter) - sorting by what's left, which is the domain, then sorting secondarily on just the host name, which I conveniently get by using the System.String class' Split() method on a period to extract what's before the first period in the string. It works. Actually, just using "Expression = { $_ }" will work too for the secondary sort criteria. That's essentially what I do in the example with a property.
This will work with PowerShell version 2 and up.
The same example, as text, for pasty delightfulness:
PS C:\> $Servers = @('host05.aaa.com', 'hostX.zzz.com', 'host10.bbb.com', 'host08.bbb.com', 'host06.ccc.com', 'host99.aaa.com', 'host00.ccc.com', 'host01.aaa.com') $Servers | Sort-Object @{ Expression = { $_ -replace '^[^.]+\.' } }, @{ Expression = { $_.Split('.')[0] } } host01.aaa.com host05.aaa.com host99.aaa.com host08.bbb.com host10.bbb.com host00.ccc.com host06.ccc.com hostX.zzz.com
And again, as text, for pasting, and for the visually impaired:
PS C:\> $ServerObj = $Servers | foreach { New-Object PSObject -Property @{ DNSHostName = $_ #ComputerName = $_.Split('.')[0] } } $ServerObj | Sort-Object @{ Expression = { $_.DNSHostName -replace '^[^.]+\.' } }, DNSHostName | Format-Table -AutoSize DNSHostName ----------- host01.aaa.com host05.aaa.com host99.aaa.com host08.bbb.com host10.bbb.com host00.ccc.com host06.ccc.com hostX.zzz.com
Me to the rescue! I even handle multiple levels of nesting in non-zero-padded numbers. By the way, that will also work for IPv4 addresses, if you modify it slightly and run it against the entire string by removing the ".Split()" method call, as an added bonus.
PS C:\> $Servers = @('host5.aaa.com', 'host00.zzz.com', 'host11a2.aaa.com', 'host11a11.aaa.com', 'host11a3.aaa.com', 'host11a10.aaa.com', 'host11.aaa.com', 'host1.aaa.com', 'host10.aaa.com', 'host2.aaa.com') $Servers | Sort-Object @{ Expression = { $_ -replace '^[^.]+\.' } }, @{ Expression = { [regex]::Replace($_.Split('.')[0], '(\d+)', { '{0:D16}' -f [int] $args[0].Value }) } }, @{ Expression = { $_ } } host1.aaa.com host2.aaa.com host5.aaa.com host10.aaa.com host11.aaa.com host11a2.aaa.com host11a3.aaa.com host11a10.aaa.com host11a11.aaa.com host00.zzz.com
That can be accomplished like this:
$Servers | Sort-Object @{Expression = { $TemporaryArray = @($_.Split('.')) [Array]::Reverse($TemporaryArray) $TemporaryArray }} b a.b a.com host01.aaa.com host05.aaa.com host99.aaa.com host00.bbb.com host08.bbb.com host10.bbb.com c.com c.c.com host00.ccc.com host06.ccc.com hostX.zzz.com a.d
Or, if you don't want to mix the subdomains with the host names, you could repeat it by first sorting one level up.
$Servers | Sort-Object @{Expression = { $TemporaryArray = @(([String]($_.Split('.', 2)[1])).Split('.')) [Array]::Reverse($TemporaryArray) $TemporaryArray }}, @{Expression = { $TemporaryArray = @($_.Split('.')) [Array]::Reverse($TemporaryArray) $TemporaryArray }} b a.b a.com c.com host01.aaa.com host05.aaa.com host99.aaa.com host00.bbb.com host08.bbb.com host10.bbb.com c.c.com host00.ccc.com host06.ccc.com hostX.zzz.com a.dPowershell Windows Regex All Categories
Minimum cookies is the standard setting. This website uses Google Analytics and Google Ads, and these products may set cookies. By continuing to use this website, you accept this.