Tested script

Last boot time and uptime report (PowerShell)

Shows when the computer last booted and how long it has been running, and warns if it has gone too long without a reboot. Handy after patching, when a machine claims it restarted but did not.

Tested

The script

<#
.SYNOPSIS
    Shows when this computer last booted and how long it has been up.
.DESCRIPTION
    On PowerShell 7 it uses Get-Uptime, which works on Windows, Linux and
    macOS. On Windows PowerShell 5.1 it falls back to the LastBootUpTime from
    CIM. Use -WarnAfterDays to flag machines that have not rebooted recently,
    for example after patching. Exits with code 2 when the warning is hit.
    Read-only.
.PARAMETER WarnAfterDays
    Flag the machine if it has been up longer than this many days. 0 turns
    the check off. Defaults to 30.
.EXAMPLE
    ./Get-UptimeReport.ps1
.EXAMPLE
    ./Get-UptimeReport.ps1 -WarnAfterDays 7
#>
[CmdletBinding()]
param(
    [ValidateRange(0, 3650)]
    [int]$WarnAfterDays = 30
)

if (Get-Command -Name Get-Uptime -ErrorAction SilentlyContinue) {
    $uptime = Get-Uptime
    $lastBoot = (Get-Date) - $uptime
}
else {
    # Windows PowerShell 5.1 has no Get-Uptime
    $lastBoot = (Get-CimInstance -ClassName Win32_OperatingSystem).LastBootUpTime
    $uptime = (Get-Date) - $lastBoot
}

$report = [PSCustomObject]@{
    Computer = [System.Environment]::MachineName
    LastBoot = $lastBoot.ToString('yyyy-MM-dd HH:mm')
    Uptime   = '{0}d {1}h {2}m' -f $uptime.Days, $uptime.Hours, $uptime.Minutes
    UpDays   = [math]::Round($uptime.TotalDays, 1)
}
# Format-List writes the report now; a bare $report can be lost when exit runs straight after it
$report | Format-List

if ($WarnAfterDays -gt 0 -and $uptime.TotalDays -gt $WarnAfterDays) {
    Write-Warning "Up for more than $WarnAfterDays days. A reboot may be overdue."
    exit 2
}
exit 0

Run it

./Get-UptimeReport.ps1
./Get-UptimeReport.ps1 -WarnAfterDays 7

How it works

Parameter

-WarnAfterDays is how long a machine may run before you want a warning. Set it to 0 to turn the check off.

Pick the right method

Get-Command -Name Get-Uptime checks whether the cmdlet exists. PowerShell 7 has it on every platform. Windows PowerShell 5.1 does not, so the else branch reads LastBootUpTime from the Win32_OperatingSystem CIM class instead. Either way you end up with two variables: the last boot time and the uptime as a timespan.

Build the report

A [PSCustomObject] holds the computer name, the boot time, a readable uptime such as 12d 4h 30m, and the uptime in days as a number you can sort or compare. It is piped to Format-List so it always prints before the script exits.

Warn and exit

If the machine has been up longer than -WarnAfterDays, the script writes a warning and exits with code 2. Otherwise it exits 0. That makes it easy to use in a scheduled task or a remote check.