dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
14.64k stars 4.57k forks source link

[System.Environment]::OSVersion.Version.Revision returns 0 #76823

Closed mmseng closed 1 year ago

mmseng commented 1 year ago

Description

I'm not much of a .NET person, so I wasn't sure where to submit this. I started here with the PowerShell community who pointed me here.

Expected behavior

When I enter [System.Environment]::OSVersion.Version.Revision into a PowerShell prompt, I expect to get the OS's current revision number, equivalent to Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' | Select -ExpandProperty "UBR".

For example:

PS> Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' | Select -ExpandProperty "UBR"
2006
PS> [System.Environment]::OSVersion.Version.Revision
2006

Observed behavior

0 is returned.

PS> Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' | Select -ExpandProperty "UBR"
2006
PS> [System.Environment]::OSVersion.Version.Revision
0

Environment

As noted, I'm not much of a .NET person, just an IT Pro with a penchant for PowerShell. The behavior described above happens across everything in our environment that I've tested, both in PowerShell 7 and 5.1. This primarily includes Win10 x64 Enterprise systems, 20H2 and newer.

I'm not sure exactly what you're looking for for .NET version, but if there's a command I can run or something to gather the necessary data, please let me know and I'll do it posthaste.

In general, we're not installing any specific version of .NET after imaging a machine, so it's whatever comes with the OS. Some googling indicates that this is generally 4.8 for the latest Win10 versions. Although in some cases we do also install older versions, as prerequisites to various software titles.

Example from a deployed machine:

PS C:\Windows\system32> Get-ItemProperty "HKLM:SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full"                      

CBS           : 1
Install       : 1
InstallPath   : C:\Windows\Microsoft.NET\Framework64\v4.0.30319\
Release       : 528372
Servicing     : 0
TargetVersion : 4.0.0
Version       : 4.8.04084
PSPath        : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework
                Setup\NDP\v4\Full
PSParentPath  : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4
PSChildName   : Full
PSDrive       : HKLM
PSProvider    : Microsoft.PowerShell.Core\Registry

Sources:

Regression?

I don't know whether this happened in any previous versions of the various environment components. I only just discovered the need for it and the apparent discrepancy.

Other information

None at this time.

dotnet-issue-labeler[bot] commented 1 year ago

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

ghost commented 1 year ago

Tagging subscribers to this area: @dotnet/area-system-runtime See info in area-owners.md if you want to be subscribed.

Issue Details
# Description I'm not much of a .NET person, so I wasn't sure where to submit this. I started [here](https://github.com/PowerShell/PowerShell/issues/18208) with the PowerShell community who pointed me here. # Expected behavior When I enter `[System.Environment]::OSVersion.Version.Revision` into a PowerShell prompt, I expect to get the OS's current revision number, equivalent to `Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' | Select -ExpandProperty "UBR"`. For example: ```console PS> Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' | Select -ExpandProperty "UBR" 2006 PS> [System.Environment]::OSVersion.Version.Revision 2006 ``` # Observed behavior `0` is returned. ```console PS> Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' | Select -ExpandProperty "UBR" 2006 PS> [System.Environment]::OSVersion.Version.Revision 0 ``` # Environment As noted, I'm not much of a .NET person, just an IT Pro with a penchant for PowerShell. The behavior described above happens across everything in our environment that I've tested, both in PowerShell 7 and 5.1. This primarily includes Win10 x64 Enterprise systems, 20H2 and newer. I'm not sure exactly what you're looking for for .NET version, but if there's a command I can run or something to gather the necessary data, please let me know and I'll do it posthaste. In general, we're not installing any specific version of .NET after imaging a machine, so it's whatever comes with the OS. Some googling indicates that this is generally 4.8 for the latest Win10 versions. Although in some cases we do also install older versions, as prerequisites to various software titles. Example from a deployed machine: ```console PS C:\Windows\system32> Get-ItemProperty "HKLM:SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" CBS : 1 Install : 1 InstallPath : C:\Windows\Microsoft.NET\Framework64\v4.0.30319\ Release : 528372 Servicing : 0 TargetVersion : 4.0.0 Version : 4.8.04084 PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4 PSChildName : Full PSDrive : HKLM PSProvider : Microsoft.PowerShell.Core\Registry ``` Sources: - https://stackoverflow.com/questions/35362303/which-net-version-does-windows-10-have-built-in#:~:text=Windows%2010%20(all%20editions)%20includes,is%20not%20installed%20by%20default. - https://docs.microsoft.com/en-us/archive/blogs/astebner/mailbag-what-version-of-the-net-framework-is-included-in-what-version-of-the-os - https://informatics-support.perkinelmer.com/hc/en-us/articles/4408235082900-How-to-find-what-Microsoft-NET-version-is-installed- ### Regression? I don't know whether this happened in any previous versions of the various environment components. I only just discovered the need for it and the apparent discrepancy. ### Other information None at this time.
Author: mmseng
Assignees: -
Labels: `area-System.Runtime`, `untriaged`
Milestone: -
terrajobst commented 1 year ago

It looks like we're always returning 0 for revision as RtlGetVersion doesn't include it.

https://github.com/dotnet/runtime/blob/3dbc850af3e8bfd6d529ed90cf00247dc9a24512/src/libraries/System.Private.CoreLib/src/System/Environment.Windows.cs#L120

What's your scenario for needing it? I think it's feasible for us to include it, but it might cause issues for upstream developers as we know that people's ability to write correct version checks has a fairly poor track record...

@jkotas what are your thoughts on this?

jkotas commented 1 year ago

Is the UBR registry key documented?

FWIW, we have changed the implementation of this function multiple times. In .NET Framework, this function calls GetVersionEx and the revision is encoded service pack version: https://github.com/microsoft/referencesource/blob/5697c29004a34d80acdaf5742d7e699022c64ecd/mscorlib/system/environment.cs#L1145

mmseng commented 1 year ago

The use case that led me to this is that I needed to check systems for compliance with mitigation of CVE-2022-37969. This was patched in the Sept. 13th security update, which presents as build revision 2006 (the Oct. 11th patch was 2130).

The simplest method to cover multiple builds (i.e. 19042, 19043, 19044), was to check the build revision for >= 2006.

The number of places one can reliably pull the UBR is pretty small, with the most reliable I've found being the registry keys noted in the OP. This however makes things much more complicated. It would be highly useful to have much easier access to it "natively" in PowerShell.

mmseng commented 1 year ago

I should note that, this IS more easily gettable in PowerShell 7 (6+?) with Get-ComputerInfo, which returns it as the WindowsUBR property. However Get-ComputerInfo in PowerShell 5.1 (which is what most vanilla systems are still equipped with) does not return this property at all. And unfortunately Get-ComputerInfo does not support targeting remote computers.

It's also returned by winver, but that's GUI only.

jkotas commented 1 year ago

Get-ComputerInfo in PowerShell 5.1

Powershell 5.1 runs on .NET Framework. It won't get this fix even if choose to fix this in .NET 8+.

mmseng commented 1 year ago

Sure. I didn't submit the issue because I wanted a fix for PowerShell 5.1. This is just how I came across it. I submitted it because it looks like a bug. Whether that's true or not, or whether it gets fixed, and in which version of which component, is above me.

dakersnar commented 1 year ago

The OS does not provide an API for querying the revision, so without that there is nothing more we can do here.

terrajobst commented 1 year ago

The OS does not provide an API for querying the revision, so without that there is nothing more we can do here.

Have we asked whether the UBR registry key is the official way to query it? At least answer seems to suggest that someone asked the product team.