Monitor Your System Health with a Custom PowerShell Dashboard
Your computer has been acting slow lately. Is it the CPU? Memory? A runaway process? Low disk space? Instead of opening Task Manager, Resource Monitor, and Disk Management separately, what if you had one command that showed you everything?
Today we're building a PowerShell system health dashboard that gives you instant visibility into your computer's vital signs. One command, all the information you need.
What You'll Learn
- How to query CPU, memory, and disk metrics in PowerShell
- Building a formatted, color-coded health dashboard
- Setting up alerts for critical thresholds
- Monitoring Windows services and processes
- Creating a continuous monitoring mode
Prerequisites
- Windows 10/11 with PowerShell 5.1+
- No additional modules required (uses built-in cmdlets)
- Administrator rights for full service monitoring
The Manual Pain
When something feels wrong with your system, the investigation usually goes like this:
- Open Task Manager, stare at CPU graph
- Sort by memory usage, hunt for memory hogs
- Open This PC, check each drive's free space
- Open Services, scroll through hundreds of entries
- Check Event Viewer for errors
- Google the symptoms because none of that helped
What if instead you could type one command and get a clear picture of your system's health?
The Automated Solution
Our dashboard will show:
- System overview: Uptime, OS version, hostname
- CPU status: Current usage and top processes
- Memory status: Used/free RAM with percentage
- Disk status: Space on all drives with warnings
- Service status: Critical services health check
- Network status: Connection state and IP info
Step 1: Gathering System Information
Let's start by collecting basic system information:
1function Get-SystemOverview {2 $os = Get-CimInstance Win32_OperatingSystem3 $cs = Get-CimInstance Win32_ComputerSystem45 # Calculate uptime6 $uptime = (Get-Date) - $os.LastBootUpTime7 $uptimeString = "{0} days, {1} hours, {2} minutes" -f $uptime.Days, $uptime.Hours, $uptime.Minutes89 return [PSCustomObject]@{10 ComputerName = $cs.Name11 OS = $os.Caption12 OSVersion = $os.Version13 Architecture = $os.OSArchitecture14 LastBoot = $os.LastBootUpTime15 Uptime = $uptimeString16 TotalRAM = [math]::Round($cs.TotalPhysicalMemory / 1GB, 2)17 }18}
This gives us the foundationβknowing what system we're looking at and how long it's been running.
Step 2: Monitoring CPU Usage
CPU monitoring tells us if the processor is being overwhelmed:
1function Get-CPUStatus {2 # Get overall CPU usage3 $cpuUsage = (Get-CimInstance Win32_Processor | Measure-Object -Property LoadPercentage -Average).Average45 # Get top CPU-consuming processes6 $topProcesses = Get-Process |7 Where-Object { $_.CPU -gt 0 } |8 Sort-Object CPU -Descending |9 Select-Object -First 5 Name,10 @{N='CPU(s)';E={[math]::Round($_.CPU, 2)}},11 @{N='Memory(MB)';E={[math]::Round($_.WorkingSet64 / 1MB, 2)}}1213 # Determine status14 $status = if ($cpuUsage -lt 50) { "Healthy" }15 elseif ($cpuUsage -lt 80) { "Elevated" }16 else { "Critical" }1718 return [PSCustomObject]@{19 UsagePercent = [math]::Round($cpuUsage, 1)20 Status = $status21 TopProcesses = $topProcesses22 }23}
The function not only reports CPU percentage but also identifies which processes are consuming the most resources.
Step 3: Monitoring Memory
Memory pressure is a common cause of system slowdowns:
1function Get-MemoryStatus {2 $os = Get-CimInstance Win32_OperatingSystem34 $totalMemory = $os.TotalVisibleMemorySize / 1MB # Convert KB to GB5 $freeMemory = $os.FreePhysicalMemory / 1MB6 $usedMemory = $totalMemory - $freeMemory7 $usedPercent = [math]::Round(($usedMemory / $totalMemory) * 100, 1)89 # Get top memory consumers10 $topMemory = Get-Process |11 Sort-Object WorkingSet64 -Descending |12 Select-Object -First 5 Name,13 @{N='Memory(MB)';E={[math]::Round($_.WorkingSet64 / 1MB, 2)}},14 @{N='Memory(GB)';E={[math]::Round($_.WorkingSet64 / 1GB, 2)}}1516 $status = if ($usedPercent -lt 70) { "Healthy" }17 elseif ($usedPercent -lt 90) { "Elevated" }18 else { "Critical" }1920 return [PSCustomObject]@{21 TotalGB = [math]::Round($totalMemory, 2)22 UsedGB = [math]::Round($usedMemory, 2)23 FreeGB = [math]::Round($freeMemory, 2)24 UsedPercent = $usedPercent25 Status = $status26 TopConsumers = $topMemory27 }28}
Step 4: Monitoring Disk Space
Low disk space causes all sorts of problems, from failed updates to application crashes:
1function Get-DiskStatus {2 $disks = Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" | ForEach-Object {3 $totalGB = [math]::Round($_.Size / 1GB, 2)4 $freeGB = [math]::Round($_.FreeSpace / 1GB, 2)5 $usedGB = $totalGB - $freeGB6 $freePercent = if ($totalGB -gt 0) { [math]::Round(($freeGB / $totalGB) * 100, 1) } else { 0 }78 $status = if ($freePercent -gt 20) { "Healthy" }9 elseif ($freePercent -gt 10) { "Warning" }10 else { "Critical" }1112 [PSCustomObject]@{13 Drive = $_.DeviceID14 Label = $_.VolumeName15 TotalGB = $totalGB16 UsedGB = $usedGB17 FreeGB = $freeGB18 FreePercent = $freePercent19 Status = $status20 }21 }2223 return $disks24}
Step 5: Monitoring Critical Services
Some Windows services are essentialβif they stop, things break:
1function Get-ServiceStatus {2 # Define critical services to monitor3 $criticalServices = @(4 @{Name = "wuauserv"; Display = "Windows Update"},5 @{Name = "WinDefend"; Display = "Windows Defender"},6 @{Name = "Spooler"; Display = "Print Spooler"},7 @{Name = "BITS"; Display = "Background Intelligent Transfer"},8 @{Name = "W32Time"; Display = "Windows Time"},9 @{Name = "Dhcp"; Display = "DHCP Client"},10 @{Name = "Dnscache"; Display = "DNS Client"},11 @{Name = "EventLog"; Display = "Windows Event Log"}12 )1314 $serviceStatus = foreach ($svc in $criticalServices) {15 $service = Get-Service -Name $svc.Name -ErrorAction SilentlyContinue1617 if ($service) {18 $status = if ($service.Status -eq "Running") { "Running" }19 elseif ($service.Status -eq "Stopped") { "Stopped" }20 else { $service.Status.ToString() }2122 [PSCustomObject]@{23 Name = $svc.Display24 ServiceName = $svc.Name25 Status = $status26 StartType = $service.StartType.ToString()27 }28 }29 else {30 [PSCustomObject]@{31 Name = $svc.Display32 ServiceName = $svc.Name33 Status = "Not Found"34 StartType = "N/A"35 }36 }37 }3839 return $serviceStatus40}
Step 6: Building the Dashboard Display
Now let's create a beautiful, color-coded dashboard output:
1function Show-Dashboard {2 param (3 [PSCustomObject]$System,4 [PSCustomObject]$CPU,5 [PSCustomObject]$Memory,6 [array]$Disks,7 [array]$Services8 )910 Clear-Host1112 # Helper function for colored status13 function Write-Status {14 param ([string]$Status)15 switch ($Status) {16 "Healthy" { Write-Host $Status -ForegroundColor Green -NoNewline }17 "Running" { Write-Host $Status -ForegroundColor Green -NoNewline }18 "Elevated" { Write-Host $Status -ForegroundColor Yellow -NoNewline }19 "Warning" { Write-Host $Status -ForegroundColor Yellow -NoNewline }20 "Critical" { Write-Host $Status -ForegroundColor Red -NoNewline }21 "Stopped" { Write-Host $Status -ForegroundColor Red -NoNewline }22 default { Write-Host $Status -ForegroundColor Gray -NoNewline }23 }24 }2526 # Header27 Write-Host "`n"28 Write-Host "ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ" -ForegroundColor Cyan29 Write-Host "β SYSTEM HEALTH DASHBOARD β" -ForegroundColor Cyan30 Write-Host "β $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') β" -ForegroundColor Cyan31 Write-Host "ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ" -ForegroundColor Cyan3233 # System Overview34 Write-Host "`nββ SYSTEM OVERVIEW βββββββββββββββββββββββββββββββββββββββββββββββββ" -ForegroundColor White35 Write-Host "β Computer: $($System.ComputerName)" -ForegroundColor White36 Write-Host "β OS: $($System.OS) ($($System.Architecture))" -ForegroundColor White37 Write-Host "β Uptime: $($System.Uptime)" -ForegroundColor White38 Write-Host "ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ" -ForegroundColor White3940 # CPU Status41 Write-Host "`nββ CPU STATUS ββββββββββββββββββββββββββββββββββββββββββββββββββββββ" -ForegroundColor White42 Write-Host -NoNewline "β Usage: $($CPU.UsagePercent)% - Status: "43 Write-Status $CPU.Status44 Write-Host ""45 Write-Host "β" -ForegroundColor White46 Write-Host "β Top CPU Processes:" -ForegroundColor White47 foreach ($proc in $CPU.TopProcesses) {48 Write-Host "β $($proc.Name): $($proc.'CPU(s)')s CPU, $($proc.'Memory(MB)')MB RAM" -ForegroundColor Gray49 }50 Write-Host "ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ" -ForegroundColor White5152 # Memory Status53 Write-Host "`nββ MEMORY STATUS βββββββββββββββββββββββββββββββββββββββββββββββββββ" -ForegroundColor White54 Write-Host -NoNewline "β Used: $($Memory.UsedGB)GB / $($Memory.TotalGB)GB ($($Memory.UsedPercent)%) - Status: "55 Write-Status $Memory.Status56 Write-Host ""57 Write-Host "β Free: $($Memory.FreeGB)GB available" -ForegroundColor White58 Write-Host "β" -ForegroundColor White59 Write-Host "β Top Memory Consumers:" -ForegroundColor White60 foreach ($proc in $Memory.TopConsumers) {61 Write-Host "β $($proc.Name): $($proc.'Memory(MB)')MB" -ForegroundColor Gray62 }63 Write-Host "ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ" -ForegroundColor White6465 # Disk Status66 Write-Host "`nββ DISK STATUS βββββββββββββββββββββββββββββββββββββββββββββββββββββ" -ForegroundColor White67 foreach ($disk in $Disks) {68 Write-Host -NoNewline "β $($disk.Drive) "69 if ($disk.Label) { Write-Host -NoNewline "($($disk.Label)) " }70 Write-Host -NoNewline "- $($disk.FreeGB)GB free of $($disk.TotalGB)GB ($($disk.FreePercent)% free) - "71 Write-Status $disk.Status72 Write-Host ""73 }74 Write-Host "ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ" -ForegroundColor White7576 # Service Status77 Write-Host "`nββ CRITICAL SERVICES βββββββββββββββββββββββββββββββββββββββββββββββ" -ForegroundColor White78 foreach ($svc in $Services) {79 Write-Host -NoNewline "β $($svc.Name): "80 Write-Status $svc.Status81 Write-Host ""82 }83 Write-Host "ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ" -ForegroundColor White8485 Write-Host ""86}
The Complete Script
Here's the full, production-ready script:
1<#2.SYNOPSIS3 Displays a comprehensive system health dashboard in PowerShell.45.DESCRIPTION6 This script monitors and displays:7 - System information and uptime8 - CPU usage and top processes9 - Memory usage and top consumers10 - Disk space on all drives11 - Critical Windows services status1213 Supports continuous monitoring mode with configurable refresh.1415.PARAMETER Continuous16 Run in continuous monitoring mode (refreshes automatically).1718.PARAMETER RefreshSeconds19 Seconds between refreshes in continuous mode. Default: 52021.PARAMETER ExportPath22 Export results to a JSON file at this path.2324.EXAMPLE25 .\SystemHealth.ps126 Display the dashboard once.2728.EXAMPLE29 .\SystemHealth.ps1 -Continuous30 Run continuous monitoring (Ctrl+C to stop).3132.EXAMPLE33 .\SystemHealth.ps1 -Continuous -RefreshSeconds 1034 Continuous monitoring with 10-second refresh.3536.NOTES37 Author: Chris Anderson38 Date: 2025-11-1839 Version: 1.040 Requires: PowerShell 5.1 or higher41#>4243[CmdletBinding()]44param (45 [Parameter(Mandatory = $false)]46 [switch]$Continuous,4748 [Parameter(Mandatory = $false)]49 [ValidateRange(1, 300)]50 [int]$RefreshSeconds = 5,5152 [Parameter(Mandatory = $false)]53 [string]$ExportPath54)5556# ============================================================================57# Functions58# ============================================================================5960function Get-SystemOverview {61 $os = Get-CimInstance Win32_OperatingSystem62 $cs = Get-CimInstance Win32_ComputerSystem6364 $uptime = (Get-Date) - $os.LastBootUpTime65 $uptimeString = "{0}d {1}h {2}m" -f $uptime.Days, $uptime.Hours, $uptime.Minutes6667 return [PSCustomObject]@{68 ComputerName = $cs.Name69 OS = $os.Caption70 OSVersion = $os.Version71 Architecture = $os.OSArchitecture72 LastBoot = $os.LastBootUpTime73 Uptime = $uptimeString74 TotalRAM = [math]::Round($cs.TotalPhysicalMemory / 1GB, 2)75 }76}7778function Get-CPUStatus {79 $cpuUsage = (Get-CimInstance Win32_Processor |80 Measure-Object -Property LoadPercentage -Average).Average8182 $topProcesses = Get-Process |83 Where-Object { $_.CPU -gt 0 } |84 Sort-Object CPU -Descending |85 Select-Object -First 5 Name,86 @{N='CPU(s)';E={[math]::Round($_.CPU, 2)}},87 @{N='Memory(MB)';E={[math]::Round($_.WorkingSet64 / 1MB, 2)}}8889 $status = if ($cpuUsage -lt 50) { "Healthy" }90 elseif ($cpuUsage -lt 80) { "Elevated" }91 else { "Critical" }9293 return [PSCustomObject]@{94 UsagePercent = [math]::Round($cpuUsage, 1)95 Status = $status96 TopProcesses = $topProcesses97 }98}99100function Get-MemoryStatus {101 $os = Get-CimInstance Win32_OperatingSystem102103 $totalMemory = $os.TotalVisibleMemorySize / 1MB104 $freeMemory = $os.FreePhysicalMemory / 1MB105 $usedMemory = $totalMemory - $freeMemory106 $usedPercent = [math]::Round(($usedMemory / $totalMemory) * 100, 1)107108 $topMemory = Get-Process |109 Sort-Object WorkingSet64 -Descending |110 Select-Object -First 5 Name,111 @{N='Memory(MB)';E={[math]::Round($_.WorkingSet64 / 1MB, 2)}}112113 $status = if ($usedPercent -lt 70) { "Healthy" }114 elseif ($usedPercent -lt 90) { "Elevated" }115 else { "Critical" }116117 return [PSCustomObject]@{118 TotalGB = [math]::Round($totalMemory, 2)119 UsedGB = [math]::Round($usedMemory, 2)120 FreeGB = [math]::Round($freeMemory, 2)121 UsedPercent = $usedPercent122 Status = $status123 TopConsumers = $topMemory124 }125}126127function Get-DiskStatus {128 $disks = Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" | ForEach-Object {129 $totalGB = [math]::Round($_.Size / 1GB, 2)130 $freeGB = [math]::Round($_.FreeSpace / 1GB, 2)131 $usedGB = $totalGB - $freeGB132 $freePercent = if ($totalGB -gt 0) {133 [math]::Round(($freeGB / $totalGB) * 100, 1)134 } else { 0 }135136 $status = if ($freePercent -gt 20) { "Healthy" }137 elseif ($freePercent -gt 10) { "Warning" }138 else { "Critical" }139140 [PSCustomObject]@{141 Drive = $_.DeviceID142 Label = $_.VolumeName143 TotalGB = $totalGB144 UsedGB = $usedGB145 FreeGB = $freeGB146 FreePercent = $freePercent147 Status = $status148 }149 }150151 return $disks152}153154function Get-ServiceStatus {155 $criticalServices = @(156 @{Name = "wuauserv"; Display = "Windows Update"},157 @{Name = "WinDefend"; Display = "Windows Defender"},158 @{Name = "Spooler"; Display = "Print Spooler"},159 @{Name = "BITS"; Display = "Background Transfer"},160 @{Name = "Dhcp"; Display = "DHCP Client"},161 @{Name = "Dnscache"; Display = "DNS Client"},162 @{Name = "EventLog"; Display = "Event Log"}163 )164165 $serviceStatus = foreach ($svc in $criticalServices) {166 $service = Get-Service -Name $svc.Name -ErrorAction SilentlyContinue167168 if ($service) {169 [PSCustomObject]@{170 Name = $svc.Display171 ServiceName = $svc.Name172 Status = $service.Status.ToString()173 StartType = $service.StartType.ToString()174 }175 }176 else {177 [PSCustomObject]@{178 Name = $svc.Display179 ServiceName = $svc.Name180 Status = "Not Found"181 StartType = "N/A"182 }183 }184 }185186 return $serviceStatus187}188189function Show-Dashboard {190 param (191 [PSCustomObject]$System,192 [PSCustomObject]$CPU,193 [PSCustomObject]$Memory,194 [array]$Disks,195 [array]$Services196 )197198 Clear-Host199200 function Write-Status {201 param ([string]$Status)202 switch ($Status) {203 "Healthy" { Write-Host $Status -ForegroundColor Green -NoNewline }204 "Running" { Write-Host $Status -ForegroundColor Green -NoNewline }205 "Elevated" { Write-Host $Status -ForegroundColor Yellow -NoNewline }206 "Warning" { Write-Host $Status -ForegroundColor Yellow -NoNewline }207 "Critical" { Write-Host $Status -ForegroundColor Red -NoNewline }208 "Stopped" { Write-Host $Status -ForegroundColor Red -NoNewline }209 default { Write-Host $Status -ForegroundColor Gray -NoNewline }210 }211 }212213 # Header214 Write-Host ""215 Write-Host " ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ" -ForegroundColor Cyan216 Write-Host " β SYSTEM HEALTH DASHBOARD β" -ForegroundColor Cyan217 Write-Host " β $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') β" -ForegroundColor Cyan218 Write-Host " ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ" -ForegroundColor Cyan219220 # System Overview221 Write-Host ""222 Write-Host " ββ SYSTEM βββββββββββββββββββββββββββββββββββββββββββββββββββββββ" -ForegroundColor White223 Write-Host " β $($System.ComputerName) | $($System.OS)" -ForegroundColor White224 Write-Host " β Uptime: $($System.Uptime) | RAM: $($System.TotalRAM)GB" -ForegroundColor Gray225 Write-Host " βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ" -ForegroundColor White226227 # CPU Status228 Write-Host ""229 Write-Host " ββ CPU ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ" -ForegroundColor White230 Write-Host -NoNewline " β Usage: $($CPU.UsagePercent)% ["231232 # Progress bar233 $barLength = 30234 $filled = [math]::Round(($CPU.UsagePercent / 100) * $barLength)235 $empty = $barLength - $filled236 $barColor = if ($CPU.UsagePercent -lt 50) { "Green" }237 elseif ($CPU.UsagePercent -lt 80) { "Yellow" }238 else { "Red" }239 Write-Host ("β" * $filled) -ForegroundColor $barColor -NoNewline240 Write-Host ("β" * $empty) -ForegroundColor DarkGray -NoNewline241 Write-Host "] "242243 Write-Host " β Top: $($CPU.TopProcesses[0].Name) ($($CPU.TopProcesses[0].'CPU(s)')s)" -ForegroundColor Gray244 Write-Host " βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ" -ForegroundColor White245246 # Memory Status247 Write-Host ""248 Write-Host " ββ MEMORY βββββββββββββββββββββββββββββββββββββββββββββββββββββββ" -ForegroundColor White249 Write-Host -NoNewline " β Used: $($Memory.UsedGB)GB / $($Memory.TotalGB)GB ["250251 $filled = [math]::Round(($Memory.UsedPercent / 100) * $barLength)252 $empty = $barLength - $filled253 $barColor = if ($Memory.UsedPercent -lt 70) { "Green" }254 elseif ($Memory.UsedPercent -lt 90) { "Yellow" }255 else { "Red" }256 Write-Host ("β" * $filled) -ForegroundColor $barColor -NoNewline257 Write-Host ("β" * $empty) -ForegroundColor DarkGray -NoNewline258 Write-Host "] $($Memory.UsedPercent)%"259260 Write-Host " β Free: $($Memory.FreeGB)GB | Top: $($Memory.TopConsumers[0].Name)" -ForegroundColor Gray261 Write-Host " βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ" -ForegroundColor White262263 # Disk Status264 Write-Host ""265 Write-Host " ββ DISKS ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ" -ForegroundColor White266 foreach ($disk in $Disks) {267 $usedPercent = 100 - $disk.FreePercent268 $filled = [math]::Round(($usedPercent / 100) * 20)269 $empty = 20 - $filled270 $barColor = if ($disk.FreePercent -gt 20) { "Green" }271 elseif ($disk.FreePercent -gt 10) { "Yellow" }272 else { "Red" }273274 Write-Host -NoNewline " β $($disk.Drive) ["275 Write-Host ("β" * $filled) -ForegroundColor $barColor -NoNewline276 Write-Host ("β" * $empty) -ForegroundColor DarkGray -NoNewline277 Write-Host "] $($disk.FreeGB)GB free ($($disk.FreePercent)%)"278 }279 Write-Host " βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ" -ForegroundColor White280281 # Services282 Write-Host ""283 Write-Host " ββ SERVICES βββββββββββββββββββββββββββββββββββββββββββββββββββββ" -ForegroundColor White284 $running = ($Services | Where-Object { $_.Status -eq "Running" }).Count285 $total = $Services.Count286 $stopped = ($Services | Where-Object { $_.Status -eq "Stopped" })287288 Write-Host " β Running: $running/$total critical services" -ForegroundColor Green289290 if ($stopped.Count -gt 0) {291 Write-Host " β Stopped: $($stopped.Name -join ', ')" -ForegroundColor Red292 }293 Write-Host " βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ" -ForegroundColor White294295 Write-Host ""296}297298function Export-HealthData {299 param (300 [string]$Path,301 [PSCustomObject]$System,302 [PSCustomObject]$CPU,303 [PSCustomObject]$Memory,304 [array]$Disks,305 [array]$Services306 )307308 $data = @{309 Timestamp = Get-Date -Format "o"310 System = $System311 CPU = @{312 UsagePercent = $CPU.UsagePercent313 Status = $CPU.Status314 }315 Memory = @{316 TotalGB = $Memory.TotalGB317 UsedGB = $Memory.UsedGB318 FreeGB = $Memory.FreeGB319 UsedPercent = $Memory.UsedPercent320 Status = $Memory.Status321 }322 Disks = $Disks323 Services = $Services324 }325326 $data | ConvertTo-Json -Depth 5 | Out-File -FilePath $Path -Encoding UTF8327}328329# ============================================================================330# Main Execution331# ============================================================================332333do {334 # Gather all metrics335 $system = Get-SystemOverview336 $cpu = Get-CPUStatus337 $memory = Get-MemoryStatus338 $disks = Get-DiskStatus339 $services = Get-ServiceStatus340341 # Display dashboard342 Show-Dashboard -System $system -CPU $cpu -Memory $memory -Disks $disks -Services $services343344 # Export if requested345 if ($ExportPath) {346 Export-HealthData -Path $ExportPath -System $system -CPU $cpu `347 -Memory $memory -Disks $disks -Services $services348 Write-Host " Data exported to: $ExportPath" -ForegroundColor Gray349 }350351 if ($Continuous) {352 Write-Host " Press Ctrl+C to stop. Refreshing in $RefreshSeconds seconds..." -ForegroundColor DarkGray353 Start-Sleep -Seconds $RefreshSeconds354 }355356} while ($Continuous)
How to Run This Script
Method 1: Single Check
1# Run once to see current status2.\SystemHealth.ps134# Export results to JSON5.\SystemHealth.ps1 -ExportPath "C:\Logs\health.json"
Method 2: Continuous Monitoring
1# Monitor with default 5-second refresh2.\SystemHealth.ps1 -Continuous34# Custom refresh rate5.\SystemHealth.ps1 -Continuous -RefreshSeconds 1067# Press Ctrl+C to stop
Method 3: Quick Function
Add this to your PowerShell profile for instant access:
1# Add to $PROFILE2function health { & "C:\Scripts\SystemHealth.ps1" }3function healthmon { & "C:\Scripts\SystemHealth.ps1" -Continuous }
Now just type health or healthmon anytime!
Customization Options
| Parameter | Default | Description |
|---|---|---|
| Continuous | $false | Enable auto-refresh mode |
| RefreshSeconds | 5 | Seconds between refreshes |
| ExportPath | (none) | Save results to JSON file |
Adding Custom Services
Edit the $criticalServices array to monitor services important to you:
1# Add SQL Server2@{Name = "MSSQLSERVER"; Display = "SQL Server"},34# Add IIS5@{Name = "W3SVC"; Display = "IIS Web Server"},
Security Considerations
β οΈ Important notes:
- This script only reads system informationβit doesn't modify anything
- No administrator rights needed for basic monitoring
- Some service queries may require elevation for full details
- Export files may contain system detailsβsecure them appropriately
- Safe to run on production systems
Common Issues & Solutions
| Issue | Cause | Solution |
|---|---|---|
| CPU shows 0% | WMI query timing | Run again; first query can be stale |
| Services show "Not Found" | Service not installed | Normalβnot all services exist on all systems |
| Memory numbers seem off | Caching and buffers | Windows uses available RAM for caching |
| Continuous mode flickers | Fast refresh | Increase RefreshSeconds |
Taking It Further
Enhance the dashboard with these features:
- Network monitoring: Add bandwidth usage and connection status
- Event log alerts: Show recent errors from Windows logs
- Temperature monitoring: Add CPU/GPU temps (requires additional tools)
- Email alerts: Send notifications when thresholds are exceeded
- Historical tracking: Store metrics over time for trend analysis
- Remote monitoring: Check multiple computers from one console
Conclusion
You now have a powerful system health dashboard that gives you instant visibility into your computer's vital signs. No more clicking through multiple tools or wondering why things feel slow.
The beauty of this script is its simplicityβone command shows you everything. Run it when something feels off, or keep it running in continuous mode on a second monitor. Either way, you'll always know exactly what your system is doing.
This is the kind of tool that system administrators have been building for decades. Now you have one too, customized to your needs and ready to extend.
Your system has no more secrets. Happy monitoring!
Sponsored Content
Interested in advertising? Reach automation professionals through our platform.
