When performing endpoint performance monitoring, a baseline shows what “normal” looks like and serves as a reference against the current state. It helps IT teams spot early signs of degradation, capacity issues, or resource misuse. Built-in Windows tools can create this baseline at low cost and in any Windows environment.
This guide provides a step-by-step process for building an endpoint performance baseline using built-in Windows tools and PowerShell.
Steps to build an endpoint performance baseline using built-in Windows tools and PowerShell
Before starting, ensure the following requirements are in place:
📌 General prerequisites:
- PowerShell 5.1 or later
- Local admin rights to run performance queries and export results
- Optional: RMM or scripting platform (e.g., NinjaOne) for automation
- Clear definition of normal system behavior for each client or environment
Step 1: Define key performance metrics to baseline
To begin with, define the key performance metrics that will serve as the foundation for your baseline. Once you have identified all the metrics, you can easily gather the right and necessary data to build an accurate baseline.
📌 Use Cases: Useful for segmenting baselines, capacity planning, establishing SLA-driven thresholds, or creating a reliable reference for troubleshooting.
Step-by-step:
- Group endpoints into cohorts or by shared traits:
- Device type: Laptop, VM, or desktop
- User role: Sales, developers, servers
- Hardware tier: RAM size, storage type, CPU model
- OS version: Windows 10 22H2, Windows 11 23H2
- Select core metrics to track. Recommended metrics include:
- CPU utilization (average and peak)
- Memory usage (used vs total)
- Disk I/O (queue length, latency)
- Network activity (bytes sent/received)
- Boot time and uptime duration
- Service startup and load time
- Average process count and top consumers
- Set appropriate thresholds for each client, device role (workstation vs server), or SLA.
- Document the metrics by creating a baseline template that includes all the established values and parameters.
Step 2: Use PowerShell to collect and store performance data
After establishing your key performance metrics, it’s time to gather the detailed, real-time performance data you need. PowerShell is a powerful, built-in Windows tool for this purpose because it’s both scriptable and repeatable.
📌 Use Cases: Best for creating troubleshooting references and comparing before-and-after performance snapshots.
📌 Prerequisites:
- PowerShell 5.1 or later
- Administrator privileges
- Optional: RMM or scripting platform (e.g., NinjaOne) for automation
Step-by-step:
- Press Win + S, search for PowerShell, right-click it, and select Run as Administrator. (Read #1 in ⚠️ Things to look out for.)
- Capture a basic CPU and memory snapshot:
Get-CimInstance Win32_Processor | Select-Object LoadPercentageGet-CimInstance Win32_OperatingSystem | Select-Object FreePhysicalMemory, TotalVisibleMemorySize
(Also refer to Get-CimInstance in Microsoft Learn’s CimCmdlets.)
- Check boot time and uptime duration:
$boot = (Get-CimInstance Win32_OperatingSystem).LastBootUpTime$uptime = (Get-Date) - $boot
- Measure disk I/O using performance counters:
Get-Counter -Counter "\PhysicalDisk(_Total)\Avg. Disk Queue Length"
(Also refer to Get-Counter in Microsoft Learn’s Microsoft.PowerShell.Diagnostics Module.)
- Export results to CSV for historical tracking:
$report | Export-Csv -Path "C:\Performance\Baseline.csv" -NoTypeInformation
Step 3: Use CMD for quick checks and verification
To spot-check or validate what your PowerShell baseline is capturing, this method uses the Command Prompt (CMD) to run built-in commands to reveal system health and performance indicators. (Read #2 in ⚠️ Things to look out for.)
📌 Use Cases: Use this for fast manual verification or on-the-spot troubleshooting without running full scripts.
Step-by-step:
- Press Win + R, type cmd, and click Enter to launch the Command Prompt.
- Check CPU and memory usage:
tasklist /fo csv | findstr /i "chrome.exe"
- View system boot time and uptime:
systeminfo | findstr /B /C:"System Boot Time"
- List all running services:
sc query type= service state= all | findstr /C:"RUNNING"
💡 Tip: These outputs can be redirected to log files for future reference during baseline creation or troubleshooting.
Step 4: Store baseline indicators in the registry
This method lets you manually save key performance indicators from your baseline into the Windows Registry. It’s an efficient way to maintain a local record and quickly compare current readings against your established baseline.
📌 Use Cases: Ideal for baseline validation, change tracking, offline auditing, and RMM integration.
📌 Prerequisite: Administrator rights to write to HKEY_LOCAL_MACHINE
⚠️ Warning: Editing the registry can cause system issues. Create a backup before proceeding.
Step-by-step:
- Choose your Registry path: (Read #3 in ⚠️ Things to look out for.)
HKEY_LOCAL_MACHINE\SOFTWARE\Org\PerformanceBaseline
- Press Win + S, search for PowerShell, right-click it, and select Run as Administrator.
- Create the Registry key:
New-Item -Path "HKLM:\SOFTWARE\Org\PerformanceBaseline" -Force
- Write baseline values (replace the example numbers with your actual baseline results):
Set-ItemProperty -Path "HKLM:\SOFTWARE\Org\PerformanceBaseline" -Name "LastCPULoad" -Value 18 -Type DWordSet-ItemProperty -Path "HKLM:\SOFTWARE\Org\PerformanceBaseline" -Name "LastFreeMemoryMB" -Value 4023 -Type DWordSet-ItemProperty -Path "HKLM:\SOFTWARE\Org\PerformanceBaseline" -Name "LastUptimeHours" -Value 72 -Type DWordSet-ItemProperty -Path "HKLM:\SOFTWARE\Org\PerformanceBaseline" -Name "BaselineCaptured" -Value "2025-07-01T10:00Z" -Type String
- Use PowerShell scripts or RMM tools to regularly populate and verify these values, ensuring your baseline stays current.
Step 5: Schedule regular collection via Task Scheduler or RMM
To keep your baseline data current, this method uses Windows Task Scheduler or an RMM platform like NinjaOne to set up automated, recurring data collection.
📌 Use Cases: Use this for rolling baseline, fleet-wide automation, and proactive monitoring.
📌 Prerequisites:
- A working PowerShell script for baseline capture
- Administrator rights on the endpoint or domain
Instructions:
- Create a scheduled task with CMD.
Example: Schedule a daily baseline capture at 10:00 AM.
schtasks /create /tn "CapturePerformanceBaseline" /tr "powershell.exe -File C:\Scripts\Capture-Baseline.ps1" /sc daily /st 10:00
You may customize parameters:
/tn– Task name/tr– Program/script to run/sc– Schedule (use/sc weeklyfor weekly runs)/st– Start time
(Also refer to schtasks commands in Microsoft Learn’s Windows commands.)
- Use NinjaOne scripting and policy engine to:
- Schedule the script to run daily or weekly
- Upload results to the central repository or attach to a ticket
- Trigger alerts if performance deviates from the defined baseline
With this setup, you can automatically capture performance snapshots from every device daily, weekly, or according to your preferred time frame.
Step 6: Apply Group Policy for performance logging support
This method uses Group Policy Objects (GPOs) to enable and standardize system performance logging on domain-joined Windows devices.
📌 Use Cases: Ideal for organization-wide consistency, centralized performance analysis, and strict policy enforcement. This method is best suited for enterprise environments.
📌 Prerequisites:
- Active Directory domain with Group Policy Management Console (GPMC) installed
- Administrator rights to create or modify GPOs
- Predefined Performance Monitor (PerfMon) templates
Step-by-step:
- Press Win + R, type gpmc.msc, and click Enter to open the Group Policy Management Console (GPMC).
- Create a new GPO or edit an existing one linked to your target Organizational Unit (OU). (Read #4 in ⚠️ Things to look out for.)
- Navigate to:
Computer Configuration > Administrative Templates > System > Performance Logs and Alerts
- Turn on the required policies for performance data collection.
- Use Performance Monitor (PerfMon) templates to define:
- Data Collector Sets for CPU, disk, and memory
- Log retention and file size caps
- Output to shared folder or local disk
- Performance data will be stored in .blg (Binary Log) files. These files can be imported into Performance Monitor for review or used in Power BI for visualization and trend analysis.
This ensures that performance logs are always collected, even if a user never initiates a manual collection.
⚠️ Things to look out for
| Risks | Potential Consequences | Reversals |
| 1. Running PowerShell scripts without admin rights | The script may fail, or data collection may be incomplete | Relaunch PowerShell as Administrator and re-run the collection script |
| 2. Using CMD checks during high workload or maintenance | Results may be skewed and fail to reflect normal performance | Re-run CMD checks during idle periods or typical workload windows |
| 3. Incorrect registry path or insufficient permissions when storing values | Baseline data not written, making future comparisons impossible | Verify the registry path and run the script with elevated permissions |
| 4. Applying Group Policy to the wrong OU or without proper scoping | Policies may not be applied to intended devices or could be applied to unintended ones | Correct OU targeting, verify GPO scope, and force update with gpupdate /force |
Additional considerations
Here are a few extra factors that can influence the accuracy and reliability of your endpoint performance baseline:
Hardware consistency
A baseline from a high-end laptop will differ from one on a budget desktop or VM. Even within the same model line, older devices may show degraded performance. Mixing different hardware skews thresholds and can cause false alerts.
Group endpoints by device class and age, as outlined in Step 1. Keep baselines separate for each class, and always record hardware details in your baseline documentation.
Post-update validation
Major Windows or driver updates can affect boot times, resource usage, and background activity. Collect a new baseline after these updates and compare it to the previous one to ensure performance hasn’t declined.
User behavior impact
Baseline timing also matters. Results will differ if a baseline is taken when a user is on a video call or has 30 browser tabs open. Schedule baseline during known idle periods or typical workload times.
Multi-session support
In Remote Desktop Services (RDS) or Virtual Desktop Infrastructure (VDI), where multiple users share one host, profile performance per session and host. This is to ensure baselines reflect actual usage patterns and the impact of concurrent users.
Quick-Start Guide
NinjaOne offers several ways to build and monitor endpoint performance baselines:
1. System Performance Check Script
Script: How to Complete a System Performance Check with PowerShell which check:
– CPU usage
– Memory usage
– Disk performance
– Network performance
– Can collect data points every minute
– Supports collecting top 5 processes during performance data collection
– Allows saving results to a custom field
– Maximum collection time is 60 minutes
2. Built-in Performance Monitoring
– CPU and memory usage are monitored and reported on the device dashboard
– Provides real-time endpoint health and performance data
– Generates context-rich alerts
– Allows creation of custom alerts for performance issues
3. Performance-Related Conditions
– Can create custom conditions like Process Resource CPU condition
– Enables triggering alerts based on specific performance thresholds
Troubleshooting
Here are common issues you may encounter when building an endpoint performance baseline and how to resolve them:
PowerShell errors
The script may fail if it’s not run with the required privileges. Check permissions and ensure you’re running PowerShell as an Administrator.
Another possible cause is that the Windows Management Instrumentation (WMI) service is disabled or corrupted, as many performance metrics rely on it. Run this command to check if it’s running:
Get-Service winmgmt
Missing performance counters
Windows performance counters can sometimes be removed or corrupted, especially after updates or system changes. To rebuild them, run:
lodctr /r
High CPU during logging
Capturing too many counters at very short intervals can overload the system. Reduce the number of counters you are logging, increase the sample interval, or both to lower CPU usage during collection.
Registry keys not updating
Registry updates may fail if the script is not elevated or if the registry path is incorrect. Run the script as Administrator and confirm that the path is accurate:
HKLM:\SOFTWARE\Org\PerformanceBaseline
NinjaOne services
NinjaOne enhances endpoint performance baselining by:
| Capability | What NinjaOne enables |
| Scheduled script deployment | Deploying baseline collection scripts on schedule across devices. |
| Centralized performance data storage | Storing performance data as custom fields or logs for reporting. |
| Endpoint health tagging | Tagging endpoints based on performance health (e.g., High CPU, Low RAM). |
| Threshold deviation alerts | Alerting on threshold deviations based on baseline drift. |
| QBR & Audit integration | Integrating data into QBR and audit reports for clients. |
With NinjaOne, MSPs can build, maintain, and monitor performance baselines across all managed tenants.
Building baselines for effective endpoint performance monitoring
Building a performance baseline with built-in tools and PowerShell empowers MSPs to proactively detect issues, reduce support noise, and validate system health.
In this guide, you learned how to define key metrics to baseline on client endpoints, gather and log performance data using PowerShell and CMD commands, and apply persistent tracking using the Registry and GPO. Finally, it explored how NinjaOne can help automate and scale baseline tracking across clients to strengthen endpoint performance monitoring.
Related topics:
