Learn how to build a robust PowerShell monitoring and alerting system with practical examples. This guide covers what to monitor, how to set up alert rules, generate dashboards, and handle incident response using only PowerShell and native Windows tools.
Intro
PowerShell is a powerful tool for automating and managing Windows environments, but its true potential is unlocked when it is used for monitoring and alerting. By leveraging PowerShell's ability to query system information, parse logs, and send notifications, you can build a custom monitoring solution tailored to your needs without relying on expensive third-party tools. This guide provides practical, step-by-step instructions to set up monitoring for critical metrics, define alert rules, create dashboards, and handle incidents effectively. Whether you are a developer, DevOps consultant, or part of a technical startup team, you will learn how to implement a lightweight yet robust monitoring system using only PowerShell and native Windows features.
Version and Environment Inventory
Before implementing monitoring, establish a clear picture of your environment. This section outlines the prerequisites, the topology, and the PowerShell version required.
Prerequisites
- Windows 10/11 or Windows Server 2016 or later.
- PowerShell 5.1 or PowerShell 7.0+ (cross-platform).
- Administrative privileges for certain commands (e.g., accessing event logs, performance counters).
- Access to an SMTP server or a webhook endpoint (e.g., Slack, Teams) for alert delivery.
- A simple text editor or PowerShell ISE for scripting.
Checking PowerShell Version
Run the following to check your PowerShell version:
$PSVersionTable.PSVersion
Expected output example:
Major Minor Build Revision
----- ----- ----- --------
7 3 4 0
If you have an older version, consider upgrading to PowerShell 7 for better performance and features.
Environment Topology
A typical monitoring setup consists of:
- Monitored hosts: Machines whose metrics you want to track (e.g., CPU, memory, disk, services).
- Monitoring server: A central machine that collects data and sends alerts (could be one of the hosts).
- Alerting channel: Email, webhook, or log file for notifications.
For simplicity, this guide assumes a single Windows machine acting as both the monitored host and the monitoring server, but the concepts scale to multiple machines using PowerShell Remoting.
Safe Configuration Path
Implement monitoring in a scoped, controlled manner. Avoid global changes; use dedicated scripts and scheduled tasks. This approach minimizes risk and allows easy rollback.
Step 1: Create a Monitoring Folder
Create a dedicated folder for scripts, logs, and configuration:
New-Item -ItemType Directory -Path "C:\Monitoring" -Force
Step 2: Write a Reusable Monitoring Function
Create a function that checks a specific metric and returns a status object. Save as C:\Monitoring\Get-CpuUsage.ps1:
function Get-CpuUsage {
$cpu = Get-Counter '\Processor(_Total)\% Processor Time'
$cpuValue = $cpu.CounterSamples[0].CookedValue
[PSCustomObject]@{
Timestamp = Get-Date
Metric = 'CPU Usage'
Value = $cpuValue
Unit = '%'
Threshold = 80
Status = if ($cpuValue -gt 80) { 'Critical' } else { 'OK' }
}
}
This function reads the current CPU usage and compares it to a threshold.
Step 3: Configure Alert Rules
Create a script to evaluate the metric and send an alert if needed. Example: C:\Monitoring\Check-CpuAlert.ps1:
$result = Get-CpuUsage
if ($result.Status -eq 'Critical') {
$subject = "CPU Alert on $env:COMPUTERNAME"
$body = "CPU usage is $($result.Value)% (threshold: $($result.Threshold)%) at $($result.Timestamp)"
# Replace with your SMTP details
Send-MailMessage -To '[email protected]' -From '[email protected]' -Subject $subject -Body $body -SmtpServer 'smtp.example.com'
Write-Host "Alert sent: $subject"
} else {
Write-Host "CPU usage normal: $($result.Value)%"
}
Step 4: Schedule the Check
Use Task Scheduler to run the check every 5 minutes:
$action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument '-NoProfile -WindowStyle Hidden -File "C:\Monitoring\Check-CpuAlert.ps1"'
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 5)
Register-ScheduledTask -TaskName 'CPU Monitor' -Action $action -Trigger $trigger -Description 'Checks CPU usage and alerts if high' -User 'SYSTEM'
This creates a scheduled task that runs as SYSTEM.
Step 5: Implement Other Metrics
Repeat the pattern for other important metrics: memory usage, disk space, service status, etc. Create a modular approach with a main script that calls each check.
Verification and Diagnostics
After setting up monitoring, verify that it works as expected. Use these diagnostics to confirm data collection, alerting, and scheduling.
Verify CPU Usage Function
Run the function manually:
. .\Get-CpuUsage.ps1
Get-CpuUsage | Format-Table
Expected output:
Timestamp Metric Value Unit Threshold Status
--------- ------ ----- ---- --------- ------
10/25/2023 10:15:32 AM CPU Usage 23.5 % 80 OK
Test Alert Script
To test the alert without waiting for a real threshold breach, temporarily modify the threshold in the function or use a mock value. Ensure the script sends an email or writes to a log. For safer testing, replace the Send-MailMessage line with a Write-Host or Out-File to avoid spamming.
Check Scheduled Task
Verify the task is registered and its status:
Get-ScheduledTask -TaskName 'CPU Monitor'
Check last run result:
(Get-ScheduledTaskInfo -TaskName 'CPU Monitor').LastTaskResult
A result of 0 indicates success. To manually run the task:
Start-ScheduledTask -TaskName 'CPU Monitor'
Diagnostic Logging
Add logging to your scripts for troubleshooting. At the top of your script, redirect output to a log file:
Start-Transcript -Path "C:\Monitoring\log.txt" -Append
End with Stop-Transcript. Then inspect the log after running.
Failure Modes and Recovery
Even a simple monitoring setup can fail. Understand common failure modes and how to recover.
Failure: Scheduled Task Does Not Run
- Cause: Incorrect task configuration, insufficient permissions, or missing script file.
- Recovery: Check task status and history:
Get-ScheduledTask -TaskName 'CPU Monitor' | Get-ScheduledTaskInfo | Format-List *
Ensure the script path is correct. If wrong, update the action:
Set-ScheduledTask -TaskName 'CPU Monitor' -Action (New-ScheduledTaskAction -Execute 'powershell.exe' -Argument '-File "C:\Monitoring\Check-CpuAlert.ps1"')
Failure: Email Not Sent
- Cause: SMTP server unreachable, authentication required, or firewall block.
- Recovery: Test email manually:
Send-MailMessage -To '[email protected]' -From '[email protected]' -Subject 'Test' -Body 'Test' -SmtpServer 'smtp.example.com'
If it fails, check network connectivity and SMTP settings. Consider using a fallback like writing to a webhook or a file.
Failure: False Alerts or Missed Alerts
- Cause: Threshold set too low or high, or metric retrieval error.
- Recovery: Review collected values over time. Adjust thresholds in the function. Verify the metric retrieval works independently:
Get-Counter '\Processor(_Total)\% Processor Time'
Rollback Plan
To remove monitoring, delete the scheduled task and the monitoring folder:
Unregister-ScheduledTask -TaskName 'CPU Monitor' -Confirm:$false
Remove-Item -Path 'C:\Monitoring' -Recurse -Force
This completely removes the components.
Operations Checklist
Use this checklist for ongoing operations and reviews.
| Task | Frequency | Description |
|---|---|---|
| Review alert history | Weekly | Check logs and email sent items for alert frequency and false positives. |
| Verify scheduled tasks | Daily | Use Get-ScheduledTask to ensure monitoring tasks are enabled and have not failed. |
| Test alert delivery | Monthly | Send test alerts to confirm email or webhook channels are working. |
| Adjust thresholds | As needed | Based on observed baseline metrics, fine-tune thresholds to reduce noise. |
| Update scripts | When environment changes | Modify monitoring scripts if new services or servers are added. |
| Backup monitoring scripts | Before changes | Copy script folder to a backup location (e.g., C:\MonitoringBackup). |
Example: Reviewing Alert History
To show recent entries from the log file:
Get-Content 'C:\Monitoring\log.txt' -Tail 50
This displays the last 50 lines of the log for quick review.
Conclusion
PowerShell provides a flexible and cost-effective way to monitor your Windows environment and set up custom alerts. By following this guide, you have learned how to:
- Inventory your environment and confirm prerequisites.
- Create a safe, scoped monitoring configuration using scripts and scheduled tasks.
- Implement a CPU usage monitor with alerting as a template for other metrics.
- Verify the monitoring works through diagnostic checks.
- Handle common failure modes and rollback cleanly.
- Establish an operations checklist for ongoing maintenance.
As a next step, expand your monitoring to include memory, disk, and critical services. Use the same pattern to create additional checks and combine them into a single comprehensive monitoring script. Remember to start narrow and measurable, as a local pilot, before scaling to production. With these practical examples, you can build a reliable monitoring system tailored to your needs.