Automating Windows Server Performance Monitoring: WMI Scripting and Alternative Tools to Perfmon


2 views

Managing Windows Server infrastructure (2003/IIS/SQL) with manual Perfmon setups creates operational inefficiencies. When monitoring PCs reboot, administrators waste hours recreating:

  • CPU/Memory/Disk counter thresholds
  • Custom performance data collector sets
  • Real-time visualization layouts

This script automates Perfmon counter configuration and persists settings:


# Create persistent data collector
$collectorName = "ProdServerMetrics"
$counters = @(
    "\Processor(_Total)\% Processor Time", 
    "\Memory\Available MBytes",
    "\LogicalDisk(C:)\% Free Space"
)

New-DataCollectorSet -Name $collectorName -SampleInterval 5 -PerformanceCounter $counters | 
Start-DataCollectorSet

# Export for redeployment
Export-Counter -Path "C:\monitoring\perfconfig.xml" -Counter $counters -Force

1. PRTG Network Monitor

Enterprise-ready solution with pre-configured Windows sensors:

  • Auto-discovers WMI performance counters
  • Preserves dashboards through reboots
  • API for custom integrations (Python example):

import prtg.sensor

sensors = {
    "CPU_Load": "wmi_cpu_load",
    "SQL_Connections": "sql_connection_pool" 
}

dashboard = prtg.Dashboard(config="prod_monitoring.json")
dashboard.deploy_sensors(sensors)

2. Zabbix Windows Templates

Open-source option with these advantages:

  • Pre-built Windows performance templates
  • Low-footprint agent deployment
  • Auto-registration of new servers

For large environments, consider this layered approach:

  1. Data Collection Layer: PowerShell + WMI for raw metrics
  2. Processing Layer: Telegraf for metrics aggregation
  3. Visualization Layer: Grafana dashboards with alert rules

# Sample Telegraf config
[[inputs.win_perf_counters]]
  Object = "Processor"
  Instances = ["_Total"]
  Counters = [
    "% Idle Time",
    "% Interrupt Time"
  ]
  Interval = "10s"
  • Audit existing Perfmon counters using Get-Counter -ListSet *
  • Document threshold values for critical metrics
  • Test backup/restore procedures before migration
  • Validate alert routing matches on-call rotations

Windows Performance Monitor (Perfmon) remains a powerful tool for tracking server metrics like CPU usage, memory allocation, and IIS request queues. However, as you've experienced, manually reconfiguring counters after reboots creates operational inefficiencies. Let's explore programmatic solutions.

PowerShell provides native access to performance counters through the System.Diagnostics.PerformanceCounter class. Here's a reusable script to automate counter setup:


# Save this as Configure-Perfmon.ps1
$counters = @(
    "\Processor(_Total)\% Processor Time",
    "\Memory\Available MBytes",
    "\Web Service(_Total)\Current Connections",
    "\SQLServer:Buffer Manager\Buffer cache hit ratio"
)

$dataCollectorSet = New-Object -ComObject PLA.DataCollectorSet
$dataCollectorSet.DisplayName = "Production_Server_Metrics"
$dataCollectorSet.Duration = 0  # Continuous collection

$dataCollector = $dataCollectorSet.DataCollectors.CreateDataCollector(0)
$dataCollector.FileName = "ServerMetrics_"
$dataCollector.FileNameFormat = 1  # yyyyMMdd format
$dataCollector.SampleInterval = 15  # Seconds

foreach ($counter in $counters) {
    $dataCollector.PerformanceCounters.Add($counter) | Out-Null
}

$dataCollectorSet.RootPath = "C:\PerfLogs\Admin\Production"
$dataCollectorSet.Commit("Production_Servers", $null, 0x0003) | Out-Null
$dataCollectorSet.Start($false)

For real-time visualization without manual configuration, consider these tools:

Prometheus + Grafana Stack


# Sample docker-compose.yml for Windows monitoring
version: '3'
services:
  prometheus:
    image: prom/prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml

  grafana:
    image: grafana/grafana
    ports:
      - "3000:3000"

Configure prometheus.yml to scrape Windows metrics using the WMI exporter:


scrape_configs:
  - job_name: 'windows'
    static_configs:
      - targets: ['wmi_exporter:9182']
    metrics_path: '/metrics'

Commercial Option: PRTG Network Monitor

PRTG offers preconfigured Windows server sensors including:

  • CPU Load (WMI)
  • Memory Usage (SNMP)
  • IIS Active Connections
  • SQL Server Deadlocks

Combine PowerShell logging with your existing Nagios setup:


# Log performance data to CSV
Get-Counter -Counter "\Processor(_Total)\% Processor Time" -SampleInterval 5 -MaxSamples 12 | 
Export-Counter -FileFormat CSV -Path "C:\Monitoring\CPU_Usage.csv"

# Threshold-based alerting
$cpu = (Get-Counter -Counter "\Processor(_Total)\% Processor Time").CounterSamples.CookedValue
if ($cpu -gt 90) {
    Send-MailMessage -To "noc@company.com" -Subject "CPU Alert" -Body "CPU at ${cpu}%"
}

When migrating from Perfmon:

  1. Document all currently monitored counters
  2. Test new tools in staging before production rollout
  3. Establish baseline performance metrics
  4. Configure equivalent alert thresholds