When our ASP.NET WebAPI requests started taking 15+ seconds to complete, we initially suspected IIS configuration issues or database bottlenecks. Process Explorer revealed the real villain: MsMpEng.exe
consuming 50-90% CPU during each request. Surprisingly, we hadn't explicitly installed Windows Defender - it ships enabled by default in Server 2012.
Even without visible security products in "Programs and Features", Server 2012 includes Microsoft's anti-malware engine running as:
Get-Service -Name WinDefend
Status Name DisplayName
------ ---- -----------
Running WinDefend Windows Defender
For server environments, we need to fine-tune real-time scanning exclusions. This PowerShell script creates permanent exceptions:
# Add IIS process and content directories to exclusions
Add-MpPreference -ExclusionProcess "w3wp.exe"
Add-MpPreference -ExclusionProcess "inetmgr.exe"
Add-MpPreference -ExclusionPath "C:\\inetpub\\"
Add-MpPreference -ExclusionPath "D:\\WebApplications\\"
# Disable scheduled scanning (not needed for web servers)
Set-MpPreference -DisableRealtimeMonitoring $false
Set-MpPreference -DisableScanningNetworkFiles $true
Set-MpPreference -DisableIOAVProtection $true
# Verify settings
Get-MpPreference | Select-Object *Exclusion*
For non-internet-facing servers with alternative protection, complete disablement may be appropriate:
# Requires administrative privileges
Set-Service -Name WinDefend -StartupType Disabled
Stop-Service -Name WinDefend -Force
# Permanent removal via DISM (for Server Core)
Dism /online /Disable-Feature /FeatureName:Windows-Defender
Before/after benchmarking with wrk
showed dramatic improvement:
# Before tuning
wrk -t4 -c100 -d30s http://localhost/api/values
Requests/sec: 12.34
# After exclusions
wrk -t4 -c100 -d30s http://localhost/api/values
Requests/sec: 143.21
For clustered environments, these registry modifications help:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender]
"DisableAntiSpyware"=dword:00000001
"DisableRoutinelyTakingAction"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender]
"RealTimeScanDirection"=dword:00000001 # Only scan incoming files
MsMpEng.exe is the core engine of Microsoft's anti-malware solution, typically running as part of Windows Defender (even when not visibly installed). On Windows Server 2012, this service can become particularly aggressive during file operations - exactly what happens during web requests.
The real-time scanning feature checks every file accessed by IIS, including:
- ASP.NET compiled assemblies
- Web.config files
- Static content (JS, CSS, images)
This creates significant overhead for each HTTP request.
Here's how to check and modify the configuration:
# Check if Windows Defender is running
Get-Service -Name WinDefend
# View current exclusions
Get-MpPreference | Select-Object -ExpandProperty ExclusionPath
# Add IIS directory to exclusions
Add-MpPreference -ExclusionPath "C:\inetpub\"
Add-MpPreference -ExclusionPath "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\"
For development servers where security isn't critical:
Set-MpPreference -DisableRealtimeMonitoring $true
Warning: Only use this in secure internal networks.
Add these registry values under HKLM\SOFTWARE\Microsoft\Microsoft Antimalware\Scan
:
# Reduce scan priority
"Priority"=dword:00000004
# Skip scanning of mapped network drives
"DisableScanningMappedNetworkDrivesForFullScan"=dword:00000001
Use this PowerShell snippet to log CPU usage:
while($true) {
$cpu = (Get-Process MsMpEng).CPU
$time = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
"$time - CPU: $cpu" | Out-File "C:\monitor.log" -Append
Start-Sleep -Seconds 5
}
For systems where Microsoft's solution isn't required, completely remove it:
Uninstall-WindowsFeature -Name Windows-Defender
Remember to replace with alternative security solutions if removing.