Hardening Windows 11: Essential Security Configuration Guide
Complete guide to hardening Windows 11 with GPOs, ASR rules, PowerShell scripts, and security best practices for enterprise and home users.
TL;DR
Summary not available.
TL;DR
This guide provides a comprehensive approach to hardening Windows 11 systems using Group Policy Objects (GPOs), Attack Surface Reduction (ASR) rules, and PowerShell automation. We'll cover essential security configurations that can reduce attack vectors by up to 80% when properly implemented.
Introduction
Windows 11 introduced several security improvements over its predecessors, but out-of-the-box configurations often prioritize usability over security. This guide will walk you through essential hardening steps that every system administrator should implement, whether managing enterprise environments or securing personal systems.
Always test these configurations in a non-production environment first. Some settings may impact user experience or application functionality.
Security Baseline Overview
Before diving into specific configurations, let's establish our security baseline priorities:
- Principle of Least Privilege: Users and processes should have minimal necessary permissions
- Defense in Depth: Multiple layers of security controls
- Attack Surface Reduction: Minimize exposed services and features
- Monitoring and Logging: Comprehensive audit trails
- Regular Updates: Automated patching and vulnerability management
Group Policy Configuration
Essential GPO Settings
Let's start with the most critical Group Policy settings that should be implemented on every Windows 11 system:
User Account Control (UAC)
# PowerShell script to configure UAC via registry
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "ConsentPromptBehaviorAdmin" -Value 2
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "ConsentPromptBehaviorUser" -Value 3
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "EnableLUA" -Value 1GPO Path: Computer Configuration > Policies > Windows Settings > Security Settings > Local Policies > Security Options
Key settings:
- User Account Control: Behavior of the elevation prompt for administrators: Set to "Prompt for consent on the secure desktop"
- User Account Control: Behavior of the elevation prompt for standard users: Set to "Prompt for credentials on the secure desktop"
Windows Defender Configuration
# Enable Windows Defender real-time protection
Set-MpPreference -DisableRealtimeMonitoring $false
Set-MpPreference -DisableBehaviorMonitoring $false
Set-MpPreference -DisableBlockAtFirstSeen $false
Set-MpPreference -DisableIOAVProtection $false
Set-MpPreference -DisableScriptScanning $falseGPO Path: Computer Configuration > Policies > Administrative Templates > Windows Components > Microsoft Defender Antivirus
Advanced Security Policies
Audit Policy Configuration
Comprehensive logging is crucial for security monitoring:
# Configure advanced audit policies
auditpol /set /category:"Logon/Logoff" /success:enable /failure:enable
auditpol /set /category:"Account Logon" /success:enable /failure:enable
auditpol /set /category:"Account Management" /success:enable /failure:enable
auditpol /set /category:"Policy Change" /success:enable /failure:enable
auditpol /set /category:"Privilege Use" /success:enable /failure:enable
auditpol /set /category:"System" /success:enable /failure:enableNetwork Security
# Disable SMBv1 protocol (major security risk)
Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol -NoRestart
# Configure SMB security
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force
Set-SmbServerConfiguration -RequireSecuritySignature $true -ForceAttack Surface Reduction (ASR) Rules
ASR rules are one of the most effective ways to prevent common attack vectors. Here's how to implement them:
PowerShell ASR Configuration
# Function to configure ASR rules
function Set-ASRRules {
$ASRRules = @{
# Block executable content from email client and webmail
"BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550" = "Enabled"
# Block all Office applications from creating child processes
"D4F940AB-401B-4EFC-AADC-AD5F3C50688A" = "Enabled"
# Block Office applications from creating executable content
"3B576869-A4EC-4529-8536-B80A7769E899" = "Enabled"
# Block Office applications from injecting code into other processes
"75668C1F-73B5-4CF0-BB93-3ECF5CB7CC84" = "Enabled"
# Block JavaScript or VBScript from launching downloaded executable content
"D3E037E1-3EB8-44C8-A917-57927947596D" = "Enabled"
# Block execution of potentially obfuscated scripts
"5BEB7EFE-FD9A-4556-801D-275E5FFC04CC" = "Enabled"
# Block Win32 API calls from Office macros
"92E97FA1-2EDF-4476-BDD6-9DD0B4DDDC7B" = "Enabled"
# Block process creations originating from PSExec and WMI commands
"D1E49AAC-8F56-4280-B9BA-993A6D77406C" = "Enabled"
# Block untrusted and unsigned processes that run from USB
"B2B3F03D-6A65-4F7B-A9C7-1C7EF74A9BA4" = "Enabled"
# Use advanced protection against ransomware
"C1DB55AB-C21A-4637-BB3F-A12568109D35" = "Enabled"
}
foreach ($Rule in $ASRRules.GetEnumerator()) {
try {
Add-MpPreference -AttackSurfaceReductionRules_Ids $Rule.Key -AttackSurfaceReductionRules_Actions $Rule.Value
Write-Host "Successfully configured ASR rule: $($Rule.Key)" -ForegroundColor Green
}
catch {
Write-Warning "Failed to configure ASR rule: $($Rule.Key) - $($_.Exception.Message)"
}
}
}
# Execute the function
Set-ASRRulesASR Rule Monitoring
# Script to check ASR rule effectiveness
function Get-ASRRuleStatus {
$ASRRules = Get-MpPreference | Select-Object -ExpandProperty AttackSurfaceReductionRules_Ids
$ASRActions = Get-MpPreference | Select-Object -ExpandProperty AttackSurfaceReductionRules_Actions
if ($ASRRules.Count -eq 0) {
Write-Host "No ASR rules configured" -ForegroundColor Yellow
return
}
for ($i = 0; $i -lt $ASRRules.Count; $i++) {
$RuleName = switch ($ASRRules[$i]) {
"BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550" { "Block executable content from email" }
"D4F940AB-401B-4EFC-AADC-AD5F3C50688A" { "Block Office child processes" }
"3B576869-A4EC-4529-8536-B80A7769E899" { "Block Office executable content" }
"75668C1F-73B5-4CF0-BB93-3ECF5CB7CC84" { "Block Office code injection" }
"D3E037E1-3EB8-44C8-A917-57927947596D" { "Block script-launched executables" }
"5BEB7EFE-FD9A-4556-801D-275E5FFC04CC" { "Block obfuscated scripts" }
"92E97FA1-2EDF-4476-BDD6-9DD0B4DDDC7B" { "Block Win32 API from Office macros" }
"D1E49AAC-8F56-4280-B9BA-993A6D77406C" { "Block PSExec/WMI processes" }
"B2B3F03D-6A65-4F7B-A9C7-1C7EF74A9BA4" { "Block untrusted USB processes" }
"C1DB55AB-C21A-4637-BB3F-A12568109D35" { "Ransomware protection" }
default { "Unknown rule" }
}
$Action = switch ($ASRActions[$i]) {
"Enabled" { "Enabled" }
"AuditMode" { "Audit Only" }
"Disabled" { "Disabled" }
default { "Unknown" }
}
Write-Host "$RuleName : $Action" -ForegroundColor $(if ($Action -eq "Enabled") { "Green" } elseif ($Action -eq "Audit Only") { "Yellow" } else { "Red" })
}
}
# Check current ASR status
Get-ASRRuleStatusWindows Firewall Configuration
Advanced Firewall Rules
# Configure Windows Firewall with advanced security
# Block all inbound connections by default
netsh advfirewall set allprofiles firewallpolicy blockinbound,allowoutbound
# Enable logging
netsh advfirewall set allprofiles logging filename "%systemroot%\system32\LogFiles\Firewall\pfirewall.log"
netsh advfirewall set allprofiles logging maxfilesize 4096
netsh advfirewall set allprofiles logging droppedconnections enable
netsh advfirewall set allprofiles logging allowedconnections enable
# Block common attack ports
$BlockedPorts = @(135, 139, 445, 1433, 1434, 3389, 5985, 5986)
foreach ($Port in $BlockedPorts) {
New-NetFirewallRule -DisplayName "Block Port $Port" -Direction Inbound -Protocol TCP -LocalPort $Port -Action Block -Enabled True
}PowerShell Execution Policy
# Set secure PowerShell execution policy
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine -Force
# Enable PowerShell script block logging
$RegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging"
if (!(Test-Path $RegPath)) {
New-Item -Path $RegPath -Force
}
Set-ItemProperty -Path $RegPath -Name "EnableScriptBlockLogging" -Value 1Service Hardening
Disable Unnecessary Services
# Function to safely disable services
function Disable-UnnecessaryServices {
$ServicesToDisable = @(
"Fax", # Fax service
"MapsBroker", # Downloaded Maps Manager
"lfsvc", # Geolocation Service
"SharedAccess", # Internet Connection Sharing
"TrkWks", # Distributed Link Tracking Client
"WMPNetworkSvc", # Windows Media Player Network Sharing
"XblAuthManager", # Xbox Live Auth Manager
"XblGameSave", # Xbox Live Game Save
"XboxNetApiSvc" # Xbox Live Networking Service
)
foreach ($Service in $ServicesToDisable) {
try {
$ServiceObj = Get-Service -Name $Service -ErrorAction SilentlyContinue
if ($ServiceObj) {
Stop-Service -Name $Service -Force -ErrorAction SilentlyContinue
Set-Service -Name $Service -StartupType Disabled
Write-Host "Disabled service: $Service" -ForegroundColor Green
}
}
catch {
Write-Warning "Could not disable service: $Service - $($_.Exception.Message)"
}
}
}
# Execute service hardening
Disable-UnnecessaryServicesRegistry Security Hardening
Critical Registry Modifications
# Function to apply security registry settings
function Set-SecurityRegistrySettings {
$RegistrySettings = @{
# Disable AutoRun for all drives
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" = @{
"NoDriveTypeAutoRun" = 255
}
# Disable Windows Script Host
"HKLM:\SOFTWARE\Microsoft\Windows Script Host\Settings" = @{
"Enabled" = 0
}
# Enable DEP for all programs
"HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer" = @{
"NoDataExecutionPrevention" = 0
"NoHeapTerminationOnCorruption" = 0
}
# Disable remote registry access
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurePipeServers\winreg" = @{
"RemoteRegAccess" = 0
}
}
foreach ($RegPath in $RegistrySettings.Keys) {
if (!(Test-Path $RegPath)) {
New-Item -Path $RegPath -Force | Out-Null
}
foreach ($Setting in $RegistrySettings[$RegPath].GetEnumerator()) {
try {
Set-ItemProperty -Path $RegPath -Name $Setting.Key -Value $Setting.Value -Force
Write-Host "Applied registry setting: $RegPath\$($Setting.Key)" -ForegroundColor Green
}
catch {
Write-Warning "Failed to apply registry setting: $RegPath\$($Setting.Key) - $($_.Exception.Message)"
}
}
}
}
# Apply registry hardening
Set-SecurityRegistrySettingsBitLocker Configuration
Enable BitLocker with TPM
# Function to enable BitLocker
function Enable-BitLockerProtection {
# Check if TPM is available
$TPM = Get-Tpm
if ($TPM.TpmPresent -and $TPM.TpmReady) {
try {
# Enable BitLocker on system drive
Enable-BitLocker -MountPoint "C:" -EncryptionMethod Aes256 -UsedSpaceOnly -TpmProtector
# Add recovery password protector
Add-BitLockerKeyProtector -MountPoint "C:" -RecoveryPasswordProtector
Write-Host "BitLocker enabled successfully" -ForegroundColor Green
# Get recovery key
$RecoveryKey = (Get-BitLockerVolume -MountPoint "C:").KeyProtector | Where-Object {$_.KeyProtectorType -eq "RecoveryPassword"}
Write-Host "Recovery Key: $($RecoveryKey.RecoveryPassword)" -ForegroundColor Yellow
Write-Warning "Save this recovery key in a secure location!"
}
catch {
Write-Error "Failed to enable BitLocker: $($_.Exception.Message)"
}
}
else {
Write-Warning "TPM is not available or ready. BitLocker cannot be enabled."
}
}
# Enable BitLocker if conditions are met
Enable-BitLockerProtectionMonitoring and Compliance
Security Compliance Check Script
# Comprehensive security compliance checker
function Test-SecurityCompliance {
$ComplianceResults = @()
# Check UAC status
$UACEnabled = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "EnableLUA").EnableLUA
$ComplianceResults += [PSCustomObject]@{
Check = "User Account Control"
Status = if ($UACEnabled -eq 1) { "PASS" } else { "FAIL" }
Details = "UAC is $(if ($UACEnabled -eq 1) { 'enabled' } else { 'disabled' })"
}
# Check Windows Defender status
$DefenderStatus = Get-MpComputerStatus
$ComplianceResults += [PSCustomObject]@{
Check = "Windows Defender Real-time Protection"
Status = if ($DefenderStatus.RealTimeProtectionEnabled) { "PASS" } else { "FAIL" }
Details = "Real-time protection is $(if ($DefenderStatus.RealTimeProtectionEnabled) { 'enabled' } else { 'disabled' })"
}
# Check Windows Update status
$UpdateService = Get-Service -Name "wuauserv"
$ComplianceResults += [PSCustomObject]@{
Check = "Windows Update Service"
Status = if ($UpdateService.Status -eq "Running") { "PASS" } else { "FAIL" }
Details = "Windows Update service is $($UpdateService.Status.ToString().ToLower())"
}
# Check firewall status
$FirewallProfiles = Get-NetFirewallProfile
$FirewallEnabled = ($FirewallProfiles | Where-Object {$_.Enabled -eq $false}).Count -eq 0
$ComplianceResults += [PSCustomObject]@{
Check = "Windows Firewall"
Status = if ($FirewallEnabled) { "PASS" } else { "FAIL" }
Details = "All firewall profiles are $(if ($FirewallEnabled) { 'enabled' } else { 'not enabled' })"
}
# Check ASR rules
$ASRRules = Get-MpPreference | Select-Object -ExpandProperty AttackSurfaceReductionRules_Ids
$ComplianceResults += [PSCustomObject]@{
Check = "Attack Surface Reduction Rules"
Status = if ($ASRRules.Count -gt 0) { "PASS" } else { "FAIL" }
Details = "$($ASRRules.Count) ASR rules configured"
}
# Display results
Write-Host "`nSecurity Compliance Results:" -ForegroundColor Cyan
Write-Host "=" * 50 -ForegroundColor Cyan
$ComplianceResults | ForEach-Object {
$Color = if ($_.Status -eq "PASS") { "Green" } else { "Red" }
Write-Host "[$($_.Status)]" -ForegroundColor $Color -NoNewline
Write-Host " $($_.Check): $($_.Details)"
}
$PassCount = ($ComplianceResults | Where-Object {$_.Status -eq "PASS"}).Count
$TotalCount = $ComplianceResults.Count
$CompliancePercentage = [math]::Round(($PassCount / $TotalCount) * 100, 2)
Write-Host "`nOverall Compliance: $CompliancePercentage% ($PassCount/$TotalCount)" -ForegroundColor $(if ($CompliancePercentage -ge 80) { "Green" } elseif ($CompliancePercentage -ge 60) { "Yellow" } else { "Red" })
}
# Run compliance check
Test-SecurityComplianceAutomated Hardening Script
Here's a comprehensive script that applies all the hardening measures:
# Windows 11 Hardening Master Script
param(
[switch]$SkipASR,
[switch]$SkipBitLocker,
[switch]$TestMode
)
function Write-HardeningLog {
param([string]$Message, [string]$Level = "INFO")
$Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$LogMessage = "[$Timestamp] [$Level] $Message"
Write-Host $LogMessage -ForegroundColor $(
switch ($Level) {
"ERROR" { "Red" }
"WARNING" { "Yellow" }
"SUCCESS" { "Green" }
default { "White" }
}
)
}
# Main hardening function
function Start-WindowsHardening {
Write-HardeningLog "Starting Windows 11 hardening process..." "SUCCESS"
if ($TestMode) {
Write-HardeningLog "Running in TEST MODE - no changes will be made" "WARNING"
return
}
try {
# Apply UAC settings
Write-HardeningLog "Configuring User Account Control..."
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "ConsentPromptBehaviorAdmin" -Value 2
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "EnableLUA" -Value 1
# Configure Windows Defender
Write-HardeningLog "Configuring Windows Defender..."
Set-MpPreference -DisableRealtimeMonitoring $false
Set-MpPreference -DisableBehaviorMonitoring $false
Set-MpPreference -DisableBlockAtFirstSeen $false
# Apply ASR rules if not skipped
if (-not $SkipASR) {
Write-HardeningLog "Applying Attack Surface Reduction rules..."
Set-ASRRules
}
# Configure firewall
Write-HardeningLog "Configuring Windows Firewall..."
netsh advfirewall set allprofiles firewallpolicy blockinbound,allowoutbound | Out-Null
# Disable unnecessary services
Write-HardeningLog "Disabling unnecessary services..."
Disable-UnnecessaryServices
# Apply registry hardening
Write-HardeningLog "Applying registry security settings..."
Set-SecurityRegistrySettings
# Enable BitLocker if not skipped
if (-not $SkipBitLocker) {
Write-HardeningLog "Configuring BitLocker..."
Enable-BitLockerProtection
}
Write-HardeningLog "Windows 11 hardening completed successfully!" "SUCCESS"
Write-HardeningLog "System restart recommended to ensure all changes take effect." "WARNING"
}
catch {
Write-HardeningLog "Error during hardening process: $($_.Exception.Message)" "ERROR"
}
}
# Execute hardening
Start-WindowsHardeningVerification and Testing
Security Validation Checklist
After applying these hardening measures, verify your configuration:
-
Run Windows Security Assessment:
Get-ComputerInfo | Select-Object WindowsProductName, WindowsVersion, TotalPhysicalMemory Get-MpComputerStatus | Select-Object AntivirusEnabled, RealTimeProtectionEnabled, IoavProtectionEnabled -
Test ASR Rules:
- Download EICAR test file to verify antivirus detection
- Test Office macro blocking with sample malicious documents
- Verify script execution policies are enforced
-
Validate Network Security:
Get-NetFirewallProfile | Select-Object Name, Enabled Get-NetFirewallRule | Where-Object {$_.Enabled -eq $true -and $_.Direction -eq "Inbound"} | Select-Object DisplayName, Action
Key Takeaways
- Layered Security: No single security measure is sufficient; implement multiple overlapping controls
- Regular Updates: Keep systems patched and security configurations current
- Monitoring: Implement comprehensive logging and regular security assessments
- User Training: Technical controls must be complemented by user awareness
- Testing: Always test hardening measures in non-production environments first
- Documentation: Maintain detailed records of all security configurations
- Compliance: Regularly verify that hardening measures remain effective
Conclusion
Windows 11 hardening is an ongoing process that requires careful planning, implementation, and maintenance. The configurations outlined in this guide provide a solid security foundation, but remember that security is not a one-time setup—it requires continuous monitoring and updates.
Start with the most critical settings (UAC, Windows Defender, Firewall) and gradually implement additional hardening measures based on your risk assessment and organizational requirements. Always test changes in a controlled environment before deploying to production systems.
Regular security assessments and compliance checks will help ensure your hardening measures remain effective against evolving threats. Consider implementing automated scripts to maintain consistent security configurations across your environment.
Remember: Security is a journey, not a destination. Stay informed about emerging threats and update your hardening strategies accordingly.