In the previous tip we reported that ReleaseId is deprecated and can no longer be used to correctly identify the current Windows 10 version. Instead, DisplayVersion should be used:
PS> (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion').DisplayVersion 20H2
However, DisplayVersion, too, is not a dependable way of determining the current Windows 10 version as its purpose originally was to enable the shell to report the current version to the user. It, too, may change in the future.
The only supported safe way of identifying the current Windows 10 version is using an OS class called AnalyticsInfo. This is not trivial though because the class runs asynchronously in WinRT. PowerShell 7 (pwsh.exe) cannot access this class. The built-in Windows PowerShell (powershell.exe) however can create a wrapper and return the information:
# load WinRT and runtime types [System.Void][Windows.System.Profile.AnalyticsInfo,Windows.System.Profile,ContentType=WindowsRuntime] Add-Type -AssemblyName 'System.Runtime.WindowsRuntime' # define call and information to query [Collections.Generic.List[System.String]]$names = 'DeviceFamily', 'OSVersionFull', 'FlightRing', 'App', 'AppVer' $task = [Windows.System.Profile.AnalyticsInfo]::GetSystemPropertiesAsync($names) # use reflection to find method definition $definition = [System.WindowsRuntimeSystemExtensions].GetMethods().Where{ $_.Name -eq 'AsTask' -and $_.GetParameters().Count -eq 1 -and $_.GetParameters()[0].ParameterType.Name -eq 'IAsyncOperation`1' } # create generic method $Method = $definition.MakeGenericMethod( [System.Collections.Generic.IReadOnlyDictionary[System.String,System.String]] ) # call async method and wait for completion $task = $Method.Invoke.Invoke($null, $task) $null = $task.Wait(-1) # emit output $task.Result
The result looks similar to this:
Key Value --- ----- OSVersionFull 10.0.19042.985.amd64fre.vb_release.191206-1406 FlightRing Retail App powershell_ise.exe AppVer 10.0.19041.1 DeviceFamily Windows.Desktop
OSVersionFull returns the full details about the current Windows version.
Note that the method called in the example above can retrieve a lot more details. $names lists the attribute names to query. Unfortunately, there is no way to discover the available attribute names as 3rd party can add potentially endless additional information. The five attributes used in this example are the only ones guaranteed.