Windows Defender is free, built-in, and — when properly configured — surprisingly capable. Combined with hardening settings that go beyond defaults, you can significantly reduce your attack surface without spending a dollar. This guide walks through every essential Windows hardening step with PowerShell commands.
1. Windows Defender Configuration
# Enable all Windows Defender protection features
Set-MpPreference -DisableRealtimeMonitoring $false
Set-MpPreference -DisableBehaviorMonitoring $false
Set-MpPreference -DisableIOAVProtection $false
Set-MpPreference -DisableScriptScanning $false
Set-MpPreference -EnableNetworkProtection Enabled
Set-MpPreference -EnableControlledFolderAccess Enabled # Ransomware protection!
Set-MpPreference -PUAProtection Enabled # Block potentially unwanted apps
Set-MpPreference -CloudBlockLevel High
Set-MpPreference -CloudExtendedTimeout 50
# Enable Attack Surface Reduction (ASR) rules - blocks common attack techniques
# Block Office macros from creating child processes
Add-MpPreference -AttackSurfaceReductionRules_Ids 3B576869-A4EC-4529-8536-B80A7769E899 -AttackSurfaceReductionRules_Actions Enabled
# Block credential stealing from LSASS
Add-MpPreference -AttackSurfaceReductionRules_Ids 9E6C4E1F-7D60-472F-BA1A-A39EF669E4B0 -AttackSurfaceReductionRules_Actions Enabled
# Block untrusted executable content from USB
Add-MpPreference -AttackSurfaceReductionRules_Ids B2B3F03D-6A65-4F7B-A9C7-1C7EF74A9BA4 -AttackSurfaceReductionRules_Actions Enabled
# Block Process Creation from WMI (living off the land)
Add-MpPreference -AttackSurfaceReductionRules_Ids E6DB77E5-3DF2-4CF1-B95A-636979351E5B -AttackSurfaceReductionRules_Actions Enabled
# View current Defender status
Get-MpComputerStatus | Select AMRunningMode, AntivirusEnabled, RealTimeProtectionEnabled, NISEnabled2. Windows Firewall Hardening
# Enable firewall on all profiles
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled True
# Block all inbound by default
Set-NetFirewallProfile -Profile Public -DefaultInboundAction Block -DefaultOutboundAction Allow
# View current rules
Get-NetFirewallRule | Where-Object {$_.Enabled -eq $true -and $_.Direction -eq "Inbound"} | Select DisplayName, Protocol, LocalPort
# Remove dangerous built-in rules (file sharing on public networks)
Set-NetFirewallRule -DisplayGroup "File and Printer Sharing" -Profile Public -Enabled False
# Block SMBv1 at firewall level (ransomware spreads via SMB)
New-NetFirewallRule -DisplayName "Block SMBv1" -Direction Inbound -Protocol TCP -LocalPort 445 -Action Block -Profile Public
# Block PowerShell remoting inbound (unless needed)
Disable-PSRemoting -Force3. Disable SMBv1
# Check if SMBv1 is enabled (it causes WannaCry/EternalBlue)
Get-WindowsOptionalFeature -Online -FeatureName SMB1Protocol
# Disable SMBv1 (CRITICAL - WannaCry/NotPetya spread via SMBv1)
Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol -NoRestart
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force
# Verify
Get-SmbServerConfiguration | Select EnableSMB1Protocol, EnableSMB2Protocol
# Also disable SMBv1 client (prevents your machine from being used as a pivot)
Set-SmbClientConfiguration -EnableBandwidthThrottling $false
sc.exe config lanmanworkstation depend= bowser/mrxsmb20/nsi
sc.exe config mrxsmb10 start= disabled4. User Account Control (UAC) and Admin Settings
# Set UAC to highest setting (prompt for ALL admin actions)
$registryPath = "HKLM:SOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystem"
Set-ItemProperty -Path $registryPath -Name "ConsentPromptBehaviorAdmin" -Value 2
Set-ItemProperty -Path $registryPath -Name "ConsentPromptBehaviorUser" -Value 3
Set-ItemProperty -Path $registryPath -Name "EnableLUA" -Value 1
Set-ItemProperty -Path $registryPath -Name "PromptOnSecureDesktop" -Value 1
# Disable local administrator account (use dedicated admin accounts instead)
Disable-LocalUser -Name "Administrator"
# Ensure guest account is disabled
Get-LocalUser "Guest" | Disable-LocalUser
# List all local admin accounts
Get-LocalGroupMember -Group "Administrators"
# Rename default admin account (makes it harder to target)
Rename-LocalUser -Name "Administrator" -NewName "Workstation_Admin"5. PowerShell Security
# Enable PowerShell Script Block Logging (critical for SIEM detection)
$path = "HKLM:SOFTWAREPoliciesMicrosoftWindowsPowerShellScriptBlockLogging"
New-Item -Path $path -Force
Set-ItemProperty -Path $path -Name "EnableScriptBlockLogging" -Value 1
Set-ItemProperty -Path $path -Name "EnableScriptBlockInvocationLogging" -Value 1
# Enable PowerShell Module Logging
$path2 = "HKLM:SOFTWAREPoliciesMicrosoftWindowsPowerShellModuleLogging"
New-Item -Path $path2 -Force
Set-ItemProperty -Path $path2 -Name "EnableModuleLogging" -Value 1
# Set execution policy to RemoteSigned (prevent unsigned scripts)
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine -Force
# Enable AMSI (Antimalware Scan Interface) for all scripts
# AMSI is already built-in on Windows 10+ but ensure it is not disabled
Get-ItemProperty "HKLM:SOFTWAREMicrosoftAMSIProviders"
# Log all PowerShell transcripts
$path3 = "HKLM:SOFTWAREPoliciesMicrosoftWindowsPowerShellTranscription"
New-Item -Path $path3 -Force
Set-ItemProperty -Path $path3 -Name "EnableTranscripting" -Value 1
Set-ItemProperty -Path $path3 -Name "OutputDirectory" -Value "C:PSTranscripts"
Set-ItemProperty -Path $path3 -Name "EnableInvocationHeader" -Value 16. Credential Protection
# Enable Credential Guard (prevents Mimikatz from reading LSASS)
# Requires UEFI, Secure Boot, TPM 2.0, and Windows 10 Enterprise/Server 2016+
# Via registry (Hyper-V must be enabled)
$cgPath = "HKLM:SYSTEMCurrentControlSetControlDeviceGuard"
Set-ItemProperty -Path $cgPath -Name "EnableVirtualizationBasedSecurity" -Value 1
Set-ItemProperty -Path $cgPath -Name "RequirePlatformSecurityFeatures" -Value 1
$lsaPath = "HKLM:SYSTEMCurrentControlSetControlLSA"
Set-ItemProperty -Path $lsaPath -Name "LsaCfgFlags" -Value 1
# Add WDigest to prevent plaintext credentials in memory
Set-ItemProperty -Path "HKLM:SYSTEMCurrentControlSetControlSecurityProvidersWDigest" -Name "UseLogonCredential" -Value 0
# Protect LSASS with RunAsPPL (Protected Process Light)
Set-ItemProperty -Path "HKLM:SYSTEMCurrentControlSetControlLSA" -Name "RunAsPPL" -Value 1
# Disable NTLM (if Kerberos is available everywhere)
Set-ItemProperty -Path "HKLM:SYSTEMCurrentControlSetControlLsaMSV1_0" -Name "RestrictSendingNTLMTraffic" -Value 27. Windows Update Configuration
# Check current update status
Get-HotFix | Sort-Object InstalledOn -Descending | Select -First 10
# Check for missing updates (requires PSWindowsUpdate module)
Install-Module -Name PSWindowsUpdate -Force
Get-WindowsUpdate
Install-WindowsUpdate -AcceptAll -AutoReboot
# Configure automatic updates via registry
$wuPath = "HKLM:SOFTWAREPoliciesMicrosoftWindowsWindowsUpdateAU"
New-Item -Path $wuPath -Force
Set-ItemProperty -Path $wuPath -Name "AUOptions" -Value 4 # Auto download and install
Set-ItemProperty -Path $wuPath -Name "NoAutoRebootWithLoggedOnUsers" -Value 08. Audit Policy Configuration
# Configure advanced audit policy
auditpol /set /subcategory:"Logon" /success:enable /failure:enable
auditpol /set /subcategory:"Logoff" /success:enable
auditpol /set /subcategory:"Account Lockout" /failure:enable
auditpol /set /subcategory:"Process Creation" /success: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:"Kerberos Service Ticket Operations" /success:enable /failure:enable
auditpol /set /subcategory:"File Share" /success:enable /failure:enable
# View current audit policy
auditpol /get /category:*
# Increase Security event log size (default is too small)
Limit-EventLog -LogName Security -MaximumSize 1GB
wevtutil sl Security /ms:10737418249. AppLocker Application Whitelisting
# Generate default AppLocker rules (allows Windows and Program Files)
Get-AppLockerPolicy -Effective | Out-String
# Create AppLocker policy via PowerShell
New-AppLockerPolicy -RuleType Path -FileInformation "C:Windows*" -User Everyone -RuleNamePrefix "Allow Windows"
# Block execution from temp directories (common malware staging locations)
New-AppLockerPolicy -RuleType Path -FileInformation "%TEMP%*" -User Everyone -RuleNamePrefix "Block TEMP" -Deny
# Enable AppLocker service
Set-Service -Name AppIDSvc -StartupType Automatic
Start-Service -Name AppIDSvc
# Test if a file would be blocked
Test-AppLockerPolicy -XMLPolicy (Get-AppLockerPolicy -Effective -Xml) -Path "C: empmalware.exe" -User EveryoneWindows Hardening Checklist
- Windows Defender: Real-time, cloud, ASR rules all enabled
- SMBv1 disabled (prevents WannaCry/EternalBlue)
- PowerShell logging: Script block + module + transcription enabled
- Credential Guard enabled (blocks Mimikatz)
- WDigest disabled (no plaintext passwords in memory)
- UAC at maximum, guest/default admin account disabled
- All Windows updates applied, auto-update configured
- Audit policy configured, Security log size at 1GB+
- AppLocker or WDAC configured for application whitelisting
- Controlled Folder Access enabled (ransomware protection)
Run Microsoft’s Security Baseline tool to compare your configuration against Microsoft’s own recommendations: download the Security Compliance Toolkit from the Microsoft Download Center and use the Policy Analyzer to see exactly what differs from the baseline.