How to Monitor Server Uptime With PowerShell

Overview

This guide shows how to monitor server uptime on Windows with pure PowerShell: ICMP ping reachability, optional HTTP health checks, OS-level uptime via CIM, CSV logging for Excel/BI, and lightweight webhook alerts for Teams/Slack.

Updated: October 01, 2025

1) Why PowerShell?

  • Built-in on Windows; zero agents and minimal dependencies.
  • Combines network reachability (ICMP/HTTP) with OS-level uptime via CIM/WMI.
  • Easy scheduling with Task Scheduler; outputs tidy CSV for Excel/Power BI.

2) Quick Start

Get-Uptime
Get-Uptime -Since   # last boot datetime (PowerShell 6+)

On Windows PowerShell 5.1, compute uptime from CIM:

Get-CimInstance Win32_OperatingSystem |
  Select @{{n='LastBoot';e={[Management.ManagementDateTimeConverter]::ToDateTime($_.LastBootUpTime)}},
         @{{n='UptimeHours';e={{(Get-Date) - [Management.ManagementDateTimeConverter]::ToDateTime($_.LastBootUpTime) | % TotalHours}}}}

3) What to Check

  • ICMP Ping — server reachable? Test-Connection SERVER -Count 1 -Quiet
  • TCP/Port — service port open? Test-NetConnection SERVER -Port 443
  • HTTP(S) — app returns 200–399? Invoke-WebRequest https://app/health -Method Head
  • Uptime — last boot & elapsed (CIM or Get-Uptime -Since)

4) Production-Ready Mini Script

Download the ready-to-run script and sample files:

Schedule every 5 minutes. It logs CSV and can notify a Teams/Slack webhook on DOWN or recent reboot.

5) Visuals

Uptime time-series line chart
Figure 1 — Uptime % over the last 14 days.
Incidents by type bar chart
Figure 2 — Incidents grouped by type (synthetic example).
PowerShell run sample output
Figure 3 — Sample console output: ping, uptime, alerts.

6) Scheduling

$action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument '-NoProfile -ExecutionPolicy Bypass -File "C:\Path\Monitor-Uptime.ps1"'
$trigger = New-ScheduledTaskTrigger -Once (Get-Date).AddMinutes(1) -RepetitionInterval (New-TimeSpan -Minutes 5) -RepetitionDuration ([TimeSpan]::MaxValue)
Register-ScheduledTask -TaskName 'UptimeMonitor' -Action $action -Trigger $trigger

7) Forensics via Event Logs

Filter classic reboot root-cause IDs (41, 6008, 1074, 6005, 6006):

$since = (Get-Date).AddDays(-7)
Get-WinEvent -FilterHashtable @{{LogName='System'; StartTime=$since; Id=@(41,1074,6005,6006,6008)}} |
  Select TimeCreated, Id, ProviderName, LevelDisplayName, Message

8) FAQ

  • Ping blocked? Use Test-NetConnection for TCP or Invoke-WebRequest for HTTP health instead.
  • No Get-Uptime on 5.1? Use CIM: Get-CimInstance Win32_OperatingSystem and compute from LastBootUpTime.