Complete Guide to Querying .NET Framework Versions Using PowerShell

Nov 20, 2025 · Programming · 8 views · 7.8

Keywords: PowerShell | .NET Framework | Version Detection | Registry Query | Automation Script

Abstract: This article provides a comprehensive guide on using PowerShell scripts to detect installed .NET Framework versions in Windows systems. Through analysis of registry structures and version mapping relationships, it offers complete solutions from basic queries to advanced version identification, including Release value conversion for .NET Framework 4.5+ and compatibility handling for earlier versions.

Introduction

Accurately detecting installed .NET Framework versions is a common requirement in Windows system administration and application development. While manual inspection through Control Panel or Settings applications is possible, programmatic queries become essential in automation scripts and bulk deployment scenarios. PowerShell, as a powerful scripting tool on the Windows platform, provides convenient registry access capabilities, making it an ideal choice for achieving this goal.

Fundamental Principles of .NET Framework Version Detection

.NET Framework installation information is primarily stored in the Windows registry. For different framework versions, registry paths and key value structures show significant differences:

For .NET Framework 4.5 and later versions, relevant information is located under the HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full path. The crucial Release REG_DWORD value corresponds to specific framework versions and requires conversion through predefined mapping tables.

Earlier versions (1.0-4.0) are distributed across different subkeys under HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP, identified by key values such as Install and Version that indicate installation status and specific versions.

Basic Query Script Implementation

The following PowerShell script provides basic .NET Framework version detection functionality:

Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -Recurse |
Get-ItemProperty -Name Version, Release -ErrorAction SilentlyContinue |
Where-Object { $_.PSChildName -match '^(?!S)\p{L}' } |
Select-Object PSChildName, Version, Release

The core logic of this script includes:

Advanced Version Mapping Solution

For .NET Framework 4.5+ versions, Release values need to be converted to readable version numbers. Here is the complete solution:

$VersionMap = @{
    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'
}

Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -Recurse |
Get-ItemProperty -Name Version, Release -ErrorAction SilentlyContinue |
Where-Object { $_.PSChildName -match '^(?!S)\p{L}' } |
Select-Object @{
    Name = ".NET Framework"; Expression = { $_.PSChildName }
}, @{
    Name = "Product"; Expression = { $VersionMap[$_.Release] }
}, Version, Release

Architecture Compatibility Considerations

When running 32-bit applications on 64-bit systems, registry paths require special handling. The correct approach is to access the HKLM:\SOFTWARE\Wow6432Node\Microsoft\NET Framework Setup\NDP path. The following code demonstrates proper handling of architecture differences:

# Detect system architecture and select correct registry path
if ([Environment]::Is64BitOperatingSystem -and -not [Environment]::Is64BitProcess) {
    $BasePath = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\NET Framework Setup\NDP'
} else {
    $BasePath = 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP'
}

Version Verification and Minimum Version Checking

In practical applications, it's often necessary to verify whether a specific version or higher of .NET Framework is installed. The following example checks if .NET Framework 4.6.2 or later is installed:

$ReleaseValue = Get-ItemPropertyValue -LiteralPath 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full' -Name Release
$IsInstalled = $ReleaseValue -ge 394802
Write-Output "NET Framework 4.6.2 or later installed: $IsInstalled"

Automated Script Generation

To maintain the timeliness of version mappings, scripts can be created to automatically generate mapping tables from official documentation:

$DocumentUrl = "https://raw.githubusercontent.com/dotnet/docs/master/docs/framework/migration-guide/how-to-determine-which-versions-are-installed.md"
$MarkdownContent = Invoke-WebRequest $DocumentUrl -UseBasicParsing

# Parse Markdown tables and generate version mappings
$MappingTable = $MarkdownContent -split "`n" |
Where-Object { $_ -match "^\|.*NET Framework" } |
ForEach-Object {
    $Parts = $_ -replace "\|" -split "\s+"
    if ($Parts.Count -ge 2) {
        "    $($Parts[1]) = [version]'$($Parts[0])'"
    }
}

Write-Output "`$VersionMap = @{"
$MappingTable
Write-Output "}"

Performance Optimization Recommendations

When using version detection scripts in production environments, consider the following optimization measures:

Practical Application Scenarios

These techniques can be applied in various scenarios:

Conclusion

Using PowerShell to query the registry for .NET Framework version detection is a reliable and efficient method. The scripts and techniques provided in this article cover complete solutions from basic queries to advanced version mapping, capable of meeting requirements in different scenarios. As the .NET ecosystem continues to evolve, it's recommended to regularly update version mapping tables to ensure accuracy.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.