Windows Server Performance Monitor (PerfMon) & Telemetry Baselines
Monitoring Windows Server performance requires more than opening Task Manager when users complain of lag. Production environments require continuous, repeatable telemetry capture to detect memory leaks, CPU thread starvation, and storage latency spikes before outages occur.
This guide covers starting a persistent Performance Monitor (PerfMon) Data Collector Set, capturing critical disk and memory counters, and configuring a low-memory alert. The collector runs until you stop it; the example does not configure a scheduled start.
đ Windows Server Telemetry Pipeline
A robust telemetry architecture combines three tiers:
- System Health Counters: CPU utilization (
% Processor Time), Available MBytes, and Queue Length. - Storage Subsystem Metrics: Disk Seconds/Read, Disk Seconds/Write, and Average Disk Queue.
- Data Collector Sets: Bounded circular binary logs (
.blg) that retain recent measurements for historical analysis.
Step 1: Query Available Performance Counter Categories
Discover Available Performance Counter Sets via PowerShell
Counter DiscoveryDiscover installed system counter sets and inspect their specific instances using PowerShell:
# List high-priority performance counter sets:Get-Counter -ListSet "Processor", "Memory", "PhysicalDisk", "Paging File" | Select-Object CounterSetName, Description
# Inspect all specific counters under the Memory set:(Get-Counter -ListSet Memory).PathsStep 2: Capture Real-Time System Telemetry Samples
Sample CPU, Memory, and Disk Latency Counters
Real-Time SamplingExecute a targeted sample collection to measure immediate system pressure and disk latency:
# Define critical telemetry counters:$counters = @( "\Processor(_Total)\% Processor Time", "\Memory\Available MBytes", "\PhysicalDisk(_Total)\Avg. Disk sec/Read", "\PhysicalDisk(_Total)\Avg. Disk sec/Write", "\System\Processor Queue Length")
# Sample counters 5 times at 2-second intervals:Get-Counter -Counter $counters -SampleInterval 2 -MaxSamples 5 | Select-Object -ExpandProperty CounterSamples | Format-Table Path, CookedValue -AutoSize
Figure 1: Windows Performance Monitor (perfmon.msc) real-time line graph visualizing \Processor(_Total)% Processor Time, memory capacity, and disk latency.
Step 3: Create and Start a Persistent Background Data Collector Set
Create a Persistent Circular Performance Log
Log AutomationCreate a persistent Data Collector Set that records metrics to a bounded circular binary log (.blg). It continues running after the shell closes and stops only when stopped, the computer shuts down, or a configured limit is reached.
# Create an output directory for performance logs:New-Item -ItemType Directory -Path "C:\PerfLogs\SystemBaseline" -Force
# Create a circular Data Collector Set recording every 15 seconds, capped at 500 MB:logman.exe create counter "ServerBaseline" ` -f bincirc ` -si 15 ` -max 500 ` -o "C:\PerfLogs\SystemBaseline\Telemetry.blg" ` -c "\Processor(_Total)\% Processor Time" "\Memory\Available MBytes" "\PhysicalDisk(_Total)\% Disk Time"
# Start the collector set:logman.exe start "ServerBaseline"
Figure 2: Data Collector Set properties dialog configuring Binary (circular) log format, 500 MB maximum threshold, and output path to Telemetry.blg.
Step 4: Configure a Low-Memory Alert and Event Log Reporting
Configure a Low-Memory Warning Alert
AlertingCreate an alert for available memory below 1024 MB and enable Event Log reporting. This command does not create or run a scheduled task. If you want an action such as a script or notification, create and test a Task Scheduler task separately, then reference its exact task name with -tn.
# Enable Event Log reporting when the threshold is crossed:logman.exe create alert "LowMemoryAlert" ` -th "\Memory\Available MBytes<1024" ` -el
# Start the alert monitor:logman.exe start "LowMemoryAlert"
# Verify active status of all Data Collector Sets:logman.exe queryStep 5: Stop the Collector Before Exporting Its BLG Log
Export Binary Telemetry to CSV or Reports with relog.exe
ReportingStop the counter collector first so the binary log is closed, then convert the captured .blg file to CSV. Start the collector again if monitoring should continue.
# Close the active log before reading it:logman.exe stop "ServerBaseline"
# Convert the closed binary performance log into CSV:relog.exe "C:\PerfLogs\SystemBaseline\Telemetry.blg" -f csv -o "C:\PerfLogs\SystemBaseline\Report.csv"
# Confirm exported CSV output:Get-Item "C:\PerfLogs\SystemBaseline\Report.csv" | Select-Object Name, Length, LastWriteTime
# Optional: resume collection after exportlogman.exe start "ServerBaseline"