.NET Versions
Windows Server
.NET Installation
Production Server
.NET Framework

What's the foolproof way to tell which versions of .NET are installed on a production Windows Server?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

The foolproof answer is that you have to check two different product lines separately. .NET Framework is discovered from the Windows registry, while modern .NET, meaning .NET Core and .NET 5 or later, is discovered from the dotnet host and runtime folders. Checking only one of those will miss real installations on a production server.

Check .NET Framework from the Registry

For .NET Framework, the authoritative source is the registry under the NDP keys. Versions 4.5 and later are identified by the Release value under the Full subkey.

PowerShell example:

powershell
1$full = Get-ItemProperty `
2  "HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" `
3  -ErrorAction SilentlyContinue
4
5$full.Release

If that value exists, map it to the framework version using Microsoft's release table. For older framework versions such as 3.5 or 2.0, inspect the versioned NDP subkeys directly:

powershell
1Get-ChildItem "HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP" -Recurse |
2  Get-ItemProperty -Name Version -ErrorAction SilentlyContinue |
3  Where-Object { $_.Version } |
4  Select-Object PSChildName, Version

On 64-bit servers, it can also be worth checking the 32-bit registry view if you are auditing legacy software:

powershell
Get-ChildItem "HKLM:\SOFTWARE\WOW6432Node\Microsoft\NET Framework Setup\NDP" -Recurse

Check Modern .NET with the Host

For .NET Core, .NET 5, .NET 6, .NET 7, .NET 8, and later, the best first commands are:

powershell
dotnet --list-runtimes
dotnet --list-sdks

--list-runtimes tells you which runtime packs are installed, which is what deployed applications usually depend on. --list-sdks tells you which build SDKs are present, which matters for build servers or admin shells.

Sample output looks like:

text
Microsoft.AspNetCore.App 8.0.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 8.0.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]

If the server runs applications but does not have the dotnet command on PATH, inspect the installation folders directly:

powershell
Get-ChildItem "C:\Program Files\dotnet\shared\Microsoft.NETCore.App" -Name
Get-ChildItem "C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App" -Name

Why One Method Is Not Enough

This is where many production audits go wrong. A server can have:

  • '.NET Framework 4.8 for an older IIS application'
  • '.NET 8 runtime for a newer service'
  • No SDKs at all, because only runtimes are installed

A single registry query or a single dotnet command will not capture all of that.

There is also a deployment distinction worth remembering: ASP.NET Core hosting bundles, desktop runtimes, and plain Microsoft.NETCore.App runtimes are related but not identical. If you are validating a specific application host, make sure the exact runtime family required by that app appears in the runtime list.

A Practical Audit Script

For repeatable server checks, gather both families together:

powershell
1Write-Host ".NET Framework"
2Get-ChildItem "HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP" -Recurse |
3  Get-ItemProperty -Name Version, Release -ErrorAction SilentlyContinue |
4  Where-Object { $_.Version -or $_.Release } |
5  Select-Object PSChildName, Version, Release
6
7Write-Host ""
8Write-Host "Modern .NET runtimes"
9dotnet --list-runtimes
10
11Write-Host ""
12Write-Host "Modern .NET SDKs"
13dotnet --list-sdks

That is usually sufficient for production support work without remote GUI access.

Common Pitfalls

  • Checking only .NET Framework registry keys and forgetting modern .NET.
  • Checking only dotnet --list-sdks and assuming runtimes will appear there.
  • Using Environment.Version from an application process and assuming it identifies every installed runtime on the machine.
  • Forgetting that a production server may intentionally have runtimes installed without SDKs.

Summary

  • Use the registry for .NET Framework.
  • Use dotnet --list-runtimes and dotnet --list-sdks for modern .NET.
  • Audit both product lines because they are installed and versioned differently.
  • Prefer runtime checks over SDK checks when validating app-hosting capability.
  • On a production Windows Server, combining both methods is the closest thing to foolproof.

Course illustration
Course illustration

All Rights Reserved.