Diagnosing and Resolving Sporadic CPU Spikes in Windows Server 2008 Domain Controllers (DHCP/EventLog Focus)


1 views

When monitoring our Windows Server 2008 SP2 Domain Controllers, we noticed a consistent pattern of CPU utilization spikes occurring every 2-3 seconds. The vSphere performance charts reveal this behavior has persisted for over a year, with increased frequency since March. Process Explorer points to svchost.exe hosting three critical services:

- dhcpcsvc.dll (DHCP Client)
- wevtsvc.dll (Windows Event Log)
- lmhsvc.dll (LMHOSTS)

The EventLog service appears to be generating excessive RpcBindingUnbind calls. This suggests inefficient RPC connection handling, which could explain the periodic CPU spikes. Here's how to verify this programmatically:

@echo off
:: Capture RPC binding events
logman create trace RPCTrace -o C:\RPCTrace.etl -p "Microsoft-Windows-RPC" 0xffffffffffffffff -ets
timeout /t 30
logman stop RPCTrace -ets

For environments with multiple network interfaces, the DHCP client service can cause similar spikes. Try these registry tweaks:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters]
"DisableDHCPMediaSense"=dword:00000001
"TcpAckFrequency"=dword:00000001

The Windows Event Log service can be particularly resource-intensive on older OS versions. Consider these adjustments:

# PowerShell: Optimize event log settings
$logs = Get-WinEvent -ListLog *
foreach ($log in $logs) {
    if ($log.IsEnabled -and $log.LogMode -eq "Circular") {
        $log.MaximumSizeInBytes = 104857600 # 100MB
        $log.SaveChanges()
    }
}

For vSphere environments, ensure these VM settings are properly configured:

  • CPU: 2 vCPUs minimum with proper affinity settings
  • Memory: Enable memory reservation matching VM RAM allocation
  • Storage: Separate vmdk for system and log files

Implement this PowerShell monitor to capture spike patterns:

while ($true) {
    $cpu = (Get-Counter '\Processor(_Total)\% Processor Time').CounterSamples.CookedValue
    if ($cpu -gt 80) {
        $proc = Get-Process | Sort-Object CPU -Descending | Select -First 3
        $date = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
        "$date - CPU Spike detected. Top processes:n$proc" | Out-File "C:\CPU_Spikes.log" -Append
    }
    Start-Sleep -Seconds 1
}

While these mitigation steps help, the ultimate solution involves:

  1. Migrating to Windows Server 2012 R2 or newer
  2. Implementing proper DC load balancing
  3. Consider deploying RODCs for branch offices

When dealing with intermittent CPU spikes on legacy Windows Server 2008 SP2 Domain Controllers (not R2), we observe a distinctive pattern where svchost.exe processes hosting dhcpcsvc.dll, wevtsvc.dll, and lmhsvc.dll exhibit 80-100% CPU usage bursts every 2-3 seconds. The virtualization environment (vSphere 5.5.0 build 1331820) shows this pattern has persisted for over a year with increasing frequency since March.

The RPC binding/unbinding activity from EventLog service is particularly suspicious. Here's what we see in Process Explorer:

Thread Stack Trace:
ntoskrnl.exe!KeSynchronizeExecution+0x3a1
ntdll.dll!RpcBindingUnbind+0x15
wevtsvc.dll!ElfRpcBindingUnbind+0x2d
wevtsvc.dll!ElfPerformRpcOperation+0x112

Here's how to gather more forensic data:

# Capture ETW traces for DHCP and EventLog
logman start DhcpTrace -p Microsoft-Windows-DHCP-Client -o dhcp.etl -ets
logman start EventLogTrace -p Microsoft-Windows-EventLog -o eventlog.etl -ets

# Check for leaked RPC handles
rpcping -s %computername% -o -a connect -u 10 -v

For Windows Server 2008 SP2, these registry modifications may help:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Eventlog]
"MaxRpcCalls"=dword:00000032
"RpcConnectionTimeout"=dword:00002710

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Dhcp]
"APIProtocolSupport"=dword:00000004

Since this occurs in vSphere 5.5, verify these VM settings:

# PowerCLI snippet to check advanced parameters
Get-VM "DC*" | Get-AdvancedSetting | Where {
    $_.Name -like "vhv.*" -or 
    $_.Name -eq "hypervisor.cpuid.v0"
} | Format-Table Entity,Name,Value

Create a custom perfmon collector:

typeperf "\Process(svchost*)\% Processor Time" -si 1 -o svchost_cpu.csv
typeperf "\TCPv4\Connections Established" -si 1 -o tcp_conn.csv

Enable DHCP client debug logging:

netsh dhcp client set debug 1
netsh trace start scenario=netconnection capture=yes tracefile=dhcp.etl