How to Install .NET Framework and .NET on Windows Server 2022

Windows Server 2022 ships with .NET Framework 4.8 pre-installed, making it the most capable out-of-the-box runtime for legacy ASP.NET applications. However, modern workloads increasingly require the cross-platform .NET runtime (formerly .NET Core) — versions 6, 7, or 8. This guide covers checking what is already installed, adding .NET Framework features, installing .NET 6/7/8, managing multiple versions side-by-side, and using the dotnet CLI effectively on Server Core and Desktop Experience.

.NET Framework 4.8 on Windows Server 2022

Windows Server 2022 includes .NET Framework 4.8 as an optional Windows feature. On Desktop Experience installations it may already be enabled. On Server Core you may need to install it explicitly. Use PowerShell to check and install the feature:

Get-WindowsFeature NET-Framework-45-Core
Get-WindowsFeature NET-Framework-45-ASPNET
Get-WindowsFeature NET-WCF-Services45

The feature name NET-Framework-45-Core is the base runtime and is required before enabling ASP.NET or WCF features. To install it along with HTTP Activation (required for WCF services over HTTP):

Install-WindowsFeature NET-Framework-45-Core -IncludeAllSubFeature
Install-WindowsFeature NET-WCF-HTTP-Activation45

You can also install .NET Framework 4.8 features via Server Manager under Add Roles and Features > Features > .NET Framework 4.8 Features. The installer does not require a reboot when the binaries are already present in the Windows component store (WinSxS), which they are on a freshly installed Windows Server 2022 system.

Verifying Installed .NET Framework Version

The .NET Framework version is stored in the Windows registry. The most reliable way to query it is:

Get-ItemProperty -Path "HKLM:SOFTWAREMicrosoftNET Framework SetupNDPv4Full" -Name Release, Version

A Release value of 528040 or higher confirms .NET Framework 4.8 is installed. You can also check from the command line:

reg query "HKLMSOFTWAREMicrosoftNET Framework SetupNDPv4Full" /v Release

On a standard Windows Server 2022 installation, you should see a Release DWORD value of 528049 or higher, which maps to .NET Framework 4.8 on Windows Server 2022.

Installing .NET 6, 7, or 8 (Modern .NET)

Modern .NET (version 5 and later) is not a Windows Feature — it is installed separately from Microsoft’s release servers. There are three installation methods: the official installer MSI, the dotnet-install PowerShell script, and the winget package manager.

Method 1: MSI Installer

Download the .NET 8 SDK or runtime MSI from https://dotnet.microsoft.com/en-us/download/dotnet/8.0. Choose the Windows x64 installer. Run it silently with:

Start-Process -FilePath "dotnet-sdk-8.0.100-win-x64.exe" -ArgumentList "/install /quiet /norestart" -Wait

Method 2: dotnet-install.ps1 Script

Microsoft provides a PowerShell installation script that is ideal for automated deployments and CI/CD pipelines. Download and run it as follows:

# Download the install script
Invoke-WebRequest -Uri "https://dot.net/v1/dotnet-install.ps1" -OutFile "C:dotnet-install.ps1"

# Install .NET 8 SDK (current channel)
& C:dotnet-install.ps1 -Channel 8.0 -Runtime sdk

# Install only the ASP.NET Core Runtime
& C:dotnet-install.ps1 -Channel 8.0 -Runtime aspnetcore

# Install to a custom directory
& C:dotnet-install.ps1 -Channel 8.0 -InstallDir "C:dotnet8"

Method 3: winget

If winget is available (it is included with newer Windows Server 2022 updates), you can install .NET with a single command:

winget install Microsoft.DotNet.SDK.8
winget install Microsoft.DotNet.AspNetCore.8

Configuring DOTNET_ROOT

The DOTNET_ROOT environment variable tells the .NET SDK and runtime tooling where the .NET installation is located. This is especially important when you have installed .NET to a non-default path. The default installation directory on Windows is C:Program Filesdotnet. To set it system-wide:

[System.Environment]::SetEnvironmentVariable(
    "DOTNET_ROOT",
    "C:Program Filesdotnet",
    [System.EnvironmentVariableTarget]::Machine
)

# Add dotnet to PATH if not already present
$currentPath = [System.Environment]::GetEnvironmentVariable("PATH", "Machine")
if ($currentPath -notlike "*C:Program Filesdotnet*") {
    [System.Environment]::SetEnvironmentVariable(
        "PATH",
        "$currentPath;C:Program Filesdotnet",
        [System.EnvironmentVariableTarget]::Machine
    )
}

After setting environment variables at the machine level, open a new PowerShell session or run refreshenv (if Chocolatey is installed) for the changes to take effect in the current shell.

Running Multiple .NET Versions Side-by-Side

One of the key advantages of modern .NET over .NET Framework is side-by-side installation. You can have .NET 6, 7, and 8 installed simultaneously on the same server. Each version lives in its own subdirectory under C:Program Filesdotnetsdk and C:Program Filesdotnetshared:

# List all installed SDKs
dotnet --list-sdks

# List all installed runtimes
dotnet --list-runtimes

# Show full SDK/runtime info
dotnet --info

Sample output from dotnet --list-sdks:

6.0.419 [C:Program Filesdotnetsdk]
7.0.409 [C:Program Filesdotnetsdk]
8.0.101 [C:Program Filesdotnetsdk]

Each project will automatically use the correct SDK version based on the project file’s <TargetFramework> element or the global.json file in the directory tree.

Pinning SDK Version with global.json

When you need to ensure that all developers and CI agents use exactly the same SDK version, place a global.json file in the root of your repository or solution directory:

{
  "sdk": {
    "version": "8.0.101",
    "rollForward": "latestPatch",
    "allowPrerelease": false
  }
}

The rollForward policy controls what happens when the pinned version is not installed:

  • disable — fail if the exact version is absent
  • patch — roll forward to the latest patch of the specified minor version
  • latestPatch — use the latest patch of the specified minor version (recommended)
  • minor — roll forward to the latest minor version if exact is missing
  • latestMajor — use the absolute latest SDK installed

Create the file from PowerShell:

New-Item -Path "C:MyAppglobal.json" -ItemType File -Value '{
  "sdk": {
    "version": "8.0.101",
    "rollForward": "latestPatch"
  }
}'

Using the dotnet CLI

The dotnet CLI is the primary tool for building and running .NET applications on a server. Key commands include:

# Check version and environment
dotnet --version
dotnet --info

# Create a new console application
dotnet new console -n MyApp -o C:ProjectsMyApp

# Restore NuGet packages
dotnet restore C:ProjectsMyAppMyApp.csproj

# Build in Release configuration
dotnet build C:ProjectsMyAppMyApp.csproj -c Release

# Run the application
dotnet run --project C:ProjectsMyAppMyApp.csproj

# Publish a self-contained executable for Windows x64
dotnet publish C:ProjectsMyAppMyApp.csproj 
    -c Release 
    -r win-x64 
    --self-contained true 
    -o C:PublishedMyApp

# Publish as framework-dependent (requires .NET runtime on host)
dotnet publish C:ProjectsMyAppMyApp.csproj 
    -c Release 
    --no-self-contained 
    -o C:PublishedMyApp

NuGet Package Source Configuration

In corporate environments, you may need to configure NuGet to use an internal package feed (such as Azure Artifacts, JFrog Artifactory, or a local ProGet server). The NuGet configuration file is located at %APPDATA%NuGetNuGet.Config per user, or you can place a NuGet.Config file in your project or solution directory for project-level configuration.

# Add a private NuGet feed
dotnet nuget add source "https://pkgs.dev.azure.com/myorg/_packaging/myfeed/nuget/v3/index.json" `
    --name "MyInternalFeed" `
    --username "myuser" `
    --password "myPAT"

# List configured sources
dotnet nuget list source

# Disable nuget.org temporarily
dotnet nuget disable source "nuget.org"

# Clear the local NuGet cache
dotnet nuget locals all --clear

For proxy-aware environments, add the following to NuGet.Config:



  
    
    
    
  
  
    
    
  

Installing .NET on Server Core

Windows Server 2022 Server Core has no GUI, so all .NET installation must be done via PowerShell or the command line. The dotnet-install.ps1 script and MSI installers both work on Server Core. If the server has no internet access, download the offline bundle (the “binaries” zip) from the .NET download page and extract it manually:

# Extract the .NET 8 binary zip to a custom location
Expand-Archive -Path "C:Installersdotnet-sdk-8.0.101-win-x64.zip" -DestinationPath "C:dotnet8"

# Set environment variables
[System.Environment]::SetEnvironmentVariable("DOTNET_ROOT", "C:dotnet8", "Machine")
$path = [System.Environment]::GetEnvironmentVariable("PATH", "Machine")
[System.Environment]::SetEnvironmentVariable("PATH", "$path;C:dotnet8", "Machine")

# Verify
& "C:dotnet8dotnet.exe" --info

For Server Core used as a build agent, it is common to install multiple SDK versions using the dotnet-install script with different -Channel values (6.0, 7.0, 8.0), all targeting the same -InstallDir directory. The shared installation directory means all versions share the same DOTNET_ROOT and PATH entry, and dotnet --list-sdks will show all of them.

Enabling .NET Framework 3.5 (Legacy Applications)

Some older applications require .NET Framework 3.5. Unlike 4.8, this version must be explicitly installed on Windows Server 2022. You can install it from the Windows Server 2022 ISO (as the source) or directly from Windows Update:

# Install from Windows Update (requires internet access)
Install-WindowsFeature Net-Framework-Core

# Install from the WS2022 ISO mounted at D:
Install-WindowsFeature Net-Framework-Core -Source "D:sourcessxs"

# Verify installation
Get-WindowsFeature Net-Framework-Core

This installs both .NET Framework 2.0 SP2 and 3.5 SP1. Applications targeting .NET 2.0, 3.0, or 3.5 will all work once this feature is enabled. Note that enabling this feature alongside .NET Framework 4.8 is fully supported — both versions coexist without conflict.