Worklet: Predictable Reboot Notifications for Windows

  • 25 September 2019
  • 34 replies

Show first post

34 replies

Userlevel 4

Would you be willing to share this with us?

Userlevel 4

Here you go. Feel freer to reach out if you need help

.RebootNotifications.pdf (133.8 KB)

Userlevel 4

impressive script, kudo’s! Just curious why base encode an image and not use another file attached to the worklet?

Userlevel 4

Just an old habit. 🙂 You can definitely use the method you mentioned - that’s probably easier 🙂

Userlevel 4

Hi everyone. I recently made a change to this worklet. It now installs 2 scheduled tasks.

Here is the new reboot powershell script:

Add-Type @'
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace PInvoke.Win32 {

public static class UserInput {

[DllImport("user32.dll", SetLastError=false)]
private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

private struct LASTINPUTINFO {
public uint cbSize;
public int dwTime;

public static DateTime LastInput {
get {
DateTime bootTime = DateTime.UtcNow.AddMilliseconds(-Environment.TickCount);
DateTime lastInput = bootTime.AddMilliseconds(LastInputTicks);
return lastInput;

public static TimeSpan IdleTime {
get {
return DateTime.UtcNow.Subtract(LastInput);

public static int LastInputTicks {
get {
lii.cbSize = (uint)Marshal.SizeOf(typeof(LASTINPUTINFO));
GetLastInputInfo(ref lii);
return lii.dwTime;

Function IsAutomaticReboot

Two conditions must be met for automatic reboot
1. The local time must be between $rebootStartTime and $rebootEndTime
2. There has not been any user input for at least $idleTime minutes


$boolTimeConditionMet = $False
$minTime = Get-Date $rebootStartTime
$maxTime = Get-Date $rebootEndTime
$now = Get-Date
if ($minTime.TimeOfDay -le $now.TimeOfDay -and $maxTime.TimeOfDay -ge $now.TimeOfDay)
$boolTimeConditionMet = $True

$boolIdleConditionMet = $False
$idleTime = [PInvoke.Win32.UserInput]::IdleTime
if ($idleTime.Minutes -ge $minIdleTime)
$boolIdleConditionMet = $True

return ($boolIdleConditionMet -and $boolTimeConditionMet)

Function RebootComputer
Restart-Computer -Force

# These parameters control the time of day window within which automatic reboot will be initiated
[string]$rebootStartTime = "1am"
[string]$rebootEndTime = "5am"

# If there is no user input detected for $minIdleTime minutes within $rebootStarTime and $rebootEndTime, automatic reboot
# will be initiated
[int]$minIdleTime = 30

# Check if a reboot is pending
$sysInfo = New-Object -ComObject "Microsoft.Update.SystemInfo"
if (IsAutomaticReboot)

This scheduled job needs to be installed with certain properties for it to work. And here is the powershell script to do this:

$action = New-ScheduledTaskAction -Execute wscript.exe -Argument "//B C:\ProgramData\amagent\rebootNotification\Hidden.vbs C:\ProgramData\amagent\rebootNotification\RunToastHidden.cmd" 
$trigger = New-ScheduledTaskTrigger -Daily -At 9am
$principal = New-ScheduledTaskPrincipal -UserID "NT AUTHORITY\SYSTEM" -LogonType ServiceAccount -RunLevel Highest
$settings = New-ScheduledTaskSettingsSet -MultipleInstances Parallel
$task = Register-ScheduledTask -TaskName "Reboot No Reminder" -Trigger $trigger -Action $action -User "NT AUTHORITY\SYSTEM"
$task.Triggers.Repetition.Interval = "PT1H"
$task.Triggers.Repetition.Duration = "P1D"
$task.Settings.StartWhenAvailable = $True
$task | Set-ScheduledTask -ErrorAction SilentlyContinue
Userlevel 4

The reason for the change is this: the previous script would not reboot the computer between 1am and 5am if there is no user logged on.

would it be possible to share this in a non-PDF output?

Maybe implement it directly in Automox ?

Userlevel 1

I think it would be helpful to include all dependencies, like this will require Toast notifications to be enabled or the user will never see these alerts (which is kinda a big deal).  You’d want to build some checks at the head of the script like the following, to a) check if notifications are enabled, and b) enable them.

function Test-WindowsPushNotificationsEnabled() {
$ToastEnabledKey = (Get-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\PushNotifications" -Name ToastEnabled -ErrorAction Ignore).ToastEnabled
if ($ToastEnabledKey -eq "1") {
Write-Host "Toast notifications for the logged on user are enabled in Windows"
elseif ($ToastEnabledKey -eq "0") {
Write-Host "Toast notifications for the logged on user are not enabled in Windows. The script will try to enable toast notifications for the logged on user"

# Create Enable-WindowsPushNotifications
# This is used to re-enable toast notifications if the user disabled them generally in Windows
function Enable-WindowsPushNotifications() {
$ToastEnabledKeyPath = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\PushNotifications"
Write-Host "Trying to enable toast notifications for the logged on user"
try {
Set-ItemProperty -Path $ToastEnabledKeyPath -Name ToastEnabled -Value 1 -Force
Get-Service -Name WpnUserService** | Restart-Service -Force
Write-Host "Successfully enabled toast notifications for the logged on user"
catch {
Write-Host "Failed to enable toast notifications for the logged on user. Toast notifications will probably not be displayed"