How to Use Performance Monitor on Windows Server 2012 R2

Performance Monitor (perfmon.exe) is the primary built-in tool on Windows Server 2012 R2 for collecting, graphing, and analyzing system performance data. It provides real-time monitoring of hundreds of performance counters spanning CPU utilization, memory consumption, disk I/O, network throughput, and application-specific metrics. More importantly, Performance Monitor supports data collection sets — scheduled, recurring collections that log performance data to files for trend analysis, capacity planning, and post-incident forensics.

For production Windows Server 2012 R2 environments, Performance Monitor is essential for establishing performance baselines, identifying bottlenecks, validating infrastructure changes, and meeting SLA monitoring requirements. This guide covers launching and using the interactive interface, creating data collector sets, configuring performance alerts, and analyzing collected data — both through the GUI and through PowerShell automation.

Prerequisites

– Windows Server 2012 R2 with local or Remote Desktop access
– Administrative credentials
– Sufficient disk space for log file storage (performance logs can grow large)
– Knowledge of which application or service you are monitoring
– PowerShell 4.0 for command-line automation

Step 1: Open Performance Monitor

Launch Performance Monitor from Server Manager (Tools menu) or directly from Run:

perfmon.exe

Alternatively, open it with a specific view:

# Open directly to System Monitor (real-time graph)
perfmon /sys

# Open to Data Collector Sets
perfmon /report

The Performance Monitor console has three main sections in the left navigation pane:

Monitoring Tools: Contains Performance Monitor (real-time) and Performance Reports
Data Collector Sets: User Defined, System, and Event Trace Sessions
Reports: Stored reports from completed data collection sessions

Step 2: Add Performance Counters to the Real-Time View

The default view shows only the % Processor Time counter. Add counters by pressing Ctrl+N or clicking the green plus icon. For a standard server health view, add these essential counters:

Processor% Processor Time (_Total)
Processor% Privileged Time (_Total)
MemoryAvailable MBytes
MemoryPages/sec
MemoryPage Faults/sec
PhysicalDisk% Disk Time (_Total)
PhysicalDiskAvg. Disk Queue Length (_Total)
PhysicalDiskDisk Reads/sec (_Total)
PhysicalDiskDisk Writes/sec (_Total)
Network InterfaceBytes Total/sec (each adapter)
Network InterfaceOutput Queue Length (each adapter)
SystemProcessor Queue Length
SystemContext Switches/sec

You can also add these counters via PowerShell for documentation and repeatability:

# List all available counter sets
Get-Counter -ListSet * | Select-Object CounterSetName | Sort-Object CounterSetName

# List individual counters in a specific category
Get-Counter -ListSet "Processor" | Select-Object -ExpandProperty Paths

# Get a specific counter value immediately
Get-Counter -Counter "Processor(_Total)% Processor Time" -SampleInterval 2 -MaxSamples 5

Step 3: Create a Data Collector Set

Data Collector Sets (DCS) record performance data to a log file for later analysis. Creating a comprehensive DCS is one of the most important Performance Monitor tasks for production servers.

In the GUI: Right-click User Defined under Data Collector Sets, select New > Data Collector Set, choose “Create manually (Advanced),” select “Performance counter,” and add your desired counters.

Create a data collector set via PowerShell using logman.exe (the command-line perfmon tool):

# Create a comprehensive data collector set
logman create counter "ServerBaseline" `
    -c "Processor(_Total)% Processor Time" `
       "MemoryAvailable MBytes" `
       "MemoryPages/sec" `
       "PhysicalDisk(_Total)Avg. Disk Queue Length" `
       "PhysicalDisk(_Total)% Disk Time" `
       "Network Interface(*)Bytes Total/sec" `
       "SystemProcessor Queue Length" `
       "Process(_Total)% Processor Time" `
       "Process(_Total)Working Set" `
    -si 00:00:30 `
    -f bincirc `
    -max 500 `
    -o "C:PerfLogsServerBaselineServerBaseline.blg"

The -si 00:00:30 sets a 30-second sample interval. The -f bincirc uses a circular binary log file format that overwrites old data when the size limit (-max 500 MB) is reached.

Step 4: Configure DCS Schedule and Start/Stop

Configure the data collector set to run automatically on a schedule:

# Start the data collector set
logman start "ServerBaseline"

# Stop it
logman stop "ServerBaseline"

# Query status
logman query "ServerBaseline"

# Schedule to start at system boot and stop after 8 hours
logman update "ServerBaseline" -b 00:00:00 -rf 08:00:00 -rpas

# List all data collector sets
logman query

In the GUI, right-click the DCS and select Properties to configure schedule tabs — you can set it to run at specific times, during business hours, or continuously.

Step 5: Read Performance Logs with PowerShell

After collecting data, analyze log files using the Get-Counter cmdlet or the relog utility:

# Read a performance log file (BLG format)
$counters = Import-Counter -Path "C:PerfLogsServerBaselineServerBaseline_000001.blg"
$counters | Select-Object -First 5 | Format-List

# Get average CPU from a log file
$cpuSamples = Import-Counter `
    -Path "C:PerfLogsServerBaselineServerBaseline_000001.blg" `
    -Counter "Processor(_Total)% Processor Time"

$avgCPU = ($cpuSamples.CounterSamples | Measure-Object -Property CookedValue -Average).Average
Write-Host "Average CPU Usage: $([math]::Round($avgCPU, 2))%"

Convert a BLG binary log to CSV for analysis in Excel:

relog "C:PerfLogsServerBaselineServerBaseline_000001.blg" -f CSV -o "C:PerfLogsServerBaselineServerBaseline.csv"

Step 6: Use the Performance Analysis Report

Windows Server 2012 R2 includes built-in system diagnostics reports that automatically analyze performance data. Run a System Diagnostics report:

# Launch the built-in system diagnostics collector (runs for 60 seconds)
# In perfmon GUI: Data Collector Sets > System > System Diagnostics > Right-click > Start

# Start it via command line
logman start "SystemSystem Diagnostics"

After the collector finishes, find the report in Performance Monitor under Reports > System > System Diagnostics. The report identifies potential issues including missing drivers, hardware failures, and performance bottlenecks.

Step 7: Monitor IIS and Application-Specific Counters

For servers running IIS or SQL Server, add application-specific counters to your data collection:

# IIS performance counters
Get-Counter -ListSet "Web Service" | Select-Object -ExpandProperty Paths

# Add IIS counters to the DCS
logman update counter "ServerBaseline" `
    -c "Web Service(_Total)Current Connections" `
       "Web Service(_Total)Get Requests/sec" `
       "Web Service(_Total)Bytes Sent/sec" `
       "ASP.NETRequests Queued" `
       "ASP.NETRequests Rejected"

For SQL Server monitoring:

logman update counter "ServerBaseline" `
    -c "SQLServer:Buffer ManagerBuffer cache hit ratio" `
       "SQLServer:Buffer ManagerPage life expectancy" `
       "SQLServer:SQL StatisticsBatch Requests/sec" `
       "SQLServer:General StatisticsUser Connections"

Step 8: Set Performance Counter Alerts

Create alerts that trigger when a counter exceeds a threshold. The alert can write to the event log, start a data collector set, or run a program:

# Create a CPU alert using logman
logman create alert "HighCPUAlert" `
    -c "Processor(_Total)% Processor Time" `
    -th "Processor(_Total)% Processor Time>90" `
    -si 00:00:15 `
    -tnf "C:ScriptsHandleHighCPU.ps1" `
    -ela

# Start the alert
logman start "HighCPUAlert"

Step 9: Remote Performance Monitoring

Performance Monitor can monitor remote servers. In the GUI, connect to a remote computer by right-clicking Performance Monitor and selecting “Connect to another computer.” Via PowerShell:

# Read counters from a remote server
Get-Counter -ComputerName "Server01" -Counter "Processor(_Total)% Processor Time" -SampleInterval 5 -MaxSamples 12

# Create a remote data collector set
logman create counter "RemoteBaseline" -s "Server01" `
    -c "Processor(_Total)% Processor Time" `
       "MemoryAvailable MBytes" `
    -si 00:00:30 `
    -o "\Server01c$PerfLogsRemoteBaseline.blg"

logman start "RemoteBaseline" -s "Server01"

Step 10: Interpret Key Performance Indicators

Understanding threshold values is critical for meaningful performance monitoring:

# Script to evaluate current performance against thresholds
$thresholds = @{
    "Processor(_Total)% Processor Time"           = 80
    "MemoryAvailable MBytes"                       = 512  # Alert if BELOW this
    "PhysicalDisk(_Total)Avg. Disk Queue Length"   = 2
    "SystemProcessor Queue Length"                 = 4
}

$counters = Get-Counter -Counter $thresholds.Keys

foreach ($sample in $counters.CounterSamples) {
    $threshold = $thresholds[$sample.Path -replace "\\[^\]+", ""]
    $status = if ($sample.CookedValue -gt $threshold) { "WARNING" } else { "OK" }
    Write-Host "$status | $($sample.Path): $([math]::Round($sample.CookedValue,1))"
}

Summary

Performance Monitor on Windows Server 2012 R2 is a comprehensive, built-in performance management platform that requires no additional licensing. By creating scheduled Data Collector Sets with appropriate counter selections, configuring threshold alerts, and regularly reviewing the collected data, administrators can establish performance baselines, detect emerging capacity issues before they become outages, and provide evidence-based justification for hardware upgrades. The combination of the GUI console for interactive analysis and PowerShell with Get-Counter and logman for automation makes Performance Monitor suitable for both ad-hoc troubleshooting and systematic long-term capacity management.