WINDOWS SERVER 2022 — SECURITY HARDENING LAYERS Network Layer — Firewall & TLS 1.3 OS Layer — Defender, Audit Policies, Group Policy Windows Update Auto patching WSUS / SCCM Critical + Security Account Security Rename Admin Password policy Lockout policy Defender + AV Real-time scan Cloud protection Tamper protection Audit & Logging Logon events Privilege use Policy changes Secured-core Server ⟶ Hardware Root of Trust ⟶ UEFI Secure Boot ⟶ VBS Defense in depth: every layer reduces the attack surface

A freshly installed Windows Server 2022 is not secure by default. Before connecting it to your network and deploying workloads, you need to configure networking, apply patches, harden the operating system, and enable proper auditing. Skipping these steps leaves your server vulnerable to lateral movement, privilege escalation, and data exfiltration. This guide walks you through the complete initial setup and security hardening process, following CIS Benchmark recommendations and Microsoft best practices.

Prerequisites

Before you begin, make sure you have:

  • Windows Server 2022 installed (Standard or Datacenter edition)
  • Administrator access to the server (local or via RDP)
  • Network information: static IP address, subnet mask, default gateway, and DNS server addresses
  • Internet connectivity for downloading updates and Defender definitions
  • A backup plan — take a snapshot or checkpoint before making system-level changes

Tip: Prefer Server Core installation for production servers. It has a smaller attack surface, fewer updates, and less resource consumption compared to Desktop Experience.

Step 1: Configure Networking and Hostname

The first task on any new server is setting a proper hostname and static network configuration.

Rename the Server

# Check current name
hostname

# Rename and schedule a reboot
Rename-Computer -NewName "SRV-PROD-01" -Restart

Configure Static IP Address

# List network adapters
Get-NetAdapter

# Remove existing DHCP configuration
Remove-NetIPAddress -InterfaceAlias "Ethernet0" -Confirm:$false
Remove-NetRoute -InterfaceAlias "Ethernet0" -Confirm:$false

# Set static IP
New-NetIPAddress -InterfaceAlias "Ethernet0" `
  -IPAddress "10.0.1.20" `
  -PrefixLength 24 `
  -DefaultGateway "10.0.1.1"

# Set DNS servers
Set-DnsClientServerAddress -InterfaceAlias "Ethernet0" `
  -ServerAddresses "10.0.1.5", "10.0.1.6"

Configure the Time Zone

# List available time zones
Get-TimeZone -ListAvailable | Where-Object { $_.Id -like "*Eastern*" }

# Set time zone
Set-TimeZone -Id "Eastern Standard Time"

# Configure NTP source
w32tm /config /manualpeerlist:"time.windows.com" /syncfromflags:manual /reliable:YES /update
Restart-Service w32time
w32tm /resync /force

Step 2: Configure Windows Update

Keeping the server patched is the single most effective security measure you can take.

Install the PSWindowsUpdate Module

# Install NuGet provider if needed
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force

# Install PSWindowsUpdate module
Install-Module -Name PSWindowsUpdate -Force -Confirm:$false

# Import the module
Import-Module PSWindowsUpdate

Check and Install Updates

# List available updates
Get-WindowsUpdate

# Install all available updates
Install-WindowsUpdate -AcceptAll -AutoReboot

# Check update history
Get-WUHistory | Select-Object -First 20 | Format-Table Date, Title, Result

Configure Automatic Updates via Registry

# Configure Windows Update for auto-download, notify before install
$WUPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU"
New-Item -Path $WUPath -Force | Out-Null

Set-ItemProperty -Path $WUPath -Name "NoAutoUpdate" -Value 0
Set-ItemProperty -Path $WUPath -Name "AUOptions" -Value 3  # Auto download, notify install
Set-ItemProperty -Path $WUPath -Name "ScheduledInstallDay" -Value 1  # Every Sunday
Set-ItemProperty -Path $WUPath -Name "ScheduledInstallTime" -Value 3  # 3 AM

Step 3: Enable and Configure Windows Defender

Windows Server 2022 includes Windows Defender Antivirus. On Server Core, it runs without a GUI but is fully functional via PowerShell.

Verify Defender Status

# Check Defender status
Get-MpComputerStatus | Select-Object AntivirusEnabled, RealTimeProtectionEnabled,
  IoavProtectionEnabled, AntispywareEnabled, AntivirusSignatureLastUpdated

# Update definitions
Update-MpSignature

Configure Real-Time Protection

# Enable all protection features
Set-MpPreference -DisableRealtimeMonitoring $false
Set-MpPreference -MAPSReporting Advanced
Set-MpPreference -SubmitSamplesConsent SendAllSamples
Set-MpPreference -DisableBlockAtFirstSeen $false

# Enable network protection
Set-MpPreference -EnableNetworkProtection Enabled

# Enable controlled folder access (ransomware protection)
Set-MpPreference -EnableControlledFolderAccess Enabled

Configure Exclusions for Application Paths

# Add exclusions for known application paths (adjust for your environment)
Add-MpPreference -ExclusionPath "D:\SQLData"
Add-MpPreference -ExclusionPath "D:\SQLLogs"
Add-MpPreference -ExclusionProcess "sqlservr.exe"

# Verify exclusions
Get-MpPreference | Select-Object -ExpandProperty ExclusionPath

Warning: Only add exclusions for trusted application paths. Each exclusion creates a blind spot for the antivirus engine. Never exclude temp directories or user-writable paths.

Step 4: Configure Windows Firewall

The Windows Firewall should be enabled on all profiles. The principle is simple: block everything inbound by default, then allow only the ports your services require.

Enable All Firewall Profiles

# Enable firewall on all profiles
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled True

# Set default actions: block inbound, allow outbound
Set-NetFirewallProfile -Profile Domain,Public,Private `
  -DefaultInboundAction Block `
  -DefaultOutboundAction Allow

# Enable firewall logging
Set-NetFirewallProfile -Profile Domain,Public,Private `
  -LogAllowed True `
  -LogBlocked True `
  -LogFileName "%systemroot%\system32\LogFiles\Firewall\pfirewall.log" `
  -LogMaxSizeKilobytes 16384

Create Specific Allow Rules

# Allow RDP only from management subnet
New-NetFirewallRule -DisplayName "RDP - Management Only" `
  -Direction Inbound -Protocol TCP -LocalPort 3389 `
  -RemoteAddress "10.0.100.0/24" -Action Allow

# Allow WinRM (for remote management)
New-NetFirewallRule -DisplayName "WinRM HTTPS" `
  -Direction Inbound -Protocol TCP -LocalPort 5986 `
  -RemoteAddress "10.0.100.0/24" -Action Allow

# Allow ICMP (ping) from internal network
New-NetFirewallRule -DisplayName "ICMP Allow Internal" `
  -Direction Inbound -Protocol ICMPv4 `
  -RemoteAddress "10.0.0.0/8" -Action Allow

Review and Clean Up Default Rules

# List all enabled inbound rules
Get-NetFirewallRule -Direction Inbound -Enabled True |
  Format-Table DisplayName, Profile, Action

# Disable rules you don't need (example: disable built-in file sharing)
Disable-NetFirewallRule -DisplayGroup "File and Printer Sharing"

Step 5: Disable Legacy Protocols and Enforce TLS 1.3

Windows Server 2022 is the first Windows Server release with native TLS 1.3 support. You should disable all older protocol versions.

Disable SSL 2.0, SSL 3.0, TLS 1.0, and TLS 1.1

# Function to disable a protocol
function Disable-Protocol {
    param([string]$Protocol)
    $basePath = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\$Protocol"

    foreach ($side in @("Server", "Client")) {
        $path = "$basePath\$side"
        New-Item -Path $path -Force | Out-Null
        Set-ItemProperty -Path $path -Name "Enabled" -Value 0 -Type DWord
        Set-ItemProperty -Path $path -Name "DisabledByDefault" -Value 1 -Type DWord
    }
    Write-Host "Disabled $Protocol" -ForegroundColor Yellow
}

# Disable legacy protocols
Disable-Protocol -Protocol "SSL 2.0"
Disable-Protocol -Protocol "SSL 3.0"
Disable-Protocol -Protocol "TLS 1.0"
Disable-Protocol -Protocol "TLS 1.1"

Verify TLS 1.3 Is Enabled

# Check TLS 1.3 registry (enabled by default on Server 2022)
$tls13Path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Server"
if (Test-Path $tls13Path) {
    Get-ItemProperty -Path $tls13Path
} else {
    Write-Host "TLS 1.3 is using default settings (enabled)" -ForegroundColor Green
}

Disable Weak Cipher Suites

# Disable weak ciphers
$weakCiphers = @("RC4 128/128", "RC4 64/128", "RC4 56/128", "DES 56/56", "Triple DES 168")
foreach ($cipher in $weakCiphers) {
    $path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\$cipher"
    New-Item -Path $path -Force | Out-Null
    Set-ItemProperty -Path $path -Name "Enabled" -Value 0 -Type DWord
}

# Set strong cipher suite order
$cipherOrder = @(
    "TLS_AES_256_GCM_SHA384",
    "TLS_AES_128_GCM_SHA256",
    "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
    "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
    "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
    "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
) -join ","

Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Cryptography\Configuration\SSL\00010002" `
  -Name "Functions" -Value $cipherOrder

Step 6: Account Security and Password Policies

Rename the Built-in Administrator Account

# Rename the default Administrator account (CIS recommendation)
Rename-LocalUser -Name "Administrator" -NewName "SrvLocalAdmin"

# Disable the Guest account
Disable-LocalUser -Name "Guest"

Configure Password and Lockout Policies

# Set password policy via net accounts
net accounts /minpwlen:14 /maxpwage:60 /minpwage:1 /uniquepw:24

# Set account lockout policy
net accounts /lockoutthreshold:5 /lockoutduration:30 /lockoutwindow:30

Restrict Remote Desktop Access

# Only allow specific group for RDP access
$rdpGroup = "Remote Desktop Users"
Remove-LocalGroupMember -Group $rdpGroup -Member "Everyone" -ErrorAction SilentlyContinue

# Add only authorized users
Add-LocalGroupMember -Group $rdpGroup -Member "DOMAIN\RDP-Admins"

# Enable NLA (Network Level Authentication) for RDP
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" `
  -Name "UserAuthentication" -Value 1

Step 7: Configure Audit Policies and Logging

Proper auditing is essential for detecting intrusions and satisfying compliance requirements.

Enable Advanced Audit Policies

# Account Logon events
auditpol /set /subcategory:"Credential Validation" /success:enable /failure:enable
auditpol /set /subcategory:"Kerberos Authentication Service" /success:enable /failure:enable

# Logon/Logoff events
auditpol /set /subcategory:"Logon" /success:enable /failure:enable
auditpol /set /subcategory:"Logoff" /success:enable
auditpol /set /subcategory:"Special Logon" /success:enable

# Object Access
auditpol /set /subcategory:"File System" /success:enable /failure:enable
auditpol /set /subcategory:"Registry" /success:enable /failure:enable

# Policy Changes
auditpol /set /subcategory:"Audit Policy Change" /success:enable /failure:enable
auditpol /set /subcategory:"Authentication Policy Change" /success:enable

# Privilege Use
auditpol /set /subcategory:"Sensitive Privilege Use" /success:enable /failure:enable

# System events
auditpol /set /subcategory:"Security State Change" /success:enable /failure:enable
auditpol /set /subcategory:"Security System Extension" /success:enable /failure:enable

Configure Event Log Sizes

# Increase Security log to 1 GB
wevtutil sl Security /ms:1073741824

# Increase System log to 256 MB
wevtutil sl System /ms:268435456

# Increase Application log to 256 MB
wevtutil sl Application /ms:268435456

# Set retention to auto-archive
wevtutil sl Security /rt:false /ab:true

Verify Audit Configuration

# Display all audit policies
auditpol /get /category:*

# Check recent security events
Get-WinEvent -LogName Security -MaxEvents 10 |
  Format-Table TimeCreated, Id, Message -Wrap

Step 8: Disable Unnecessary Services

Reducing the number of running services shrinks the attack surface.

# Services commonly disabled on hardened servers
$servicesToDisable = @(
    "XblAuthManager",      # Xbox Live Auth Manager
    "XblGameSave",         # Xbox Live Game Save
    "WSearch",             # Windows Search (unless needed)
    "MapsBroker",          # Downloaded Maps Manager
    "lfsvc",               # Geolocation Service
    "SharedAccess",        # Internet Connection Sharing
    "WMPNetworkSvc",       # Windows Media Player Network Sharing
    "Browser"              # Computer Browser
)

foreach ($svc in $servicesToDisable) {
    $service = Get-Service -Name $svc -ErrorAction SilentlyContinue
    if ($service) {
        Stop-Service -Name $svc -Force -ErrorAction SilentlyContinue
        Set-Service -Name $svc -StartupType Disabled
        Write-Host "Disabled: $svc" -ForegroundColor Yellow
    }
}

Step 9: Additional CIS Benchmark Hardening

Disable SMBv1

# Disable SMBv1 (critical — used by WannaCry and similar malware)
Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol -NoRestart
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force

Enable Credential Guard

# Enable Virtualization-Based Security and Credential Guard
$regPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard"
Set-ItemProperty -Path $regPath -Name "EnableVirtualizationBasedSecurity" -Value 1
Set-ItemProperty -Path $regPath -Name "RequirePlatformSecurityFeatures" -Value 3

$credGuardPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"
Set-ItemProperty -Path $credGuardPath -Name "LsaCfgFlags" -Value 1

Restrict PowerShell Execution

# Enable PowerShell script block logging
$psLogPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging"
New-Item -Path $psLogPath -Force | Out-Null
Set-ItemProperty -Path $psLogPath -Name "EnableScriptBlockLogging" -Value 1

# Enable PowerShell module logging
$psModLogPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging"
New-Item -Path $psModLogPath -Force | Out-Null
Set-ItemProperty -Path $psModLogPath -Name "EnableModuleLogging" -Value 1

# Set execution policy to RemoteSigned
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine -Force

Disable Anonymous Access

# Restrict anonymous enumeration of SAM accounts and shares
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" `
  -Name "RestrictAnonymousSAM" -Value 1
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" `
  -Name "RestrictAnonymous" -Value 1

# Disable null session pipes
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" `
  -Name "NullSessionPipes" -Value @() -Type MultiString

Troubleshooting

Common Issues After Hardening

Locked out after renaming Administrator: If you lose access after renaming the built-in Administrator account, boot into Safe Mode or use a Windows Recovery Environment. The renamed account still has the same SID and permissions.

RDP stops working after firewall changes: Always create your RDP allow rule before setting the default inbound action to Block. If locked out, use the server console (iLO, iDRAC, VMware Console) to fix the firewall:

# Emergency: temporarily disable firewall via console
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False
# Fix your rules, then re-enable

Applications break after TLS hardening: Some legacy applications require TLS 1.0/1.1. Test thoroughly in a staging environment before deploying. If needed, you can selectively re-enable a protocol for a specific application rather than system-wide.

Event log flooding after enabling audits: If your Security event log fills up quickly, review which subcategories generate the most events. File System auditing on busy file servers can generate enormous volumes. Consider using a SIEM to collect logs remotely with appropriate filtering.

Verification Checklist

Run this script to verify your hardening configuration:

Write-Host "=== Security Hardening Verification ===" -ForegroundColor Cyan

# Check hostname
Write-Host "`nHostname: $(hostname)"

# Check firewall status
Get-NetFirewallProfile | Format-Table Name, Enabled, DefaultInboundAction

# Check Defender status
$defender = Get-MpComputerStatus
Write-Host "Defender Real-Time Protection: $($defender.RealTimeProtectionEnabled)"
Write-Host "Defender Signatures Updated: $($defender.AntivirusSignatureLastUpdated)"

# Check SMBv1
$smb1 = Get-SmbServerConfiguration | Select-Object -ExpandProperty EnableSMB1Protocol
Write-Host "SMBv1 Disabled: $(-not $smb1)"

# Check audit policies
Write-Host "`nAudit Policies:"
auditpol /get /category:"Logon/Logoff"

# Check disabled legacy protocols
$protocols = @("SSL 2.0", "SSL 3.0", "TLS 1.0", "TLS 1.1")
foreach ($proto in $protocols) {
    $path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\$proto\Server"
    if (Test-Path $path) {
        $enabled = (Get-ItemProperty -Path $path).Enabled
        Write-Host "$proto Disabled: $($enabled -eq 0)"
    }
}

Summary

Hardening Windows Server 2022 is not a one-time activity but a foundational practice that must happen before deploying any workload. In this guide, you configured static networking, applied Windows Updates, enabled and tuned Windows Defender, locked down the firewall to allow only necessary traffic, disabled legacy TLS/SSL protocols in favor of TLS 1.3, hardened account policies, and enabled comprehensive auditing. These steps align with CIS Benchmark Level 1 recommendations and significantly reduce your server’s attack surface. From here, continue with role-specific hardening (IIS, SQL Server, Active Directory) and integrate your event logs into a centralized SIEM for ongoing monitoring.