27

In PowerShell, if I have a list of strings containing versions, "3.0.1.1", "3.2.1.1", etc., how can I sort it the way System.Version would sort it in C#?

5 Answers 5

39
PS C:\> $ver="3.0.1.1","3.2.1.1"
PS C:\> $ver|%{[System.Version]$_}|sort

Major  Minor  Build  Revision
-----  -----  -----  --------
3      0      1      1
3      2      1      1
Sign up to request clarification or add additional context in comments.

1 Comment

You can also use $ver | %{ $_ -as [System.Version] } | sort. This one will filter out invalid version numbers (while the original one from the answer will throw an error when encountering an invalid version string.
12

Just convert it to a Version and sort that way:

$list = "3.0.1.1","3.2.1.1" 
$sorted = $list | %{ new-object System.Version ($_) } | sort

Comments

9

A version string can be cast to a Version object, and sort-object can be passed a script block and sort on the result.

PS C:\Users\me> "3.11.0.1", "3.0.1.1", "3.2.1.1" | sort
3.0.1.1
3.11.0.1
3.2.1.1

PS C:\Users\me> "3.11.0.1", "3.0.1.1", "3.2.1.1" | sort {[version] $_}
3.0.1.1
3.2.1.1
3.11.0.1

(Added an extra version string to make the example actually meaningful.)

1 Comment

Perfect many thanks!
2
# I needed to sort historical versions (Octopus) with varying decimal formats.
# Try # this (it is easy to add to a more complex expression sort)
# Special Case "3.00.1.10.1.10" and "3.0.1.10.1.10" required the double sort
# to work correctly
    $vers = @()`enter code here`
    $vers +=  @( "3.1.60",      "3.1.52","3.1.51")
    $vers +=  @( "3.00.46",     "3.00.36","3.50.2145.11")
    $vers +=  @( "3.50.2145.10","3.50.2145.9")
    $vers +=  @( "3.50.2145.8", "3.50.2145.7")
    $vers +=  @( "3.50.2145.6", "3.50.2145.5")
    $vers +=  @( "3.50.2145.4", "3.50.2145.3")
    $vers +=  @( "3.50.2145.2", "3.50.2145.1")
    $vers +=  @( "3.50.2145",   "3.50.2143")
    $vers +=  @( "3.50.2141",    "3.50.2135")    
    $vers +=  @( "3.0.1.10.1.1", "3.00.1.10.1.10")
    $vers +=  @( "2.1.3.4",      "3.0","3.")
    $vers +=  @( "3.0.1.10.1.100","3.0.1.10.1.10")
    $mySortAsc = @{Expression={ [regex]::Replace($_ ,'\d+', { $args[0].Value.PadLeft(20,'0') }) };Descending=$false}
    $mySortDesc = @{Expression={ [regex]::Replace($_ ,'\d+', { $args[0].Value.PadLeft(20,'0') }) };Descending=$true}    
    $nl = [Environment]::NewLine
    Write-Output ($nl + "Ascending Sort" + $nl);
    $vers | Sort-Object | Sort-Object $mySortAsc
    Write-Output ($nl + "Descending Sort" + $nl);
    $vers | Sort-Object -Descending | Sort-Object $mySortDesc
<# Result
Ascending Sort

2.1.3.4
3.
3.0
3.0.1.10.1.1
3.0.1.10.1.10
3.00.1.10.1.10
3.0.1.10.1.100
3.00.36
3.00.46
3.1.51
3.1.52
3.1.60
3.50.2135
3.50.2141
3.50.2143
3.50.2145
3.50.2145.1
3.50.2145.2
3.50.2145.3
3.50.2145.4
3.50.2145.5
3.50.2145.6
3.50.2145.7
3.50.2145.8
3.50.2145.9
3.50.2145.10
3.50.2145.11

Descending Sort

3.50.2145.11
3.50.2145.10
3.50.2145.9
3.50.2145.8
3.50.2145.7
3.50.2145.6
3.50.2145.5
3.50.2145.4
3.50.2145.3
3.50.2145.2
3.50.2145.1
3.50.2145
3.50.2143
3.50.2141
3.50.2135
3.1.60
3.1.52
3.1.51
3.00.46
3.00.36
3.0.1.10.1.100
3.00.1.10.1.10
3.0.1.10.1.10
3.0.1.10.1.1
3.0
3.
2.1.3.4
#>

3 Comments

While this code may answer the question, providing additional context regarding how and why it solves the problem would improve the answer's long-term value.
This works really well! I dont have proper System.Versions as my version names include a "V" before the numbers. The Regex does not seem to care about that. Nice!
@MasterAzazel you can just $verList | sort { [version]($_ -replace '^v') }
1

Just to add another corner case: powershell treats this single digit kind of version '2' as invalid. Have to add '.0' to the end to create the version object before sorting:

if($version  -match '^\d$')
{
  $version = $version + '.0'
}
New-Object System.Version $version

1 Comment

The .NET System.Version class declares version numbers consist of two to four components: major.minor[.build[.revision]].

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.