Within PowerShell there are several different options for returning the OS version.
[environment]::OSVersion.Version
The OSVersion variable works in all OS's with one caveat being that Windows 8.1 will read as Windows 8.0 due to some API changes, despite that this is a good easy solution for most purposes.
To return a Single version number:
[double]$osver = [string][environment]::OSVersion.Version.major + '.' + [environment]::OSVersion.Version.minor
# In the above we cast to a string to build the value and then cast back to a double.
# This numeric version number can then be tested against a desired minimum version:
if ($osver -gt 6.0) {echo we have Windows Vista/Server 2008 or greater}if ($osver -gt 6.1) {echo we have Windows 7/Server 2008 R2 or greater}
if ($osver -gt 10.0) {echo we have Windows 10/Server 2016 or greater}
To get the OS version of a remote machine, you could run this same command with Invoke-Command
PS C:\> $ver = Invoke-Command -Computername computer64 -ScriptBlock {[Environment]::OSVersion.Version} PS C:\> $verHowever this is quite slow and requires setting up PS Remoting so a faster / easier alternative is to use
WMI/CIM as described below.
Get-CimInstance Win32_OperatingSystem
Get-CimInstance works in all OS’s but requires PowerShell 3.0+
Get-CimInstance like all the CIM cmdlets is particularly useful for querying remote machines, just add the -computername option.
Get-WmiInstance
An older and much slower version which predates the CIM* cmdlets, Get-WmiInstance works in PowerShell 1.0 and 2.0 but is deprecated in v3.0+ and not available at all in PowerShell 6.0
SystemInfo works in all OS’s but as a CMD utility you will have to parse the string output with FOR.
It is also very slow.
This also works in all OS’s but as an internal CMD command it has to be run within CMD.
To capture the output you either have to test the errorlevel or parse the string output.
Directly importing system DLLs and reading the version information. This works but requires rather a lot of code and there’s no guarantee those DLLs will be updated or even exist in future versions of Windows.
In Windows 10 we can also read the build/releaseID from the registry (1709,1803 etc)
[string]$osRelease = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").ReleaseIdAgain we can make this a handy function:
Function get-build{ [string]$osRelease = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").ReleaseId "$osRelease" }
One extra postscript about using an environment variable, is that system wide variables can potentially be changed, this can be very useful for testing changes but in highly secure systems you may not want to rely on the value always being true.
“In any collection of data, the figure most obviously correct, beyond all need of checking, is the mistake” ~ Finagle's third law
Related PowerShell Cmdlets:
Get-Host - returns the version of PowerShell.