To effortlessly retrieve the device’s uptime, indicating the time of its last reboot, execute the command provided below:
Get-ciminstance Win32_OperatingSystem | Select -Exp LastBootUpTime
Furthermore, there exist notification messages, known as toasts, that prompt users to initiate a reboot via this approach.
This method operates seamlessly unless a certain scenario unfolds…
When does the issue arise?
The complication arises when fast startup is activated on the device and the user opts for a device shutdown instead of a reboot.
Upon restarting, a toast notification informs the user that their device hasn’t undergone a reboot for a specific duration, often indicating the date of the last reboot.
This situation can become particularly vexing if the user receives scheduled toast notifications, as they may not discern between a reboot and a shutdown.
So, what’s the crux of the problem?
The concern with this approach arises from the interaction of fast startup with the device. If fast boot is enabled and a user chooses to shut down the device (as opposed to rebooting), the time recorded as the last boot-up will be inaccurate.
To ascertain the accurate time information, accounting for the presence of fast boot, as well as distinguishing between reboots and shutdowns, we will leverage the event log.
Specifically, the event log that holds the answers is named: Microsoft-Windows-Kernel-Boot.
The event ID to monitor within this log is: 27.
The interpretation of the codes is as follows:
– 0x0: Indicates a full shutdown or reboot.
– 0x1: Signifies a shutdown that utilized fast boot.
– 0x2: Represents a resumption from hibernation.
For detecting code 0x0 or 0x1, follow these steps:
# For code 0x0
((Get-WinEvent -ProviderName ‘Microsoft-Windows-Kernel-Boot’ | where {$_.ID -eq 27 -and $_.message -like “*0x0*”} -ea silentlycontinue)[0]).TimeCreated
# For code 0x1
((Get-WinEvent -ProviderName ‘Microsoft-Windows-Kernel-Boot’ | where {$_.ID -eq 27 -and $_.message -like “*0x1*”} -ea silentlycontinue)[0]).TimeCreated
To check if fast boot is enabled using the Windows Registry, you can navigate to the relevant registry key and examine the value of the corresponding entry. Here’s how you can do it:
1. Press Windows Key + R to open the Run dialog.
2. Type regedit and press Enter to open the Windows Registry Editor.
3. Navigate to the following registry key:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Power
4. Look for an entry named HiberbootEnabled in the right-hand pane. This entry’s value indicates whether fast boot is enabled or not:
– If the value is 1 fast boot is enabled.
– If the value is 0 fast boot is not enabled.
To check if Fast Boot is enabled with PowerShell, we can achieve this easily with the following script:
# Get the value of the HiberbootEnabled registry key
$HiberbootEnabled = Get-ItemPropertyValue -Path “HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Power” -Name “HiberbootEnabled” -ErrorAction SilentlyContinue
# Check if the value is null or 0
if ($HiberbootEnabled -eq $null) {
Write-Output “The HiberbootEnabled registry value is not found.”
} elseif ($HiberbootEnabled -eq 0) {
Write-Output “Fast boot is not enabled.”
} elseif ($HiberbootEnabled -eq 1) {
Write-Output “Fast boot is enabled.”
} else {
Write-Output “The HiberbootEnabled value is not recognized: $HiberbootEnabled”
}
By knowing this information, we can create the following script:
# Check if fast boot is enabled
$FastBootEnabled = (Get-ItemPropertyValue -Path “HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Power” -Name “HiberbootEnabled” -ErrorAction SilentlyContinue)
if ($FastBootEnabled -eq $null) {
Write-Output “Fast boot status: Not found”
} elseif ($FastBootEnabled -eq 0) {
Write-Output “Fast boot status: Disabled”
} elseif ($FastBootEnabled -eq 1) {
Write-Output “Fast boot status: Enabled”
} else {
Write-Output “Fast boot status: Unknown”
}
# Get the last boot time
$LastReboot = Get-CimInstance Win32_OperatingSystem | Select-Object -ExpandProperty LastBootUpTime
# Get the last boot time from event logs
$BootEvent = Get-WinEvent -ProviderName ‘Microsoft-Windows-Kernel-Boot’ | Where-Object {$_.ID -eq 27}
if ($BootEvent -ne $null) {
$LastBoot = $BootEvent[0].TimeCreated
} else {
$LastBoot = $null
}
# Determine the correct uptime
if ($LastBoot -eq $null) {
$Uptime = $LastReboot
} else {
$Uptime = [System.Math]::Max($LastReboot, $LastBoot)
}
# Calculate the uptime duration
$UptimeDuration = (Get-Date) – $Uptime
$Days = $UptimeDuration.Days
$Hours = $UptimeDuration.Hours
$Minutes = $UptimeDuration.Minutes
# Display the results
Write-Output “Uptime: $Days day(s), $Hours hour(s), $Minutes minute(s)”
Get the code on GitHub.