Event ID 5000: Worker Process High CPU Usage
Complete troubleshooting guide for Exchange Server Event ID 5000 worker process high CPU usage causing slow performance, timeouts, and degraded mail services.
Table of Contents
Error Overview
Event ID 5000: Worker Process High CPU Usage
"The worker process for application pool 'MSExchangeOWAAppPool' exceeded CPU usage threshold. Process ID: 12345. CPU usage: 98%. Threshold: 90%. Actions may be throttled to protect server stability."
What This Error Means
High CPU usage in Exchange worker processes indicates the server is struggling to handle its workload. This affects all Exchange services - mail flow, client connectivity, and administrative operations. Users experience slow responses, timeouts, and degraded functionality until CPU usage is brought under control.
Key Exchange Processes
- • Store.Worker.exe - Database operations
- • w3wp.exe - IIS (OWA/ECP/EWS)
- • EdgeTransport.exe - Mail routing
- • MSExchangeSearch - Content indexing
- • NodeRunner.exe - Managed Availability
CPU Thresholds
- • Normal: 20-40% average
- • Acceptable: 40-60% sustained
- • Elevated: 60-80% sustained
- • High: 80-90% sustained
- • Critical: >90% sustained
Version Notice
This guide applies to Exchange Server 2016, 2019, and Subscription Edition. Process names and CPU management have evolved across versions. Exchange 2019 has improved CPU efficiency through optimizations in the Store Worker process.
Symptoms & Detection
User-Reported Symptoms
- ✗OWA loads extremely slowly
- ✗Outlook frequently shows "Disconnected"
- ✗Send/receive operations timeout
- ✗Email delivery significantly delayed
- ✗ECP admin console unresponsive
Administrator Detection
- →Event ID 5000 in Application log
- →Task Manager shows high CPU usage
- →Performance Monitor alerts
- →Managed Availability health probe failures
- →Transport queues building up
Event Log Entry Example
Log Name: Application
Source: MSExchange Common
Event ID: 5000
Level: Warning
Description: Performance counter 'Process(_Total)% Processor Time'
has exceeded the threshold of 90%.
Current value: 98%
Top CPU consumers:
- Microsoft.Exchange.Store.Worker (PID: 5678): 45%
- w3wp (MSExchangeOWAAppPool) (PID: 1234): 28%
- MSExchangeTransport (PID: 9012): 15%
Server may experience degraded performance.
Consider investigating the high-CPU processes.Common Causes
Content Index Rebuilding
When the search index is corrupt or needs rebuilding, the Microsoft.Exchange.Search.Service process consumes significant CPU to re-index all mailbox content. This can last hours or days depending on database size.
Problematic Mailboxes
Mailboxes with excessive items, complex rules, corrupted items, or third-party add-ins can cause high CPU during access. A single problematic mailbox can affect server-wide performance.
Antivirus Scanning
Real-time antivirus scanning of Exchange files, transport queues, and database operations creates significant CPU overhead. Improperly configured AV can double or triple CPU usage.
Insufficient Hardware
Server doesn't have enough CPU cores for the number of users and mailboxes. Common when organizations grow without scaling infrastructure or after migrations that increase server load.
Backup or Maintenance Operations
VSS backups, database maintenance, mailbox moves, or public folder migrations running during business hours can consume significant CPU alongside normal user workload.
Diagnostic Steps
Step 1: Identify High-CPU Processes
# Get top CPU-consuming processes
Get-Process | Sort-Object CPU -Descending | Select-Object -First 15 |
Select-Object ProcessName, Id,
@{N='CPU (sec)';E={[math]::Round($_.CPU,0)}},
@{N='Memory (MB)';E={[math]::Round($_.WorkingSet64/1MB,0)}},
@{N='Threads';E={$_.Threads.Count}} |
Format-Table -AutoSize
# Filter for Exchange-specific processes
$exchangeProcs = "Exchange|MSExchange|w3wp|EdgeTransport|NodeRunner|HostController"
Get-Process | Where-Object {$_.ProcessName -match $exchangeProcs} |
Sort-Object CPU -Descending |
Select-Object ProcessName, Id,
@{N='CPU (sec)';E={[math]::Round($_.CPU,0)}},
@{N='Memory (MB)';E={[math]::Round($_.WorkingSet64/1MB,0)}} |
Format-Table -AutoSize
# Real-time CPU monitoring
$server = $env:COMPUTERNAME
Get-Counter "\$server\Process(*)\% Processor Time" -SampleInterval 2 -MaxSamples 5 |
ForEach-Object { $_.CounterSamples } |
Where-Object {$_.CookedValue -gt 5 -and $_.InstanceName -ne "_total" -and $_.InstanceName -ne "idle"} |
Sort-Object CookedValue -Descending |
Select-Object InstanceName, @{N='CPU%';E={[math]::Round($_.CookedValue,1)}} -First 10 |
Format-Table -AutoSizeStep 2: Check IIS Application Pool CPU
# Get IIS worker process details
Import-Module WebAdministration
# Map w3wp processes to application pools
Get-ChildItem IIS:AppPools | ForEach-Object {
$pool = $_
$wp = Get-WmiObject Win32_Process -Filter "Name='w3wp.exe'" |
Where-Object {$_.CommandLine -match $pool.Name}
if ($wp) {
$proc = Get-Process -Id $wp.ProcessId -ErrorAction SilentlyContinue
[PSCustomObject]@{
AppPool = $pool.Name
ProcessId = $wp.ProcessId
'CPU (sec)' = [math]::Round($proc.CPU,0)
'Memory (MB)' = [math]::Round($proc.WorkingSet64/1MB,0)
Status = $pool.State
}
}
} | Sort-Object 'CPU (sec)' -Descending | Format-Table -AutoSize
# Check specific Exchange app pools
$exchangePools = @(
"MSExchangeOWAAppPool",
"MSExchangeECPAppPool",
"MSExchangeServicesAppPool",
"MSExchangeRpcProxyAppPool",
"MSExchangeMapiMailboxAppPool"
)
foreach ($poolName in $exchangePools) {
$pool = Get-WebAppPoolState -Name $poolName -ErrorAction SilentlyContinue
if ($pool) {
Write-Host "$poolName : $($pool.Value)"$pool.Value)"
}
}Step 3: Check for Content Index Activity
# Check content index status for all databases
Get-MailboxDatabaseCopyStatus * | Select-Object Name, Status, ContentIndexState,
ContentIndexErrorMessage | Format-Table -AutoSize
# Check for databases being indexed
$indexingDatabases = Get-MailboxDatabaseCopyStatus * |
Where-Object {$_.ContentIndexState -ne "Healthy"}
if ($indexingDatabases) {
Write-Host "=== Databases with Non-Healthy Index ===" -ForegroundColor Yellow
$indexingDatabases | Format-Table Name, ContentIndexState, ContentIndexErrorMessage -Wrap
}
# Check Search service CPU usage
Get-Process -Name "Microsoft.Exchange.Search.Service", "NodeRunner", "HostControllerService" -ErrorAction SilentlyContinue |
Select-Object ProcessName, Id, @{N='CPU';E={[math]::Round($_.CPU,0)}}, @{N='Memory(MB)';E={[math]::Round($_.WorkingSet64/1MB,0)}} |
Format-Table -AutoSize
# Check index folder size
$exchangePath = (Get-ItemProperty 'HKLM:SOFTWAREMicrosoftExchangeServer15Setup').MsiInstallPath
Get-MailboxDatabase | ForEach-Object {
$dbPath = Split-Path $_.EdbFilePath.PathName
$indexPath = Get-ChildItem "$dbPath*" -Directory -Filter "*.Single" -ErrorAction SilentlyContinue
if ($indexPath) {
$size = (Get-ChildItem $indexPath.FullName -Recurse | Measure-Object -Property Length -Sum).Sum / 1GB
[PSCustomObject]@{
Database = $_.Name
IndexPath = $indexPath.Name
'Size (GB)' = [math]::Round($size, 2)
}
}
} | Format-Table -AutoSizeStep 4: Identify Resource-Intensive Mailboxes
# Get store usage statistics (requires Exchange Management Shell)
# Find mailboxes consuming most resources
# Get mailboxes with largest sizes
Get-MailboxStatistics -Server $env:COMPUTERNAME |
Sort-Object TotalItemSize -Descending |
Select-Object DisplayName, ItemCount,
@{N='Size(GB)';E={[math]::Round($_.TotalItemSize.Value.ToGB(),2)}},
LastLogonTime, DatabaseName |
Select-Object -First 20 | Format-Table -AutoSize
# Find mailboxes with excessive item counts
Get-MailboxStatistics -Server $env:COMPUTERNAME |
Where-Object {$_.ItemCount -gt 100000} |
Select-Object DisplayName, ItemCount,
@{N='Size(GB)';E={[math]::Round($_.TotalItemSize.Value.ToGB(),2)}} |
Sort-Object ItemCount -Descending | Format-Table -AutoSize
# Check for mailboxes with many rules
Get-Mailbox -ResultSize 100 | ForEach-Object {
$rules = Get-InboxRule -Mailbox $_.Identity -ErrorAction SilentlyContinue
if ($rules.Count -gt 10) {
[PSCustomObject]@{
Mailbox = $_.DisplayName
RuleCount = $rules.Count
}
}
} | Sort-Object RuleCount -Descending | Format-Table -AutoSize
# Check for mailboxes with excessive folder counts
# High folder counts can cause high CPU during sync
Get-Mailbox -ResultSize 20 | ForEach-Object {
$folderCount = (Get-MailboxFolderStatistics $_.Identity | Measure-Object).Count
[PSCustomObject]@{
Mailbox = $_.DisplayName
FolderCount = $folderCount
}
} | Sort-Object FolderCount -Descending | Format-Table -AutoSizePro Tip
Use Windows Performance Recorder (WPR) to capture a detailed CPU profile during high-usage periods. This provides call stack information that can pinpoint exactly what code is consuming CPU - invaluable for complex troubleshooting.
Quick Fix
Immediate CPU Relief
These steps can provide quick relief while investigating root cause:
# Step 1: Identify and restart high-CPU IIS app pool-CPU IIS app pool
Import-Module WebAdministration
# Recycle the highest-CPU Exchange app pool
$pools = @("MSExchangeOWAAppPool", "MSExchangeECPAppPool", "MSExchangeServicesAppPool")
foreach ($pool in $pools) {
Write-Host "Recycling $pool..." -ForegroundColor Yellow
Restart-WebAppPool -Name $pool
Start-Sleep -Seconds 5
}
# Step 2: Pause content indexing if it's causing high CPU
# Get databases with active indexing
$indexing = Get-MailboxDatabaseCopyStatus * | Where-Object {$_.ContentIndexState -eq "Crawling"}
if ($indexing) {
Write-Host "Content index rebuilding in progress - this may be the cause" -ForegroundColor Yellow
# To pause (use with caution):
# Stop-Service MSExchangeFastSearch
}
# Step 3: Suspend any running mailbox moves
Get-MoveRequest -MoveStatus InProgress | Suspend-MoveRequest -Confirm:$false
# Step 4: Reduce concurrent connections (temporary)
# This affects user experience but reduces load
# Set-ThrottlingPolicy "GlobalThrottlingPolicy_<GUID>" -RcaMaxConcurrency 10"GlobalThrottlingPolicy_<GUID>" -RcaMaxConcurrency 10
# Step 5: Check for and stop runaway processes
Get-Process | Where-Object {
$_.ProcessName -match "Exchange|w3wp" -and
$_.CPU -gt 1000 -and # More than 1000 seconds of CPU time
(New-TimeSpan -Start $_.StartTime).TotalMinutes -lt 60 # Started within last hour
} | ForEach-Object {
Write-Host "High CPU process: $($_.ProcessName) (PID: $($_.Id), CPU: $($_.CPU)s)"$_.Id), CPU: $($_.CPU)s)" -ForegroundColor Red
# Uncomment to stop: Stop-Process -Id $_.Id -Force-Id $_.Id -Force
}Note: Recycling app pools causes brief interruption for users of that service. Use during lower-usage periods when possible.
Detailed Solutions
Solution 1: Fix Content Index Issues
Rebuild or repair content indexes that are causing high CPU:
# Check content index health
Get-MailboxDatabaseCopyStatus * |
Select-Object Name, ContentIndexState, ContentIndexErrorMessage |
Format-Table -Wrap
# Reset failed content index
$failedIndexes = Get-MailboxDatabaseCopyStatus * |
Where-Object {$_.ContentIndexState -eq "Failed" -or $_.ContentIndexState -eq "FailedAndSuspended"}
foreach ($db in $failedIndexes) {
Write-Host "Resetting content index for: $($db.Name)" -ForegroundColor Yellow
# Update the catalog (reseeds the index)
Update-MailboxDatabaseCopy -Identity $db.Name -CatalogOnly -Confirm:$false
}
# For crawling indexes consuming too much CPU, you can throttle
# Registry setting to limit indexing CPU usage:
# HKLMSOFTWAREMicrosoftExchangeServer15SearchSystemParameters
# MaxIOThreads (DWORD) - Default is number of processors, reduce to limit CPU
# Schedule index rebuild during off-hours
# Stop-Service MSExchangeFastSearch
# Remove index folder contents
# Start-Service MSExchangeFastSearch (will trigger rebuild)
# Monitor index progress
$lastState = ""
while ($true) {
$status = Get-MailboxDatabaseCopyStatus * |
Where-Object {$_.ContentIndexState -ne "Healthy"} |
Select-Object Name, ContentIndexState -First 1
if ($status -and $status.ContentIndexState -ne $lastState) {
Write-Host "$(Get-Date): $($status.Name) - $($status.ContentIndexState)"$status.Name) - $($status.ContentIndexState)"
$lastState = $status.ContentIndexState
}
if (-not $status) {
Write-Host "All indexes healthy" -ForegroundColor Green
break
}
Start-Sleep -Seconds 30
}Solution 2: Configure AV Exclusions
Ensure antivirus is properly configured to minimize Exchange CPU impact:
# Generate list of AV exclusions for Exchange
$exchangePath = (Get-ItemProperty 'HKLM:SOFTWAREMicrosoftExchangeServer15Setup').MsiInstallPath
Write-Host "=== Required AV Process Exclusions ===" -ForegroundColor Yellow
@(
"Cdb.exe",
"Microsoft.Exchange.AntispamUpdateSvc.exe",
"Microsoft.Exchange.ContentFilter.Wrapper.exe",
"Microsoft.Exchange.Diagnostics.Service.exe",
"Microsoft.Exchange.Directory.TopologyService.exe",
"Microsoft.Exchange.EdgeCredentialSvc.exe",
"Microsoft.Exchange.EdgeSyncSvc.exe",
"Microsoft.Exchange.Imap4.exe",
"Microsoft.Exchange.Imap4service.exe",
"Microsoft.Exchange.Notifications.Broker.exe",
"Microsoft.Exchange.Pop3.exe",
"Microsoft.Exchange.Pop3service.exe",
"Microsoft.Exchange.ProtectedServiceHost.exe",
"Microsoft.Exchange.RPCClientAccess.Service.exe",
"Microsoft.Exchange.Search.Service.exe",
"Microsoft.Exchange.Servicehost.exe",
"Microsoft.Exchange.Store.Service.exe",
"Microsoft.Exchange.Store.Worker.exe",
"Microsoft.Exchange.TransportSyncManagerSvc.exe",
"Microsoft.Exchange.UM.CallRouter.exe",
"MSExchangeDelivery.exe",
"MSExchangeFrontEndTransport.exe",
"MSExchangeHMHost.exe",
"MSExchangeHMWorker.exe",
"MSExchangeMailboxAssistants.exe",
"MSExchangeMailboxReplication.exe",
"MSExchangeRepl.exe",
"MSExchangeSubmission.exe",
"MSExchangeTransport.exe",
"MSExchangeTransportLogSearch.exe",
"OleConverter.exe",
"UmService.exe",
"UmWorkerProcess.exe",
"W3wp.exe"
) | ForEach-Object { Write-Host " $_" }
Write-Host "`n=== Required AV Folder Exclusions ===" -ForegroundColor Yellow
Write-Host "Exchange Installation: $exchangePath"
# Database and log paths
Get-MailboxDatabase | ForEach-Object {
Write-Host "DB: $($_.EdbFilePath.PathName)"
Write-Host "Logs: $($_.LogFolderPath.PathName)"
}
Write-Host "`n=== AV Best Practices ===" -ForegroundColor Cyan
Write-Host "1. Exclude all paths and processes listed above"
Write-Host "2. Disable real-time scanning for Exchange paths"-time scanning for Exchange paths"
Write-Host "3. Schedule full scans during off-hours only"-hours only"
Write-Host "4. Limit concurrent scan threads"
Write-Host "5. Use Exchange-aware AV products when possible"-aware AV products when possible"Solution 3: Address Problematic Mailboxes
Identify and fix mailboxes causing excessive CPU usage:
# Find and fix large mailboxes
$largeMailboxes = Get-MailboxStatistics -Server $env:COMPUTERNAME |
Where-Object {$_.TotalItemSize.Value.ToGB() -gt 25} |
Sort-Object TotalItemSize -Descending
Write-Host "=== Large Mailboxes (>25GB) ===" -ForegroundColor Yellow
$largeMailboxes | Select-Object DisplayName,
@{N='Size(GB)';E={[math]::Round($_.TotalItemSize.Value.ToGB(),2)}},
ItemCount | Format-Table -AutoSize
# Check for mailboxes with calendar issues
# High calendar item counts cause sync CPU spikes
Get-Mailbox -ResultSize 50 | ForEach-Object {
$calStats = Get-MailboxFolderStatistics $_.Identity -FolderScope Calendar -ErrorAction SilentlyContinue
if ($calStats.ItemsInFolder -gt 5000) {
[PSCustomObject]@{
Mailbox = $_.DisplayName
CalendarItems = $calStats.ItemsInFolder
}
}
} | Format-Table -AutoSize
# Disable problematic mailbox rules
# First, find mailboxes with many rules
Get-Mailbox -ResultSize Unlimited | ForEach-Object {
$rules = Get-InboxRule -Mailbox $_.Identity -ErrorAction SilentlyContinue
if ($rules.Count -gt 20) {
Write-Host "Mailbox with many rules: $($_.DisplayName) - $($rules.Count) rules"$rules.Count) rules" -ForegroundColor Yellow
# Review and disable unnecessary rules:
# Disable-InboxRule -Mailbox $_.Identity -Identity "RuleName"-Mailbox $_.Identity -Identity "RuleName"
}
}
# For corrupted mailboxes, run repair
# New-MailboxRepairRequest -Mailbox "user@domain.com" -CorruptionType SearchFolder,AggregateCounts,ProvisionedFolder,FolderView-Mailbox "user@domain.com" -CorruptionType SearchFolder,AggregateCounts,ProvisionedFolder,FolderView
# Consider moving large mailboxes to dedicated database
# New-MoveRequest -Identity "user@domain.com" -TargetDatabase "LargeMailboxDB" -BadItemLimit 10-Identity "user@domain.com" -TargetDatabase "LargeMailboxDB" -BadItemLimit 10Solution 4: Upgrade Server CPU Capacity
If CPU is consistently high, the server may need more processing power:
# Check current CPU configuration
$cpu = Get-CimInstance Win32_Processor
Write-Host "=== Current CPU Configuration ===" -ForegroundColor Cyan
Write-Host "Processor: $($cpu.Name)"
Write-Host "Cores: $($cpu.NumberOfCores)"
Write-Host "Logical Processors: $($cpu.NumberOfLogicalProcessors)"
Write-Host "Max Clock Speed: $($cpu.MaxClockSpeed) MHz"
# Calculate recommended CPU based on mailboxes
$mailboxCount = (Get-Mailbox -ResultSize Unlimited | Measure-Object).Count
$recommendedCores = [math]::Ceiling($mailboxCount / 1000)
Write-Host "`n=== Capacity Calculation ===" -ForegroundColor Yellow
Write-Host "Total Mailboxes: $mailboxCount"
Write-Host "Recommended Minimum Cores: $recommendedCores"
Write-Host "Current Cores: $($cpu.NumberOfCores)"
if ($cpu.NumberOfCores -lt $recommendedCores) {
Write-Host "`nWARNING: Current CPU may be undersized for workload" -ForegroundColor Red
}
# Check if hyperthreading is helping or hurting
# Exchange benefits from real cores more than HT
$htRatio = $cpu.NumberOfLogicalProcessors / $cpu.NumberOfCores
if ($htRatio -gt 1) {
Write-Host "`nHyperthreading is enabled (${htRatio}:1 ratio)"
Write-Host "Consider testing with HT disabled if experiencing high kernel time"
}
# Scaling options:
Write-Host "`n=== Scaling Options ===" -ForegroundColor Cyan
Write-Host "1. Add more CPU cores to existing server (if possible)"
Write-Host "2. Add additional Exchange server and redistribute load"
Write-Host "3. For VMs: Allocate more vCPUs (check host capacity)"
Write-Host "4. Migrate to newer, faster CPU generation"
Write-Host "5. Enable processor power management for full performance"Danger Zone
Avoid setting process affinity or CPU limits on Exchange processes. Exchange is designed to use available CPU resources dynamically. Artificial limits will cause service degradation and are not supported by Microsoft.
Verification Steps
Verify CPU Issue Resolution
# Comprehensive CPU health verification
$server = $env:COMPUTERNAME
$duration = 300 # 5 minutes
$interval = 10
Write-Host "Collecting CPU data for $($duration/60) minutes..."60) minutes..." -ForegroundColor Cyan
$samples = Get-Counter "\$server\Processor(_Total)\% Processor Time" -SampleInterval $interval -MaxSamples ($duration/$interval)
$cpuValues = $samples.CounterSamples | ForEach-Object { $_.CookedValue }
$avgCpu = ($cpuValues | Measure-Object -Average).Average
$maxCpu = ($cpuValues | Measure-Object -Maximum).Maximum
Write-Host "`n=== CPU Performance Summary ===" -ForegroundColor Green
Write-Host "Average CPU: $([math]::Round($avgCpu,1))%"1))%"
Write-Host "Maximum CPU: $([math]::Round($maxCpu,1))%"1))%"
# Determine health status
$status = if ($avgCpu -lt 40) {"HEALTHY"}
elseif ($avgCpu -lt 60) {"ACCEPTABLE"}
elseif ($avgCpu -lt 80) {"ELEVATED"}
else {"HIGH - Investigation needed"}
$color = if ($avgCpu -lt 40) {"Green"}
elseif ($avgCpu -lt 60) {"Yellow"}
elseif ($avgCpu -lt 80) {"Yellow"}
else {"Red"}
Write-Host "Status: $status" -ForegroundColor $color
# Check for recent Event ID 5000
$recentEvents = Get-WinEvent -FilterHashtable @{
LogName = 'Application'
Id = 5000
StartTime = (Get-Date).AddHours(-24)
} -ErrorAction SilentlyContinue
if ($recentEvents) {
Write-Host "`nWARNING: $($recentEvents.Count) high CPU events in last 24 hours"24 hours" -ForegroundColor Yellow
} else {
Write-Host "`nNo high CPU events in last 24 hours" -ForegroundColor Green
}
# Current top CPU processes
Write-Host "`n=== Current Top CPU Processes ===" -ForegroundColor Yellow
Get-Counter "\$server\Process(*)\% Processor Time" |
Select-Object -ExpandProperty CounterSamples |
Where-Object {$_.CookedValue -gt 1 -and $_.InstanceName -ne "_total" -and $_.InstanceName -ne "idle"} |
Sort-Object CookedValue -Descending |
Select-Object @{N='Process';E={$_.InstanceName}}, @{N='CPU%';E={[math]::Round($_.CookedValue,1)}} -First 10 |
Format-Table -AutoSize✓ Success Indicators
- • Average CPU < 40%
- • No Event ID 5000 events
- • User response times normal
- • All indexes healthy
⚠ Warning Signs
- • CPU 40-60% sustained
- • Occasional slowness
- • Spikes during peak hours
- • Index rebuilding active
✗ Failure Indicators
- • CPU > 80% sustained
- • Frequent Event ID 5000
- • Service timeouts
- • User complaints continue
Prevention Strategies
CPU Monitoring Best Practices
- ✓Set baseline alerts
Alert when sustained CPU exceeds 70%
- ✓Monitor process CPU
Track per-process CPU to identify issues early
- ✓Schedule intensive tasks
Run backups, moves during off-hours
- ✓Capacity planning
Review CPU quarterly as user count grows
CPU Monitoring Script
# Daily CPU health check
$server = $env:COMPUTERNAME
$alertThreshold = 70
# Sample CPU over 1 minute
$samples = Get-Counter "\$server\Processor(_Total)\% Processor Time" -SampleInterval 5 -MaxSamples 12
$avgCpu = ($samples.CounterSamples | Measure-Object CookedValue -Average).Average
$status = if ($avgCpu -lt $alertThreshold) {"OK"} else {"ALERT"}
# Log to CSV
$log = "$(Get-Date -Format 'yyyy-MM-dd HH:mm'),$server,$([math]::Round($avgCpu,1)),$status"-Format 'yyyy-MM-dd HH:mm'),$server,$([math]::Round($avgCpu,1)),$status"
Add-Content "C:LogsCPU_Health.csv" $log
# Send alert if needed
if ($avgCpu -gt $alertThreshold) {
$topProcs = Get-Counter "\$server\Process(*)\% Processor Time" |
Select-Object -ExpandProperty CounterSamples |
Where-Object {$_.CookedValue -gt 5 -and $_.InstanceName -ne "_total"} |
Sort-Object CookedValue -Descending |
Select-Object -First 5
Write-Warning "High CPU: $([math]::Round($avgCpu,1))%"1))%"
$topProcs | ForEach-Object {
Write-Host " $($_.InstanceName): $([math]::Round($_.CookedValue,1))%"$_.CookedValue,1))%"
}
}When to Escalate
Escalate to Exchange Specialist When:
- →High CPU persists after addressing known causes
- →Cannot identify the source of CPU consumption
- →Suspected memory leak causing CPU issues
- →Need assistance with performance profiling
- →Capacity planning for growth required
Need Expert Exchange CPU Help?
Our Exchange Server specialists can diagnose complex CPU issues, optimize your environment, and implement solutions that deliver consistent performance for your users.
15 Minutes average response time for performance emergencies
Frequently Asked Questions
Can't Resolve HIGH_CPU_USAGE?
Exchange errors can cause data loss or extended downtime. Our specialists are available 24/7 to help.
Emergency help - Chat with usMedha Cloud Exchange Server Team
Microsoft Exchange Specialists
Our Exchange Server specialists have 15+ years of combined experience managing enterprise email environments. We provide 24/7 support, emergency troubleshooting, and ongoing administration for businesses worldwide.