Sort a list of computers by domain first and then name, using PowerShell

From Svendsen Tech PowerShell Wiki
Jump to: navigation, search

If you have a list of computers from different domains, you might want to sort them by domain first and then the computer name. Here is how.

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.

Sorting computer names when you have strings

I put a bunch of fake hosts and domains in an array, and then demonstrate how to sort it by domain first and then by host name / computer name (anything real under these domains is unknown to me!).


The same example as text for pasty delightfulness:

PS C:\> $Servers = @('', '', '', '',
    '', '', '', '')
$Servers | Sort @{ Expression = { $_ -replace '^[^.]+\.' } }, @{ Expression = { $_.Split('.')[0] } }

Sorting computer names when you have an object with a string property

When you use Get-ADComputer, you get a DNSHostName property back. Here I use the same list of servers as in the example above, create custom PS objects (in a v2-compatible way) that have a DNSHostName as a string property, and then sort by domain and name. The sorting is actually easier, or at least less typing, this way.


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 @{ Expression = { $_.DNSHostName -replace '^[^.]+\.' } }, DNSHostName |
    Format-Table -AutoSize


Sorting computer names with numbers zero-padded

What if some despicable non-programmer decided to use the nomenclature "server1", "server2", "server3", etc. without padding with zeroes? Now your sorting is all whacked with 1, 10, 11, 12 ... 19, 2, 20, 21, 22 ... and so on.

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 = @('', '', '', '',
    '', '', 
    '', '', '', '')

$Servers | Sort @{ Expression = { $_ -replace '^[^.]+\.' } },
    @{ Expression = { [regex]::Replace($_.Split('.')[0], '(\d+)', { '{0:D16}' -f [int] $args[0].Value }) } },
    @{ Expression = { $_ } }