Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error in detect-reboot script #32

Open
hotzenwalder opened this issue Apr 2, 2023 · 5 comments
Open

Error in detect-reboot script #32

hotzenwalder opened this issue Apr 2, 2023 · 5 comments

Comments

@hotzenwalder
Copy link

The script used to detect the last time a system was restarted gives an error on my Windows 10 build (19045.2728 Dutch)
https://github.com/JayRHa/EndpointAnalyticsRemediationScripts/blob/main/Toast-RebootMessage/detect-reboot.ps1

The error is
`
Cannot convert value "1680444208,84456" to type "System.Int32". Error: "De indeling van de invoertekenreeks is onjuist."
At line:1 char:1

  • $diff = $now - $poweron`

It's triggered by the command $diff = $now - $poweron, but the problem is probably related to the values of $now and $poweron.
The returned values in the original script are

1680444208,84456 for $now and 1680444197,71884 for $differ.

If you replace the , with a . by changing the $now and $differ to these commands, it works.

$now = (Get-Date -UFormat "%s" -Date (Get-Date)) -replace (",",".")
$poweron = (Get-Date -UFormat "%s" -Date (Get-Process -Id $pid).StartTime) -replace (",",".")

New values are 1680444208.84456 for $now and 1680444197.71884 for $differ and then the calculations work.

I think it has something to do with the region we run in our enviroment Windows (Dutch), so the characters used for numbering might differ.

@johngagefaulkner
Copy link

Considering it's now October 10th, 2023 (more than 6 months since you opened this issue), I'd imagine you've either figured out how to fix the issue or have moved onto something else entirely. Regardless, I just came across this repository a few minutes ago and almost immediately noticed the same issue(s) you're describing.

I rewrote the entire PowerShell script but I'll just share the fix for the specific problem you asked for here:

$ProgressPreference = 'SilentlyContinue'

# Define how often you want your devices to be rebooted
$RebootDeadlineInDays = 7

# Retrieve the Operating System's "Uptime"
$Uptime = Get-ComputerInfo -Property OSUptime | Select-Object OSUptime

if ($Uptime.OSUptime.Days -ge $RebootDeadlineInDays) {
    Write-Host "Operating System has been running for $($Uptime.OSUptime.Days) days! Reboot required."
    Exit 0
} else {
    Write-Host "Operating System was rebooted $($Uptime.OSUptime.Days) days ago! Compliance check: Pass."
    Exit 1
}

Hope that helps! For what it's worth, you can choose to use different measurements of time ("Hours", "Minutes", etc.) by selecting the associated property in the "$Uptime" variable. For example, if you wanted to determine how many hours ago a device rebooted, you could use the following code:

$UptimeInDays = $Uptime.OSUptime.Days
$UptimeInHours = $Uptime.OSUptime.Hours

if ($UptimeInDays -eq 0) {
    Write-Host "Device was rebooted $UptimeInHours hours ago!"
}

@hotzenwalder
Copy link
Author

Thanks for the code, but I think this does not take Fast Boot into consideration.
With the original script it detects my system was last booted this morning, but when I run your code it tells me my system was last rebooted 12 days ago, so be carefull when you use this code. I use a different code these days, but when I try to paste it here it becomes quite unreadable

@johngagefaulkner
Copy link

johngagefaulkner commented Oct 11, 2023

Thanks for the code, but I think this does not take Fast Boot into consideration. With the original script it detects my system was last booted this morning, but when I run your code it tells me my system was last rebooted 12 days ago, so be carefull when you use this code. I use a different code these days, but when I try to paste it here it becomes quite unreadable

That's fair. I have Fast Startup disabled across all devices in our environment so that's a use-case I never would've come across.

Out of curiosity, what's your result when using the following?

$DeviceLastBootupTime = Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty LastBootupTime
$TimeDifference = (Get-Date) - $DeviceLastBootupTime
Write-Host "Device has been online for $($TimeDifference.Days) days, $($TimeDifference.Hours) hours and $($TimeDifference.Minutes) minutes."

EDIT

In all fairness*, however, technically your device hasn’t rebooted in 12 days. With Fast Startup enabled, your device is simply going to sleep and waking up from hibernation.

@hotzenwalder
Copy link
Author

The output is 'Device has been online for 13 days, 2 hours and 15 minutes.'. I know it technically has not rebooted since 13 days since it goes into hibernation, that's why we also disable fast boot so updates get installed properly.

Tried pasting my script again, but it won't get any better than this. Hope you can get the output from it you need with and without fast boot enabled

$Last_reboot = Get-ciminstance Win32_OperatingSystem | Select -Exp LastBootUpTime $Check_FastBoot = (Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Power" -ea Silentlycontinue).HiberbootEnabled If(($Check_FastBoot -eq $null) -or ($Check_FastBoot -eq 0)){ $Boot_Event = Get-WinEvent -ProviderName "Microsoft-Windows-Kernel-Boot"| where {$_.ID -eq 27 -and $_.message -like "*0x0*"} If($Boot_Event -ne $null){ $Last_boot = $Boot_Event[0].TimeCreated } } ElseIf($Check_FastBoot -eq 1){ $Boot_Event = Get-WinEvent -ProviderName "Microsoft-Windows-Kernel-Boot"| where {$_.ID -eq 27 -and $_.message -like "*0x1*"} If($Boot_Event -ne $null){ $Last_boot = $Boot_Event[0].TimeCreated } } If($Last_boot -eq $null){ $Uptime = $Last_reboot }Else { If($Last_reboot -ge $Last_boot){ $Uptime = $Last_reboot }Else{ $Uptime = $Last_boot } } $Current_Date = get-date $Diff_boot_time = $Current_Date - $Uptime $Boot_Uptime_Days = $Diff_boot_time.Days $Hour = $Diff_boot_time.Hours $Minutes = $Diff_boot_time.Minutes $Reboot_Time = "$Boot_Uptime_Days day(s)" + ": $Hour hour(s)" + " : $minutes minute(s)" If($Boot_Uptime_Days -ge $Reboot_Delay){ write-host "$Reboot_Time" EXIT 1 }Else { write-output "No Reboot needed" EXIT 0 }

@johngagefaulkner
Copy link

johngagefaulkner commented Oct 12, 2023

I was able to reformat your script to make it readable. The trick to posting any multi-line code is to use three of the backticks before your script and three more after it. You were only using 1 backtick which tells MarkDown that you're wanting to display inline code and not a block of code.

I appreciate you posting your script, though! I hope you don't mind, I've taken it and restructured it to better fit my use-case. I'm posting it here in case you (or anyone else) wants to take a look!

$ProgressPreference = 'SilentlyContinue'
$ErrorActionPreference = 'Stop'
Write-Host "[ Get-DeviceLastBootupTimeWithFastStartup.ps1 ]" -ForegroundColor Green
Write-Host "Determining whether Fast Startup is enabled, please wait... " -NoNewline

# Define Variables
$RebootThresholdInDays = 7
$FastStartupRegistryKeyPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Power"
$IsFastStartupEnabled = (Get-ItemProperty $FastStartupRegistryKeyPath -ErrorAction SilentlyContinue).HiberbootEnabled
Write-Host "Done!" -ForegroundColor Green

# Determine the last bootup time based on Fast Startup setting
$LastOSBootupTime = if ($IsFastStartupEnabled -eq 1) {
    Write-Host "[Fast Startup] Enabled"
    $LatestBootupEvent = Get-WinEvent -ProviderName "Microsoft-Windows-Kernel-Boot" | Where-Object { $_.ID -eq 27 -and $_.Message -like "*0x1*" }
    $LatestBootupEvent[0].TimeCreated
}
elseif (($null -eq $IsFastStartupEnabled) -or ($IsFastStartupEnabled -eq 0)) {
    Write-Host "[Fast Startup] Disabled"
    (Get-CimInstance Win32_OperatingSystem).LastBootUpTime
}
else {
    Write-Host "[WARNING] Unable to determine whether Fast Startup is enabled. Script exiting with exit code 1." -ForegroundColor Yellow
    exit 1
}

# Calculate OS Uptime
if ($null -ne $LastOSBootupTime) {
    Write-Host "[Last OS Bootup Time] $LastOSBootupTime"
    $OsUptime = (Get-Date) - $LastOSBootupTime
    $OsUptimeInDays = $OsUptime.Days
    $OsUptimeInHours = $OsUptime.Hours
    $OsUptimeInMinutes = $OsUptime.Minutes
    Write-Host "[Operating System Uptime] $OsUptimeInDays day(s), $OsUptimeInHours hour(s), $OsUptimeInMinutes minute(s)"

    # Check if reboot is needed
    if ($OsUptimeInDays -ge $RebootThresholdInDays) {
        Write-Host "Uptime threshold ($RebootThresholdInDays days) has been met or exceeded."
        Write-Host "[Result] " -NoNewLine
        Write-Host "Reboot required." -ForegroundColor Yellow
        exit 2
    }
    else {
        Write-Host "Uptime threshold ($RebootThresholdInDays days) has not been met."
        Write-Host "[Result] " -NoNewline
        Write-Host "No reboot required." -ForegroundColor Green
        exit 0
    }
}
else {
    Write-Host "[WARNING] Unable to determine how long the Operating System has been running. Script exiting with exit code 1." -ForegroundColor Yellow
    exit 1
}

Also, here's a screenshot of the output from the script above:
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants