PowerShell Genie

Generate uptime report

Script 2 min read Windows PowerShell 5.1 and PowerShell 7

Documentation: Microsoft Learn

Query Win32_OperatingSystem on each computer and calculate uptime from LastBootUpTime. Check unreachable hosts before using the report.

The script

1PS> $Computers = "SRV01", "SRV02"
2PS> Get-CimInstance Win32_OperatingSystem -ComputerName $Computers | Select-Object CSName,@{ Name = "UptimeHours"; Expression = {(New-TimeSpan $_.LastBootUpTime (Get-Date)).TotalHours} }

Script reader

Inspect before you run

Inspection only

Inspect the script below. It does not run in this browser.

Inspection only — no command has run.

    Show reference output
    1 CSName UptimeHours
    2 ------ -----------
    3 SRV01 73.5
    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} }
    1. Stage 1$ComputersPositional values or no named parameters
    2. Stage 2Select-ObjectPositional 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.

      1. Filter the host list first with Test-NetConnection on port 5985 so unreachable targets never reach the query.
      2. Create sessions up front with New-CimSession and inspect which ones failed, separating connectivity from query problems.
      3. Add -OperationTimeoutSec to cap the wait per host rather than accepting the default.
      4. Check whether the failing hosts resolve at all, since a stale DNS record produces an identical symptom.
      5. 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.

      Primary documentation

      Get-CimInstance reference

      Continue
      Genie guideGenerate uptime report

      Query Win32_OperatingSystem on each computer and calculate uptime from LastBootUpTime. Check unreachable hosts before using the report.