How to check the current version of Windows in PowerShell Core

Summary

The other day I was working on a (still-unpublished) article related to setting up your Windows development environment for SSL and I decided (for the first time) to use PowerShell Core to run one of the scripts. It didn't work as expected and I discovered that PowerShell Core doesn't return an accurate value when you ask it the current version of the Windows operating system; on Windows 10, PowerShell Core tells you it's running on Windows 8. Whilst this issue was fixed several months ago, the fix has still not been released so, in lieu of that, here is a more reliable way to get the current OS version which borrows from the code written to test the new version.

Background

Sometimes it's useful for a script to know about the environment in which it's running. Recently I tried to run the following code to determine the current version of Windows and which, whilst not actually being precise, gave me a sufficiently accurate answer for my purposes... until I ran it using PowerShell Core.

$winVer = [Environment]::OSVersion.Version.Major
if ($winVer -eq 6){  
    if ([Environment]::OSVersion.Version.Minor -ge 2){
        return 8
    } else {
        return 7
    }
}

Here's the first bit running in PowerShell 5, telling me I'm running Windows 10.
Getting the correct version of Windows in PowerShell And here it is in PowerShell Core, telling me I'm running Windows 8 (I know, it says Major Version 6, but the Minor Version is 2 and that's Windows 8).
Getting the incorrect version of Windows in PowerShell Core

As you can see from this pull request (https://github.com/PowerShell/PowerShell/pull/6457), this was fixed in March, but it is in version 6.1.0 which is now at rc1 and thus is still in pre-release (the current version of PowerShell Core is 6.0.4).

The specific code that tests the fix is at the bottom of this page: https://github.com/PowerShell/PowerShell/pull/6457/commits/9802e2ce71fd328b0d9c5f964793fd251e4f7226

The relevant bit is this line:

$osversionString = $psversiontable.os -replace "^Microsoft Windows (\d+\.\d+).*$",'$1'

This looks nice and simple, so perhaps we can use it.

What can I do in the meantime?

As we have seen from the tests for the new version of PowerShell Core, the $PSVersionTable variable returns the correct information. As it happens, I decided that I only care about the major version and, in fact, I only care if it's Windows 10 or not. Thus, I made the following tweak to my code:

$winVer = $PSVersionTable.OS -Replace "^Microsoft Windows (\d+).*$",'$1'

You can see it working below.

Getting the correct version of Windows in PowerShell Core

It's quite easy to see that you can get the Major, Minor and Build numbers by, for example, changing the line like this:

$PSVersionTable.OS -Replace "^Microsoft Windows (\d+\..*).*$",'$1'

And then dealing with the resultant string which, in our case, would be 10.0.17134.

The advantage of doing it this way is that it works now and it should continue to work in the future as well.

Conclusion

PowerShell Core is not exactly the same as the Windows-only version of PowerShell and determining the current version of Windows is one of the areas in which they differ. This unexpected behaviour caused me to scratch my head for a few minutes, especially when I noticed that it had been fixed back in March (until I noticed that it has still not been released). If that has also happened to you, then perhaps this will help.

I think the main thing to conclude from this is that you always need to test your code/scripts carefully and thoroughly to make sure that they behave as you're expecting them to.