Skip to main content

The idea behind this worklet is to display balloon tip in the taskbar once every 5 hours and then every 15 minutes to warn end users of an upcoming reboot and when.



If an end user reboots during the notification stages, there is a scheduled task that triggers upon restart that will run another powershell script that was written to cancel out running any future events built by this worklet.



The notification is using a custom icon file I built using a company logo.



Please do a lot of testing beforehand as the code is not professionally written to accommodate for every scenario one could encounter. Enjoy!



Evaluation Code



# Cleanup prior reboot task

Unregister-ScheduledTask -TaskName 'RebootMsg*' -Confirm:$false | Out-Null



# Establish Reboot Data Points

$uptime = (get-date) - (gcim Win32_OperatingSystem).LastBootUpTime

$sysInfo = New-Object -ComObject "Microsoft.Update.SystemInfo"



if($sysInfo.RebootRequired -or $uptime.Days -gt 28)

{

exit 1}

else

{

exit 0}



Remediation Code



Unregister-ScheduledTask -TaskName 'RebootMsg*' -Confirm:$false | Out-Null



# Establish Reboot Data Points

$uptime = (get-date) - (gcim Win32_OperatingSystem).LastBootUpTime

$sysInfo = New-Object -ComObject "Microsoft.Update.SystemInfo"



if($sysInfo.RebootRequired -or $uptime.Days -gt 28)

{



# Balloon tip pop-up

$title = 'Company'

$icon = 'C:\Users\Public\Pictures\Company.ico'

$date = Get-Date ([datetime]::Now.AddMinutes(360)) -Format 'h:mm tt'

$msg = "As part of keeping Company safe, please save your work and reboot your computer. Automatic reboot at $date"

IF(!(Test-Path $icon)){Copy-Item Company.ico $icon | Out-Null}

$workdir = "C:\ProgramData\amagent"

IF(!(Test-Path $workdir)){mkdir $workdir | Out-Null}



# Cleanup Prior Scheduled tasks if they exist

Unregister-ScheduledTask -TaskName 'RebootMsg*' -Confirm:$false | Out-Null



function Build-Scripts{

# Build script that will send message

$vbs = @"

command = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -windowstyle hidden -File C:\ProgramData\Amagent\message.ps1 -Force"

set shell = CreateObject("WScript.Shell")

shell.Run command,0

"@

New-Item -Path "$workdir" -Name "message.vbs" -ItemType "file" -Value $vbs -force | Out-Null



$script = @"

`$BalloonTipText = ("$msg")

`$BalloonTipTitle = "$title"

`$BalloonTipTime = 1000

`$BalloonTipIcon = 'None'



Add-Type -AssemblyName System.Windows.Forms

Add-Type -AssemblyName System.Drawing

[Windows.Forms.ToolTipIcon]`$BalloonTipIcon = `$BalloonTipIcon

`$ContextMenu = New-Object System.Windows.Forms.ContextMenu

`$MenuItem = New-Object System.Windows.Forms.MenuItem



`$NotifyIcon = New-Object Windows.Forms.NotifyIcon -Property @{

BalloonTipIcon = `$BalloonTipIcon

BalloonTipText = `$BalloonTipText

BalloonTipTitle = `$BalloonTipTitle

ContextMenu = `$ContextMenu

Icon = "C:\Users\Public\Pictures\Company.ico"

Text = -join `$BalloonTipText[0..62]

Visible = `$false

}

`$NotifyIcon.contextMenu.MenuItems.AddRange(`$MenuItem)

`$NotifyIcon.Visible = `$True

`$MenuItem.Text = "Exit"

`$MenuItem.add_Click({

`$NotifyIcon.Visible = `$true

`$NotifyIcon.ShowInTaskbar = `$true

})

`$NotifyIcon.ShowBalloonTip(`$BalloonTipTime)

"@

New-Item -Path "$workdir" -Name "message.ps1" -ItemType "file" -Value $script -force | Out-Null



$script = @"

# Cleanup Prior Scheduled tasks if they exist

Unregister-ScheduledTask -TaskName 'RebootMsg*' -Confirm:`$false

Remove-Item $workdir\message* -Confirm:`$false -Force

"@

New-Item -Path "C:\windows\temp\" -Name "message-stop.ps1" -ItemType "file" -Value $script -force | Out-Null



}

Build-Scripts



# Schedule actual Reboot

Function Schedule-Reboot{

# This will create a scheduled task for SYSTEM REBOOT

$TaskStartTime = [datetime]::Now.AddMinutes(360) # Six hours

$SchedService = New-Object -ComObject Schedule.Service

$SchedService.Connect()

$Task = $SchedService.NewTask(0)

$Task.RegistrationInfo.Description = 'Balloon tip pop-up'

$Task.Settings.Enabled = $true

$Task.Settings.AllowDemandStart = $true

$trigger = $Task.triggers.Create(1) # https://docs.microsoft.com/en-us/windows/win32/taskschd/triggercollection-create

$trigger.StartBoundary = $TaskStartTime.ToString("yyyy-MM-dd'T'HH🇲🇲ss")

$trigger.Enabled = $true

$action = $Task.Actions.Create(0)

$action.Path = 'C:\Windows\System32\Shutdown.exe'

$action.Arguments = "/r /t 900"

$taskFolder = $SchedService.GetFolder('\')

$taskFolder.RegisterTaskDefinition("RebootMsgReboot", $Task , 6, 'SYSTEM', $null, 4) | out-null

}

Schedule-Reboot



Function Stop-Reboot{

# This will create a scheduled task for SYSTEM REBOOT

$TaskStartTime = [datetime]::Now.AddMinutes(0) # Six hours

$SchedService = New-Object -ComObject Schedule.Service

$SchedService.Connect()

$Task = $SchedService.NewTask(0)

$Task.RegistrationInfo.Description = 'Balloon tip pop-up'

$Task.Settings.Enabled = $true

$Task.Settings.AllowDemandStart = $true

$trigger = $Task.triggers.Create(8) # https://docs.microsoft.com/en-us/windows/win32/taskschd/triggercollection-create

$trigger.StartBoundary = $TaskStartTime.ToString("yyyy-MM-dd'T'HH🇲🇲ss")

$trigger.Enabled = $true

$action = $Task.Actions.Create(0)

$action.Path = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"

$action.Arguments = "-NoProfile -NoLogo -NonInteractive -ExecutionPolicy Bypass -File C:\windows\temp\message-stop.ps1 -Force"

$taskFolder = $SchedService.GetFolder('\')

$taskFolder.RegisterTaskDefinition("RebootMsgStop", $Task , 6, 'SYSTEM', $null, 4) | out-null

}

Stop-Reboot



# Sets up multiple scheduled tasks to run once every hour up to five hours, then every 15min there after

Function Schedule-RebootMsg {

$i = 0 # Minutes

$a = 0 # task count

do

{

# This will create a scheduled task

IF($i -ge 300){$i = $i + 15}else{$i = $i + 60}

$TaskStartTime = [datetime]::Now.AddMinutes($i) # Now.AddMinutes(1)

$SchedService = New-Object -ComObject Schedule.Service

$SchedService.Connect()

$Task = $SchedService.NewTask(0)

$Task.RegistrationInfo.Description = 'Balloon tip pop-up'

$Task.Settings.Enabled = $true

$Task.Settings.AllowDemandStart = $true

$trigger = $Task.triggers.Create(1) # https://docs.microsoft.com/en-us/windows/win32/taskschd/triggercollection-create

$trigger.StartBoundary = $TaskStartTime.ToString("yyyy-MM-dd'T'HH🇲🇲ss")

$trigger.Enabled = $true

$action = $Task.Actions.Create(0)

$action.Path = "$workdir\message.vbs"

$taskFolder = $SchedService.GetFolder('\')

$taskFolder.RegisterTaskDefinition("RebootMsg$a", $Task , 6, 'Users', $null, 4) | out-null

$a++

}

while ($i -lt 360)

}

Schedule-RebootMsg



Start-ScheduledTask -TaskName RebootMsg0

Write-Output "Scheduled reboot for $date"

}else{ write-output "No Reboot Detected."}

is there a similar worklet for macOS?


Reply