article
Windows Server Hardening Checklist: 40 Controls for 2026 (CIS-Aligned)

Windows Server hardening is the process of reducing a server's attack surface to what the workload actually needs: fewer accounts, fewer open ports, fewer running services, stronger authentication, and enough logging to reconstruct what happened when something goes wrong. This checklist is the one we apply to Windows Server 2019, 2022 and 2025 hosts under management, organised so you can work through it in an afternoon and re-check it every quarter.
It follows the CIS Microsoft Windows Server Benchmark and Microsoft's security baselines but stays practical: each control says what to do, why, and how to verify it. Where a control routinely breaks applications, it says so.
Before you start
- Take a snapshot or a full backup. Several controls below change authentication behaviour. Have a way back.
- Inventory the server's role. Domain controller, file server, IIS host, SQL host, RDS host and jump box each need different exceptions. Hardening a server you do not understand is how you cause an outage.
- Use Group Policy or DSC, not manual clicks. A control applied by hand is a control that drifts. Put the settings in a GPO linked to an OU, or in a Desired State Configuration or Ansible
win_*role, and let the baseline enforce itself. - Work on a test server first. Then a canary in production. Then the fleet.
1. Accounts and authentication
- Rename or disable the built-in Administrator account and create named admin accounts.
Get-LocalUser Administrator | Select Enabled - Disable the Guest account.
Get-LocalUser Guest | Select Enabledshould returnFalse. - Enforce password policy: minimum 14 characters, history 24, maximum age 365 days or fewer, complexity on. Check with
net accountsorGet-ADDefaultDomainPasswordPolicy. - Account lockout: threshold 5 to 10, duration 15 minutes, reset counter 15 minutes.
- Use LAPS (Windows LAPS) so every server has a unique, rotated local admin password. Verify the
msLAPS-Passwordattribute is populated in AD. - Remove stale local accounts and groups.
Get-LocalUser | Where-Object { $_.LastLogon -lt (Get-Date).AddDays(-90) } - Restrict Administrators group membership to named accounts and a break-glass account. Review quarterly:
Get-LocalGroupMember Administrators. - Require MFA for RDP and admin sessions via Azure AD/Entra conditional access, an RD Gateway with MFA, or a privileged access workstation. Local password alone is not enough for an internet-adjacent server.
- Disable NTLM where possible and enforce NTLMv2 only (
LmCompatibilityLevel = 5). Audit first with the NTLM auditing GPO; legacy apps will break. - Enable Credential Guard on 2019 and later where the hardware supports it, to protect LSASS secrets.
2. Network and remote access
- Windows Defender Firewall on for all three profiles, inbound default block.
Get-NetFirewallProfile | Select Name, Enabled, DefaultInboundAction - Only the ports the role needs. Export the rule set and remove "Allow all" rules left by installers.
Get-NetFirewallRule -Enabled True -Direction Inbound | Where Action -eq Allow - Do not expose RDP (3389) to the internet. Reach it through a VPN, RD Gateway, Azure Bastion or an identity-aware proxy. If it must be reachable, change the port only as a noise reducer, never as the control.
- Require Network Level Authentication for RDP and TLS 1.2 or higher for the RDP listener.
- Disable SMBv1.
Get-WindowsOptionalFeature -Online -FeatureName SMB1Protocolshould beDisabled. Require SMB signing on file servers and domain controllers. - Disable LLMNR and NetBIOS over TCP/IP to stop credential-relay attacks on the LAN.
- Disable WinRM over HTTP from untrusted networks; allow WinRM over HTTPS with certificate validation from management subnets only.
- Disable IPv6 only if you have actually decided not to use it. Otherwise, firewall it like IPv4. Leaving it on and unmanaged is the common mistake.
- Disable unused network adapters and protocols (Link-Layer Topology Discovery, QoS Packet Scheduler on servers that do not need it).
3. Services, roles and features
- Remove roles and features the server does not use.
Get-WindowsFeature | Where Installed. Print Spooler on anything that is not a print server is the classic one; disable it. - Disable or set to Manual the services a role does not need: Xbox services, Windows Search on non-file servers, Remote Registry, Fax, Telnet, TFTP, SNMP unless it is monitored and community strings are non-default.
- Run application services under managed service accounts (gMSA) rather than domain user accounts with passwords that never rotate.
- Uninstall unused software including old runtimes, vendor bloatware and trial products left by imaging.
- Turn off Server Manager and Internet Explorer Enhanced Security auto-launch for admins who use the console, but keep IE ESC on; better still, do not browse from servers.
4. Patching and software supply
- Patch monthly, with emergency windows for CISA KEV entries. Verify with
Get-HotFix | Sort InstalledOn -Descending | Select -First 5and compare with the latest cumulative update. - Use WSUS, Intune or Azure Update Manager with rings, and take a snapshot before each cycle. Never "Install updates and shut down" on a production server without a rollback path.
- Keep .NET, PowerShell, SQL Server, IIS modules and third-party agents patched too. Windows Update does not cover them all.
- Enable Windows Defender Application Control or AppLocker in audit mode first, then enforce for servers with a fixed application set. This stops most commodity malware outright.
5. Logging, auditing and detection
- Apply the Microsoft security baseline advanced audit policy: logon events, account management, policy change, privilege use, process creation with command line.
auditpol /get /category:* - Increase event log sizes (Security to at least 1 GB) so logs survive long enough to be shipped.
- Ship logs off-box to a SIEM, Wazuh, Sentinel or your NOC's collector. Logs that only exist on the compromised server are not evidence.
- Enable PowerShell script block and module logging and Transcription. Attackers live in PowerShell; you should be able to read what they typed.
- Enable Sysmon with a maintained configuration (SwiftOnSecurity or Olaf Hartong) for process, network and file telemetry.
- Microsoft Defender Antivirus on with cloud protection, tamper protection enabled, and exclusions reviewed quarterly. If a third-party EDR is used, make sure Defender is in passive mode rather than fighting it.
- Enable Attack Surface Reduction rules at minimum for Office child processes, credential theft from LSASS, and executable content from email; audit mode first on application servers.
6. System configuration
- Enable BitLocker on data volumes for physical servers and on any server that could be physically removed. Store recovery keys in AD or Azure AD.
- Set User Account Control to always notify for administrators on servers; the prompt is annoying and that is the point.
- Disable autorun and autoplay, and disable the Windows Installer "Always install with elevated privileges" policy.
- Configure the screen lock at 15 minutes for console and RDP sessions and set RDP idle-session limits.
- Time synchronisation: point domain members at the PDC emulator and the PDC at a reliable NTP source. Log correlation and Kerberos both depend on it.
Verifying the baseline
Run the free Microsoft Security Compliance Toolkit Policy Analyzer against the Windows Server baseline, or the CIS-CAT Lite assessor against the CIS Benchmark, and keep the report. Both produce a scored gap list you can re-run each quarter. For continuous checking, Ansible win_* modules or DSC will re-assert the controls on a schedule and alert on drift through your monitoring.
A hardened server that is not monitored is only hardened until someone changes it. Wire the audit policy into your SIEM, alert on membership changes to Administrators, and treat a disabled firewall profile as a P2.
What routinely breaks, and what to do about it
- Legacy applications that need NTLMv1 or SMBv1. Isolate them on a separate VLAN with a documented risk acceptance and a retirement date, rather than weakening the whole estate.
- Printers and scanners after Print Spooler is disabled. Use a dedicated print server; do not re-enable the spooler on domain controllers.
- Backup agents and monitoring tools after AppLocker enforcement. Sign or path-allow them explicitly during the audit phase.
- Scheduled tasks running as domain users after password policy changes. Move them to gMSAs.
- Remote management from outside the management subnet after WinRM restrictions. That is the control working; use the jump host.
Hardening is a schedule, not a project
The controls above are the same ones an auditor will ask about for ISO 27001 A.8, PCI DSS requirement 2 and SOC 2 CC6. The difference between a server that passes and one that does not is usually not the initial hardening but whether anyone re-checked it after the last emergency change.
If you would rather have this done and kept done, our server maintenance and management service applies this baseline with Group Policy and Ansible, monitors for drift through the NOC, and reports on it monthly. Mixed estates are common; the Linux managed services team works the same way with CIS Linux benchmarks.
Work with Techtweek
DevOps, cloud & compliance. CERT-In empanelled, AWS Advanced Partner.
Book a consultation