I recently needed to compare version numbers with PowerShell, so I could deduce which software was superseded by a later version. But it turned out to be a little more complicated than anticipated!

In software versioning, I see 14.03.0.0 as being **less than** 14.1.0.56686. I also see 14.1.0.6 being **greater than** 14.1.0.56686. Maybe I’m wrong? Maybe it’s due to seeing software vendors wrongly version their software increments over the last 20 years and I’ve just got used to their logic?

Anyway, I ran some tests using the .Net [version] class and got the following:

```
$thisversion = "14.03.0.0"
$nextversion = "14.1.0.56686"
#test 1
switch (([version]$thisversion).CompareTo(([version]$nextversion))) {
{$_ -lt 0} { write-host "$thisversion is less than $nextversion" }
{$_ -gt 0} { write-host "$thisversion is greater than $nextversion" }
{$_ -eq 0} { write-host "$thisversion is the same as $nextversion" }
}
#returns 14.03.0.0 is greater than 14.1.0.56686 - wrong?
$thisversion = "14.1.0.6"
$nextversion = "14.1.0.56686"
#test 2
switch (([version]$thisversion).CompareTo(([version]$nextversion))) {
{$_ -lt 0} { write-host "$thisversion is less than $nextversion" } #returns this! wrong!
{$_ -gt 0} { write-host "$thisversion is greater than $nextversion" }
{$_ -eq 0} { write-host "$thisversion is the same as $nextversion" }
}
#returns 14.1.0.6 is less than 14.1.0.56686 - wrong?
```

So in our first example, it seems like .Net versioning ignores the leading zero in ’03’ and deduces that 3 is greater than 1. And in the second example, it deems that 56686 is greater than 6! Logically this is probably correct when comparing integers!

However i think software vendors perhaps write versions based on significant figures. So ’03’ is deemed as 3 (a unit), and the ‘1’ is deemed as ’10’ (a ten). And 56686 is deemed as 56686, but the 6 is deemed as 60000! Am i making any sense, or have I just made up my own versioning rules!!??

Either way, with help from others I contributed to writing a version comparison function that works….how software vendors work!

```
function CompareVersionStrings([string]$Version1, [string]$Version2) {
$v1 = $Version1.Split('.') -replace '^0', '0.'
$v2 = $Version2.Split('.') -replace '^0', '0.'
[Array]::Resize( [ref] $v1, 4 )
[Array]::Resize( [ref] $v2, 4 )
for ($i=0; $i-lt 4; $i++) {
switch (($v1[$i].length).CompareTo(($v2[$i].length))) {
{$_ -lt 0} { $v1[$i] = $v1[$i].PadLeft($v2[$i].Length,'0') }
{$_ -gt 0} { $v2[$i] = $v2[$i].PadLeft($v1[$i].Length,'0') }
}
}
$v1f = $v1 | % {[float]$_}
$v2f = $v2 | % {[float]$_}
return [Collections.StructuralComparisons]::StructuralComparer.Compare( $v1f, $v2f )
#function returns
#<0 "$Version1 is less than $Version2"
#>0 "$Version1 is greater than $Version2"
#0 "$Version1 is the same as $Version2"
}
#test 1
$thisversion = "14.03.0.0"
$nextversion = "14.1.0.56686"
switch (CompareVersionStrings $thisversion $nextversion) {
{$_ -lt 0} { write-host "$thisversion is less than $nextversion" }
{$_ -gt 0} { write-host "$thisversion is greater than $nextversion" } #returns this! wrong!
{$_ -eq 0} { write-host "$thisversion is the same as $nextversion" }
}
#returns 14.03.0.0 is less than 14.1.0.56686 - right!
#test 2
$thisversion = "14.1.0.6"
$nextversion = "14.1.0.56686"
switch (CompareVersionStrings $thisversion $nextversion) {
{$_ -lt 0} { write-host "$thisversion is less than $nextversion" } #returns this! wrong!
{$_ -gt 0} { write-host "$thisversion is greater than $nextversion" }
{$_ -eq 0} { write-host "$thisversion is the same as $nextversion" }
}
#returns 14.1.0.6 is greater than 14.1.0.56686 - right!
```

Hi Kae,

Thanks for the version compare script it really helpful.

But I encounter the login not work for this scenario

e.g:

$OldVersion = ‘120.0.6099.72’

$NewVersion = ‘120.0.6099.102’

the last 3 digit if .102 when compare with .72 it return result as

OldVersion = ‘120.0.6099.72’ is greater than NewVersion = ‘120.0.6099.102’.

where it padright to .720 compare with .102

can help to provide a solution if encounter this condition.

Sorry for the delay! Yes, I agree. I’ve swapped PadRight for PadLeft and it appears to work better! Thanks for the feedback!