Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
140 views
in Technique[技术] by (71.8m points)

PowerShell script to return versions of .NET Framework on a machine?

What would a PowerShell script be to return versions of the .NET Framework on a machine?

My first guess is something involving WMI. Is there something better?

It should be a one-liner to return only the latest version for each installation of .NET [on each line].

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you're going to use the registry you have to recurse in order to get the full version for the 4.x Framework. The earlier answers both return the root number on my system for .NET 3.0 (where the WCF and WPF numbers, which are nested under 3.0, are higher -- I can't explain that), and fail to return anything for 4.0 ...

EDIT: For .Net 4.5 and up, this changed slightly again, so there's now a nice MSDN article here explaining how to convert the Release value to a .Net version number, it's a total train wreck :-(

This looks right to me (note that it outputs separate version numbers for WCF & WPF on 3.0. I don't know what that's about). It also outputs both Client and Full on 4.0 (if you have them both installed):

Get-ChildItem 'HKLM:SOFTWAREMicrosoftNET Framework SetupNDP' -recurse |
Get-ItemProperty -name Version,Release -EA 0 |
Where { $_.PSChildName -match '^(?!S)p{L}'} |
Select PSChildName, Version, Release

Based on the MSDN article, you could build a lookup table and return the marketing product version number for releases after 4.5:

$Lookup = @{
    378389 = [version]'4.5'
    378675 = [version]'4.5.1'
    378758 = [version]'4.5.1'
    379893 = [version]'4.5.2'
    393295 = [version]'4.6'
    393297 = [version]'4.6'
    394254 = [version]'4.6.1'
    394271 = [version]'4.6.1'
    394802 = [version]'4.6.2'
    394806 = [version]'4.6.2'
    460798 = [version]'4.7'
    460805 = [version]'4.7'
    461308 = [version]'4.7.1'
    461310 = [version]'4.7.1'
    461808 = [version]'4.7.2'
    461814 = [version]'4.7.2'
    528040 = [version]'4.8'
    528049 = [version]'4.8'
}

# For One True framework (latest .NET 4x), change the Where-Object match 
# to PSChildName -eq "Full":
Get-ChildItem 'HKLM:SOFTWAREMicrosoftNET Framework SetupNDP' -Recurse |
  Get-ItemProperty -name Version, Release -EA 0 |
  Where-Object { $_.PSChildName -match '^(?!S)p{L}'} |
  Select-Object @{name = ".NET Framework"; expression = {$_.PSChildName}}, 
@{name = "Product"; expression = {$Lookup[$_.Release]}}, 
Version, Release

In fact, since I keep having to update this answer, here's a script to generate the script above (with a little extra) from the markdown source for that web page. This will probably break at some point, so I'm keeping the current copy above.

# Get the text from github
$url = "https://raw.githubusercontent.com/dotnet/docs/master/docs/framework/migration-guide/how-to-determine-which-versions-are-installed.md"
$md = Invoke-WebRequest $url -UseBasicParsing
$OFS = "`n"
# Replace the weird text in the tables, and the padding
# Then trim the | off the front and end of lines
$map = $md -split "`n" -replace " installed [^|]+" -replace "s+|" -replace "|$" |
    # Then we can build the table by looking for unique lines that start with ".NET Framework"
    Select-String "^.NET" | Select-Object -Unique |
    # And flip it so it's key = value
    # And convert ".NET FRAMEWORK 4.5.2" to  [version]4.5.2
    ForEach-Object { 
        [version]$v, [int]$k = $_ -replace ".NET Framework " -split "|"
        "    $k = [version]'$v'"
    }

# And output the whole script
@"
`$Lookup = @{
$map
}

# For extra effect we could get the Windows 10 OS version and build release id:
try {
    `$WinRelease, `$WinVer = Get-ItemPropertyValue "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersion" ReleaseId, CurrentMajorVersionNumber, CurrentMinorVersionNumber, CurrentBuildNumber, UBR
    `$WindowsVersion = "`$(`$WinVer -join '.') (`$WinRelease)"
} catch {
    `$WindowsVersion = [System.Environment]::OSVersion.Version
}

Get-ChildItem 'HKLM:SOFTWAREMicrosoftNET Framework SetupNDP' -Recurse |
    Get-ItemProperty -name Version, Release -EA 0 |
    # For The One True framework (latest .NET 4x), change match to PSChildName -eq "Full":
    Where-Object { `$_.PSChildName -match '^(?!S)p{L}'} |
    Select-Object @{name = ".NET Framework"; expression = {`$_.PSChildName}}, 
                @{name = "Product"; expression = {`$Lookup[`$_.Release]}}, 
                Version, Release,
    # Some OPTIONAL extra output: PSComputerName and WindowsVersion
    # The Computer name, so output from local machines will match remote machines:
    @{ name = "PSComputerName"; expression = {`$Env:Computername}},
    # The Windows Version (works on Windows 10, at least):
    @{ name = "WindowsVersion"; expression = { `$WindowsVersion }}
"@

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...