简体   繁体   中英

If statement for OS version

I do not get this to work and am I really confused why it is not working. My OS version is 10.0.14393 but it still prints that it is lower than 6? What is wrong here?

$verCheckOS = (Get-WmiObject Win32_OperatingSystem).Version

if ($verCheckOS -lt 6) {
    Write-Host -ForeGroundColor Red "Version is too low, $verCheckOS"
} else { 
    Write-Host -ForegroundColor Green "OS version is good, $verCheckOS"
}

This below with simple numbers work good so I do not know if the OS-version number is some specific type of datatype? How do I compare the OS version number with an if statement?

$value = 10

if ($value -lt 6) {
    Write-Host "Value is lower than 6"
} else {
    Write-Host "Value is greater than 6"
}

If you typecast the $verCheckOS variable, then something more interesting will happen:

[version]$verCheckOS = (Get-WmiObject win32_operatingsystem).version

When running the code you provided, we get an error:

if($verCheckOS -lt 6) { write-host -ForeGroundColor Red "Version is too low, $verCheckOS" }
Else { write-host -ForegroundColor Green "OS version is good, $verCheckOS" }

Could not compare "10.0.17134" to "6". Error: "Cannot convert value "6" to type "System.Version". 
Error: "Version string portion was too short or too long.""
At line:1 char:8

What happens here is the variable $verCheckOS is now a [version] datatype, and the lone integer 6 cannot be converted into a [version] datatype. It requires at least 2 octets to be able to be converted, as the [version] datatype is represented like so:

Major  Minor  Build  Revision
-----  -----  -----  --------
10     0      17134  -1      

There is a number of ways to deal with this depending on what number you're trying to compare. If you're simply looking to compare the 'Major' version octet, you can compare the integers as opposed to the versions:

if($verCheckOS.Major -lt 6) { write-host -ForeGroundColor Red "Version is too low, $verCheckOS" }
Else { write-host -ForegroundColor Green "OS version is good, $verCheckOS" }

This will return a positive result, by extrapolating the 'Major' version number and making an integer to integer comparison.

If you want to compare real 'versions', then you'll need to provide the comparison with 2 version objects, here's an example:

[version]$verCheckOS = (Get-WmiObject win32_operatingsystem).version
[version]$verCompare = "6.0"

if($verCheckOS -lt $verCompare) { write-host -ForeGroundColor Red "Version is too low, $verCheckOS" }
Else { write-host -ForegroundColor Green "OS version is good, $verCheckOS" }

To see the conversion from string to version happen in action or to try parse your own version numbers, use the [version] .NET class like so:

[version]::new("6.0")

(Get-WmiObject win32_operatingsystem).version returns a string (pipe to Get-Member to verify), so $verCheckOS -lt 6 performs lexical comparison:

  PS> '10.0.14393' -lt 6  # *lexical* comparison; 6 is coerced to a string
  True # !! lexically, '1' comes before '6'

Casting to [version] allows you to perform the intended numerical comparison based on the .Major property:

 PS> $verCheckOS = [version] (Get-WmiObject win32_operatingsystem).version
 PS> $verCheckOS.Major -lt 6  # 10 -lt 6 - numerical comparison
 False # OK

Adam Parson's helpful answer shows that it's also possible to meaningfully compare two [version] instances as a whole with -lt , which allows for more fine-grained comparison logic.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM