Windows Server Härtung: CIS Benchmark, Microsoft Security Baseline und Praxis-Guide
Systematic hardening of Windows Server 2019/2022 according to CIS Benchmark Levels 1/2 and the Microsoft Security Baseline: Disable services, disable SMB v1, restrict NTLM, enable LAPS v2 for local administrator passwords, PowerShell hardening, Windows Firewall, audit policies (auditpol), Protected Users security group, Credential Guard, AppLocker, and enforce TLS 1.3. Includes prioritized PowerShell scripts and compliance checks.
Table of Contents (12 sections)
Windows Server is the most frequently targeted operating system in enterprise environments. Default installations contain numerous insecure default configurations that make it easier for attackers to achieve lateral movement and privilege escalation. Unpatched and poorly configured Windows servers are the most common cause of lateral movement in ransomware campaigns. This guide walks you through systematic hardening based on the CIS Benchmark and Microsoft Security Baseline.
Basic Principles and Hardening Priorities
Defense in Depth for Windows Server:
- Principle of Least Necessity: only necessary services, necessary software
- Least Privilege: all accounts with minimal privileges
- Audit: log all critical events
- Segmentation: servers in separate VLANs
- Patching: Apply updates promptly
- Monitoring: EDR + SIEM
CIS Benchmark Levels:
- Level 1: Minimal restrictions, suitable for most environments
- Level 2: Higher security, may limit compatibility
- STIG: U.S. government, very restrictive
Windows Server Hardening Priorities:
Critical (implement immediately):
□ Windows Updates up to date (critical patches within 48 hours)
□ Local administrator disabled or LAPS enabled
□ SMB v1 disabled (EternalBlue/WannaCry!)
□ Restrict NTLM authentication (Pass-the-Hash)
□ Uninstall unnecessary services and roles
□ Windows Defender enabled and up to date
□ Password policies (14+ characters, complexity)
High (within one week):
□ Windows Firewall with Host-Based Rules
□ Fully configure audit logging
□ RDP hardening (NLA, TLS, port)
□ Enable PowerShell logging
□ Enable Credential Guard (Hyper-V required)
□ AppLocker / WDAC (application allowlisting)
Medium (within one month):
□ Fully implement CIS Benchmark
□ Microsoft Security Compliance Toolkit GPOs
□ Protected Users security group
□ Enforce TLS 1.3, disable older versions
□ Enforce SMB signing
Step 1: Windows Security Baseline
# Download and apply the Microsoft Security Baseline
# https://www.microsoft.com/en-us/download/details.aspx?id=55319
# Import the baseline (LGPO.exe required)
Import-Module PolicyFileEditor
# Check local security policies
secedit /export /cfg C:\sec-policy.cfg /areas SECURITYPOLICY
notepad C:\sec-policy.cfg
# Important settings in sec-policy.cfg:
# MinimumPasswordLength = 14
# PasswordComplexity = 1
# MaximumPasswordAge = 90
# LockoutBadCount = 5
# LockoutDuration = 30
# LSAAnonymousNameLookup = 0
Step 2: Disable services and roles (principle of minimalism)
# Uninstall unnecessary features:
Remove-WindowsFeature Telnet-Client # Telnet: always remove!
Remove-WindowsFeature TFTP-Client
Remove-WindowsFeature SNMP-Service # SNMP v1/v2 is insecure
Remove-WindowsFeature Windows-Search
Remove-WindowsFeature Fax
Remove-WindowsFeature XPS-Viewer
Remove-WindowsFeature SMB1Protocol # ALWAYS remove SMB v1!
# Disable dangerous/unnecessary services
$servicesToDisable = @(
"Browser", # Computer Browser (SMB enumeration)
"SSDPSRV", # SSDP Discovery (UPnP vulnerabilities)
"upnphost", # UPnP Device Host
"RemoteRegistry", # Remote Registry (NO remote registry access!)
"Spooler", # Print Spooler (PrintNightmare! - if no printer)
"Fax", # Fax service
"XblAuthManager", # Xbox Live Auth
"WMPNetworkSvc", # Windows Media Player Network
"TapiSrv", # Telephony (unless using VoIP!)
"WinRM" # WinRM - only if PowerShell remoting is not required
)
foreach ($service in $servicesToDisable) {
if (Get-Service -Name $service -ErrorAction SilentlyContinue) {
Set-Service -Name $service -StartupType Disabled
Stop-Service -Name $service -Force -ErrorAction SilentlyContinue
Write-Host "Disabled: $service"
}
}
# ALWAYS disable Print Spooler on DCs (PrintNightmare)
# CVE-2021-1675, CVE-2021-34527 - all Windows versions affected!
Step 3: SMB and Legacy Protocols
# Disable SMBv1 (EternalBlue uses SMBv1!)
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force
Disable-WindowsOptionalFeature -Online -FeatureName "SMB1Protocol" -NoRestart
# Disable SMBv1 client
sc.exe config mrxsmb10 start= disabled
# Enforce SMB signing (prevents NTLM relay attacks!)
Set-SmbServerConfiguration -RequireSecuritySignature $true -Force
Set-SmbClientConfiguration -RequireSecuritySignature $true -Force
# Enable SMB encryption (SMBv3)
Set-SmbServerConfiguration -EncryptData $true -Force
# LAN Manager / NTLM Restrictions
# Network Security: LAN Manager authentication level
# = "Send NTLMv2 response only; refuse LM & NTLM" (Value 5)
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" `
-Name "LmCompatibilityLevel" -Value 5 -Type DWord
# Enable NTLM auditing (before applying the restriction!):
Set-ItemProperty `
-Path "HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" `
-Name "AuditNtlmInDomain" `
-Value 7 # Log all NTLM authentications
# NTLM traffic in EventLog 8004:
Get-WinEvent -LogName "Microsoft-Windows-NTLM/Operational" |
Where-Object {$_.Id -eq 8004} |
Select-Object TimeCreated, Message
Step 4: PowerShell Hardening
# PowerShell Constrained Language Mode
# Prevents: System.Reflection, Add-Type, .NET Interop
[System.Environment]::SetEnvironmentVariable("__PSLockdownPolicy", "4", "Machine")
# Enable PowerShell Script Block Logging (Audit)
$regPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging"
New-Item -Path $regPath -Force
Set-ItemProperty -Path $regPath -Name "EnableScriptBlockLogging" -Value 1
# Module Logging
$regPath2 = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging"
New-Item -Path $regPath2 -Force
Set-ItemProperty -Path $regPath2 -Name "EnableModuleLogging" -Value 1
Set-ItemProperty -Path $regPath2 -Name "ModuleNames" -Value @("*") -Type MultiString
# Disable PowerShell v2 (bypasses logging!)
Disable-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2Root -NoRestart
# Enable transcription (log all PowerShell output)
$regPath3 = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription"
New-Item -Path $regPath3 -Force
Set-ItemProperty -Path $regPath3 -Name "EnableTranscripting" -Value 1
Set-ItemProperty -Path $regPath3 -Name "OutputDirectory" -Value "C:\PowerShellLogs"
Step 5: Audit Policies (SIEM Foundation)
# Enable all relevant categories
auditpol /set /subcategory:"Logon" /success:enable /failure:enable
auditpol /set /subcategory:"Account Lockout" /success:enable /failure:enable
auditpol /set /subcategory:"Logoff" /success:enable
auditpol /set /subcategory:"Process Creation" /success:enable /failure:enable
auditpol /set /subcategory:"Process Termination" /success:enable
auditpol /set /subcategory:"Security Group Management" /success:enable /failure:enable
auditpol /set /subcategory:"User Account Management" /success:enable /failure:enable
auditpol /set /subcategory:"Sensitive Privilege Use" /success:enable /failure:enable
auditpol /set /subcategory:"Object Access" /success:enable /failure:enable
auditpol /set /subcategory:"Special Logon" /success:enable
auditpol /set /subcategory:"Kerberos Authentication Service" /success:enable /failure:enable
auditpol /set /subcategory:"Credential Validation" /success:enable /failure:enable
Important Event IDs for SIEM:
4624: Successful logon (Type 3=Network, Type 10=Remote, Type 4=Batch)
4625: Failed logon (Brute Force!)
4648: Logon with explicit credentials (Pass-the-Hash indicator)
4672: Admin logon (Special Privileges)
4688: Process created (Command Execution Logging)
4698: Scheduled Task created (Persistence!)
4720: User account created (Backdoor User!)
4728/4732: Member added to group (Admin groups!)
4768: Kerberos TGT requested
4769: Kerberos Service Ticket requested
4771: Kerberos pre-authentication failed (AS-REP Roasting)
4776: NTLM authentication (Pass-the-Hash Detection)
7045: New service installed (Malware!)
4103/4104: PowerShell Module/Script Block Logging
Step 6: Configure Windows Firewall
# Enable Windows Defender Firewall (all profiles)
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled True
# Default Policy: DENY ALL → explicitly ALLOW
Set-NetFirewallProfile -Profile Domain,Public,Private `
-DefaultInboundAction Block -DefaultOutboundAction Allow `
-NotifyOnListen True -AllowLocalFirewallRules False `
-AllowLocalIPsecRules False
# Required inbound rules (Example Member Server)
New-NetFirewallRule -DisplayName "RDP (TCP)" -Direction Inbound `
-Protocol TCP -LocalPort 3389 -Action Allow -RemoteAddress "10.10.10.0/24"
# Only from Admin VLAN!
New-NetFirewallRule -DisplayName "WinRM HTTPS (TCP)" -Direction Inbound `
-Protocol TCP -LocalPort 5986 -Action Allow -RemoteAddress "10.10.10.0/24"
# Only from the management VLAN!
# Block all unused services
New-NetFirewallRule -DisplayName "Block SMB Inbound" -Direction Inbound `
-Protocol TCP -LocalPort 445 -Action Block
# Restrict outbound connections (Egress Filtering)
New-NetFirewallRule -DisplayName "Block Telnet" -Direction Outbound `
-Protocol TCP -RemotePort 23 -Action Block
New-NetFirewallRule -DisplayName "Block Tor Ports" -Direction Outbound `
-Protocol TCP -RemotePort 9050,9001 -Action Block
Step 7: Protected Users and Credential Guard
# Protected Users group (prevents NTLM, delegation, etc.)
# Recommended for all privileged accounts!
Add-ADGroupMember -Identity "Protected Users" -Members "DomainAdmin1","DomainAdmin2"
# Protected Users automatically prevents:
# → NTLM authentication
# → DES or RC4 Kerberos encryption
# → Unconstrained delegation
# → Credential caching (no NTLM hash on disk)
# → TGT valid for only 4 hours (instead of 10 hours)
# Note: Service accounts that require NTLM should NOT be added to Protected Users!
# Enable Credential Guard (Hyper-V isolation for LSASS)
# Prevents LSASS dumping / Mimikatz
# Prerequisites: UEFI, Secure Boot, Hyper-V
$path = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard"
Set-ItemProperty -Path $path -Name "EnableVirtualizationBasedSecurity" -Value 1
Set-ItemProperty -Path $path -Name "RequirePlatformSecurityFeatures" -Value 1
Set-ItemProperty -Path $path -Name "LsaCfgFlags" -Value 1 # Credential Guard
# Check Credential Guard status
$devGuard = Get-CimInstance -ClassName Win32_DeviceGuard `
-Namespace root\Microsoft\Windows\DeviceGuard
$devGuard.SecurityServicesRunning
# 1 = Credential Guard enabled
Step 8: LAPS v2 (Local Administrator Password Solution)
# LAPS v2 (integrated in Windows Server 2019/2022)
# Problem without LAPS: all machines in the domain have the same local admin and the same password!
# Pass-the-Hash: one system compromised → all others too!
# Extend the LAPS schema for AD
Update-LapsADSchema
# Set LAPS permissions (IT admins can read passwords)
Set-LapsADComputerSelfPermission -Identity "OU=Servers,DC=company,DC=de"
Set-LapsADReadPasswordPermission -Identity "OU=Servers,DC=company,DC=de" `
-AllowedPrincipals "COMPANY\IT-Admins"
# GPO: Enable LAPS
# Computer Configuration → Administrative Templates → System → LAPS
# "Configure password backup directory" = Active Directory
# "Password complexity requirements" = Uppercase letters + Lowercase letters + Numbers + Special characters
# "Password length" = 16 (minimum!)
# "Password age (days)" = 30
# Retrieve LAPS password (in an emergency)
Get-LapsADPassword -Identity "SERVER01" -AsPlainText
# Force rotation
Reset-LapsPassword -Identity "SERVER01"
# Rename local administrator (hides default account name):
Rename-LocalUser -Name "Administrator" -NewName "adm-srv-01"
# Disable if LAPS is active:
Disable-LocalUser -Name "Administrator"
TLS and Cryptography
# Disable insecure protocols:
# Disable SSL 2.0:
New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server"
Set-ItemProperty -Path "HKLM:\...\SSL 2.0\Server" -Name "Enabled" -Value 0
# Disable SSL 3.0:
New-Item -Path "HKLM:\...\SSL 3.0\Server"
Set-ItemProperty -Path "HKLM:\...\SSL 3.0\Server" -Name "Enabled" -Value 0
# Disable TLS 1.0 (Caution: older applications!):
New-Item -Path "HKLM:\...\TLS 1.0\Server"
Set-ItemProperty -Path "HKLM:\...\TLS 1.0\Server" -Name "Enabled" -Value 0
# Disable TLS 1.1:
New-Item -Path "HKLM:\...\TLS 1.1\Server"
Set-ItemProperty -Path "HKLM:\...\TLS 1.1\Server" -Name "Enabled" -Value 0
# TLS 1.2 and 1.3: ENABLED
New-Item -Path "HKLM:\...\TLS 1.2\Server"
Set-ItemProperty -Path "HKLM:\...\TLS 1.2\Server" -Name "Enabled" -Value 1
New-Item -Path "HKLM:\...\TLS 1.3\Server"
Set-ItemProperty -Path "HKLM:\...\TLS 1.3\Server" -Name "Enabled" -Value 1
# Tool: IISCrypto (GUI alternative, simpler):
# nartac.com/Products/IISCrypto → "Best Practices" template
# RC4, DES, 3DES: explicitly DISABLE
Disable-TlsCipherSuite -Name "TLS_RSA_WITH_RC4_128_SHA"
Disable-TlsCipherSuite -Name "TLS_RSA_WITH_3DES_EDE_CBC_SHA"
Check CIS Benchmark Compliance
# Manual checks (most important CIS L1 checks):
$checks = @(
@{Name="SMBv1 disabled"; Test={
-not (Get-SmbServerConfiguration).EnableSMB1Protocol
}},
@{Name="NTLMv2 only (LAN Man Level = 5)"; Test={
(Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa").LmCompatibilityLevel -eq 5
}},
@{Name="Print Spooler disabled"; Test={
(Get-Service Spooler).Status -eq "Stopped"
}},
@{Name="Guest Account disabled"; Test={
(Get-LocalUser -Name "Guest").Enabled -eq $false
}},
@{Name="Remote Registry disabled"; Test={
(Get-Service RemoteRegistry).StartType -eq "Disabled"
}}
)
foreach ($check in $checks) {
$result = & $check.Test
$status = if ($result) {"PASS"} else {"FAIL"}
Write-Host "$status | $($check.Name)"
}
Typical Hardening Sequence
Priority 1 - Immediately (prevents most common attacks):
✓ Disable SMBv1
✓ Disable Print Spooler on DCs
✓ Set NTLM Level to 5
✓ Enable Local Admin Password (LAPS)
✓ Enable audit policies
Priority 2 - Within 1 week:
✓ Enable Credential Guard
✓ Protected Users for admins
✓ Enable PowerShell logging
✓ Disable unnecessary services
✓ Configure Windows Firewall
Priority 3 - Within 1 month:
✓ Fully implement CIS Benchmark
✓ Configure AppLocker / WDAC
✓ JEA (Just Enough Administration) for remote management
✓ Implement Privileged Access Workstations (PAW)
✓ SIEM integration for critical events
✓ Disable TLS 1.0/1.1
✓ Enforce SMB signing Sources & References
- [1] CIS Microsoft Windows Server 2022 Benchmark - CIS
- [2] BSI SiSyPHuS: Sicherheitsstudie zum Windows 10 Betriebssystem - BSI
- [3] Microsoft Security Baseline - Microsoft
Questions about this topic?
Our experts advise you free of charge and without obligation.
About the Author
Geschäftsführender Gesellschafter der AWARE7 GmbH mit langjähriger Expertise in Informationssicherheit, Penetrationstesting und IT-Risikomanagement. Absolvent des Masterstudiengangs Internet-Sicherheit an der Westfälischen Hochschule (if(is), Prof. Norbert Pohlmann). Bestseller-Autor im Wiley-VCH Verlag und Lehrbeauftragter der ASW-Akademie. Einschätzungen zu Cybersecurity und digitaler Souveränität erschienen u.a. in Welt am Sonntag, WDR, Deutschlandfunk und Handelsblatt.
10 Publikationen
- Einsatz von elektronischer Verschlüsselung - Hemmnisse für die Wirtschaft (2018)
- Kompass IT-Verschlüsselung - Orientierungshilfen für KMU (2018)
- IT Security Day 2025 - Live Hacking: KI in der Cybersicherheit (2025)
- Live Hacking - Credential Stuffing: Finanzrisiken jenseits Ransomware (2025)
- Keynote: Live Hacking Show - Ein Blick in die Welt der Cyberkriminalität (2025)
- Analyse von Angriffsflächen bei Shared-Hosting-Anbietern (2024)
- Gänsehaut garantiert: Die schaurigsten Funde aus dem Leben eines Pentesters (2022)
- IT Security Zertifizierungen — CISSP, T.I.S.P. & Co (Live-Webinar) (2023)
- Sicherheitsforum Online-Banking — Live Hacking (2021)
- Nipster im Netz und das Ende der Kreidezeit (2017)