Windows Version and Build Number
07 Oct 2018 · Comments: · Tags: Windows, PowerShellUPDATED 2022-10-08
Summary
This post demonstrates some techniques for obtaining Windows version information along with advice on what to avoid.
For older Windows operating systems (XP/2003 to 8.1/2012 R2) acquiring the version number was a somewhat simple endeavour.
Starting with Windows 10 and Windows Server 2016, releases consist of two parts,
a version number and a build number. A version number may have several build
numbers associated with it. For example, Windows 10 with the Anniversary Update
is version 1607
which consists of several builds, the last of which to be
released was 10.0.14393.1066
.
Obtaining the Version Information with PowerShell
XP/2003 to 8.1/2012 R2
My preference is to use the Win32_OperatingSystem
WMI class. Normally I’d
advocate using the Get-CimInstance
cmdlet but since the aim is to target
older versions of Windows your success may vary because the cmdlet wasn’t
introduced until PowerShell 3.0. I would therefore suggest using Get-WmiObject
(which has existed since PowerShell 1.0):
I’d advise against using the OSVersion
property of the .Net Environment
class ([Environment]::OSVersion
) because it is liable to return the wrong
result on Windows 8.1 if executed from the PowerShell ISE.
See Use PowerShell to Find Operating System Version.
Windows 10 / Windows Server 2016 (and beyond?)
Windows Registry
Both the version number and build number can be obtained from the registry. Each element of the build number is stored as a separate value and therefore must be pieced together.
The October 2020 update of Windows 10 had a version number of 20H2
, which
was the first release to use a new version numbering format representing:
"...the half of the calendar year in which the release becomes available in
retail and commercial channels", see
Windows Experience Blog: What's next for Windows 10 updates.
Behind the scenes, this change introduced a new registry value called
DisplayVersion
, rendering ReleaseId
redundant. I've therefore had to update
the code to use DisplayVersion
if present, otherwise fall back to
using ReleaseId
(to accommodate versions prior to 20H2
).
It wasn't necessary to do so, but I decided to dispense with the variable
$currentVersion
(featured in the original code above) and use the
pipeline instead. Since PowerShell doesn't permit the use an if statement
directly in a pipeline, I wrapped the code to the right of the pipe in
ForEach-Object
.
$PSVersionTable.BuildVersion - DO NOT Use This
DO NOT use $PSVersionTable.BuildVersion
.
I was originally under the misapprehension that the BuildVersion
property of
the PowerShell automatic variable $PSVersionTable
referred to that of the
Windows OS. I made this mistake because I happened to have access to a Windows
10 computer where $PSVersionTable.BuildVersion.ToString()
perfectly matched
the OS build number (10.0.16299.461
). It wasn’t until I checked another
Windows 10 computer that I noticed the values were different (10.0.17134.286
for the OS build number and 10.0.17134.228
for $PSVersionTable.BuildVersion.ToString()
).
NB: BuildVersion
has since been removed from $PSVersionTable
in PowerShell Core,
see Remove BuildVersion from $PSVersionTable #3877.
Alternative (but Inadequate) Methods for Obtaining Version and Build Number
Before choosing the registry as the source from which to obtain the version number and build number I looked at and rejected the following alternatives:
-
Get-WmiObject win32_operatingsystem | Format-List *
- Version number: Not present.
- Build number: Missing the Update Build Revision (UBR).
-
[Environment]::OSVersion
- Version number: Not present.
- Build number: The Update Build Revision (UBR) always returns zero.
Deriving the Windows OS from Version Information
Conventionally Microsoft produce a desktop OS and a server OS from
the same code base.
Consequently the version information for some desktop and server releases that
share the same code base is the same. For example, Windows 7 SP1 and Windows
Server 2008 R2 SP1 both return 6.1.7601.65536
.
Therefore it’s not possible to derive the Windows OS using only the version information. If you wish to be certain of whether the target OS is desktop or server then in addition to the version information you should also capture the OS name and edition:
Comments