Generate uptime report
Documentation: Microsoft Learn
Query Win32_OperatingSystem on each computer and calculate uptime from LastBootUpTime. Check unreachable hosts before using the report.
The script
Script reader
Inspect before you run
Inspect the script below. It does not run in this browser.
Inspection only — no command has run.
Show reference output
Inspect this example’s structure
Read the command and its supplied arguments. This example requires real PowerShell or its module; this diagram does not execute it.
$Computers = "SRV01", "SRV02"
Get-CimInstance Win32_OperatingSystem -ComputerName $Computers | Select-Object CSName,@{ Name = "UptimeHours"; Expression = {(New-TimeSpan $_.LastBootUpTime (Get-Date)).TotalHours} }- Stage 1$Computers
Positional values or no named parameters - Stage 2Select-Object
Positional values or no named parameters
How it works
Query Win32_OperatingSystem on each computer and calculate uptime from LastBootUpTime. Check unreachable hosts before using the report. A calculated property named UptimeHours feeds LastBootUpTime and the current time into New-TimeSpan and reads TotalHours off the resulting span. CSName travels with each row so the output identifies its own source without a separate join.
Adapting it
Wrap the TotalHours expression in [math]::Round, or divide by 24 for a days column. Piping into Where-Object UptimeHours -gt 720 turns the report into a list of hosts overdue for a restart.
Requirements
WinRM reachable on every target plus rights to query CIM remotely.
If the result is unexpected
Some hosts return an uptime figure while others produce a connection error, and the whole command takes minutes to finish.
Passing -ComputerName opens a WS-Management connection per host, so any target with WinRM stopped or firewalled fails individually after burning the full timeout. Those failures are non-terminating, which is why partial output arrives mixed in with a stack of red text. A name that does not resolve fails the same way for an entirely different reason.
- Filter the host list first with Test-NetConnection on port 5985 so unreachable targets never reach the query.
- Create sessions up front with New-CimSession and inspect which ones failed, separating connectivity from query problems.
- Add -OperationTimeoutSec to cap the wait per host rather than accepting the default.
- Check whether the failing hosts resolve at all, since a stale DNS record produces an identical symptom.
- Run against a small known-good subset first to confirm the syntax before blaming the environment.
Validate the result
Every host in the filtered list returns a CSName with an UptimeHours value, and no error records appear in the output.
Keep the check reliable
Build the target list from something authoritative rather than a static array, and pre-test reachability so a report does not spend its runtime waiting on decommissioned hosts.