Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #================================================================================
- # Shutdown Scheduler with Windows Update–Style Toast & Tray Snooze Feature
- #
- # - Cancels any pending shutdown/restart.
- # - Schedules a new restart in 15 minutes (shutdown /r /t 900 /f /c "Scheduled by Admin").
- # - Displays a Windows Update–style toast notification.
- # - Creates a system tray icon with context menu options:
- # • Snooze for 1 Hour (cancels the scheduled restart and schedules one in 3600 seconds).
- # • Restart Now (cancels the scheduled restart and restarts immediately).
- # • Dismiss (leaves the scheduled restart as-is).
- # - The tray icon auto-exits after 60 seconds if no action is taken.
- #
- # Run in a standard account.
- #================================================================================
- #----- Begin Windows Update–Style Toast Notification Setup -----
- If ($PSVersionTable.PSVersion.Major -lt 6)
- {
- $null = [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime]
- $null = [Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime]
- }
- else
- {
- # Ensure NuGet package provider is installed
- if ($null -eq (Get-PackageProvider -Name NuGet -ErrorAction SilentlyContinue))
- {
- try { $null = Install-PackageProvider -Name NuGet -Force -Scope CurrentUser -ErrorAction Stop }
- catch { throw $_.Exception.Message }
- }
- # Ensure Microsoft.Windows.SDK.NET.Ref package is installed
- if ($null -eq (Get-Package -ProviderName NuGet -Name Microsoft.Windows.SDK.NET.Ref -AllVersions -ErrorAction SilentlyContinue))
- {
- try { $null = Install-Package -Name Microsoft.Windows.SDK.NET.Ref -ProviderName NuGet -Force -Scope CurrentUser -ErrorAction Stop }
- catch { throw $_.Exception.Message }
- }
- # Retrieve the latest WinRT.Runtime.dll and Microsoft.Windows.SDK.NET.dll files
- $WinRTRuntime = Get-ChildItem -Path "$env:LOCALAPPDATA\PackageManagement\NuGet\Packages\Microsoft.Windows.SDK.NET.Ref.*" -Filter "WinRT.Runtime.dll" -Recurse -ErrorAction SilentlyContinue |
- Sort-Object -Property VersionInfo.FileVersion -Desc | Select -ExpandProperty FullName | Select -First 1
- $WinSDKNet = Get-ChildItem -Path "$env:LOCALAPPDATA\PackageManagement\NuGet\Packages\Microsoft.Windows.SDK.NET.Ref.*" -Filter "Microsoft.Windows.SDK.NET.dll" -Recurse -ErrorAction SilentlyContinue |
- Sort-Object -Property VersionInfo.FileVersion -Desc | Select -ExpandProperty FullName | Select -First 1
- # Load the required DLLs
- Add-Type -Path $WinRTRuntime -ErrorAction Stop
- Add-Type -Path $WinSDKNet -ErrorAction Stop
- }
- #----- End Notification Setup -----
- # Function to display a Windows Update–style toast notification.
- function Show-WindowsUpdateToast {
- param (
- [Parameter(Mandatory=$true)]
- [string]$Title,
- [Parameter(Mandatory=$true)]
- [string]$SubtitleText
- )
- $AudioSource = "ms-winsoundevent:Notification.Default"
- # Windows Update–style toast XML template
- [xml]$ToastTemplate = @"
- <toast duration="long">
- <visual>
- <binding template="ToastGeneric">
- <text>Windows Updates – you know you love 'em</text>
- <group>
- <subgroup>
- <text hint-style="title" hint-wrap="true">$Title</text>
- </subgroup>
- </group>
- <group>
- <subgroup>
- <text hint-style="subtitle" hint-wrap="true">$SubtitleText</text>
- </subgroup>
- </group>
- </binding>
- </visual>
- <audio src="$AudioSource"/>
- </toast>
- "@
- try {
- $ToastXml = New-Object -TypeName Windows.Data.Xml.Dom.XmlDocument
- $ToastXml.LoadXml($ToastTemplate.OuterXml)
- $App = "Windows.SystemToast.WindowsUpdate.MoNotification2"
- [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($App).Show($ToastXml)
- }
- catch {
- Write-Host "Toast notification failed: $($_.Exception.Message)"
- }
- }
- #----- Cancel any existing scheduled shutdown/restart -----
- $shutdownOutput = shutdown /a 2>&1
- if ($shutdownOutput -match "No shutdown was scheduled") {
- $cancelMessage = "No scheduled shutdown/restart was found."
- } else {
- $cancelMessage = "A scheduled shutdown/restart was detected and cancelled."
- }
- Write-Host $cancelMessage
- Show-WindowsUpdateToast -Title "Shutdown Scheduler" -SubtitleText $cancelMessage
- #----- Schedule new restart in 15 minutes -----
- shutdown /r /t 900 /f /c "Scheduled by Admin"
- $scheduleMessage = "New restart scheduled in 15 minutes. Right-click tray icon for options."
- Write-Host $scheduleMessage
- Show-WindowsUpdateToast -Title "Shutdown Scheduler" -SubtitleText $scheduleMessage
- #----- Create a system tray icon with snooze options -----
- Add-Type -AssemblyName System.Windows.Forms
- Add-Type -AssemblyName System.Drawing
- # Create a NotifyIcon (tray icon)
- $notifyIcon = New-Object System.Windows.Forms.NotifyIcon
- $notifyIcon.Icon = [System.Drawing.SystemIcons]::Information
- $notifyIcon.Text = "Shutdown Scheduler"
- $notifyIcon.Visible = $true
- # Create a context menu for the tray icon
- $contextMenu = New-Object System.Windows.Forms.ContextMenu
- # Menu item: Snooze for 1 Hour
- $snoozeItem = New-Object System.Windows.Forms.MenuItem "Snooze for 1 Hour"
- $snoozeItem.add_Click({
- # Cancel existing scheduled shutdown and schedule restart in 1 hour
- shutdown /a 2>&1 | Out-Null
- shutdown /r /t 3600 /f /c "Snoozed by Admin"
- [System.Windows.Forms.MessageBox]::Show("System snoozed for 1 hour.", "Shutdown Scheduler")
- Show-WindowsUpdateToast -Title "Shutdown Scheduler" -SubtitleText "System snoozed for 1 hour."
- $notifyIcon.Visible = $false
- $notifyIcon.Dispose()
- [System.Windows.Forms.Application]::Exit()
- })
- # Menu item: Restart Now
- $restartNowItem = New-Object System.Windows.Forms.MenuItem "Restart Now"
- $restartNowItem.add_Click({
- shutdown /a 2>&1 | Out-Null
- shutdown /r /t 0 /f /c "Restart Now by Admin"
- [System.Windows.Forms.MessageBox]::Show("System is restarting now.", "Shutdown Scheduler")
- Show-WindowsUpdateToast -Title "Shutdown Scheduler" -SubtitleText "System is restarting now."
- $notifyIcon.Visible = $false
- $notifyIcon.Dispose()
- [System.Windows.Forms.Application]::Exit()
- })
- # Menu item: Dismiss (do nothing; keep current schedule)
- $dismissItem = New-Object System.Windows.Forms.MenuItem "Dismiss"
- $dismissItem.add_Click({
- $notifyIcon.Visible = $false
- $notifyIcon.Dispose()
- [System.Windows.Forms.Application]::Exit()
- })
- # Add items to the context menu
- $contextMenu.MenuItems.Add($snoozeItem)
- $contextMenu.MenuItems.Add($restartNowItem)
- $contextMenu.MenuItems.Add($dismissItem)
- $notifyIcon.ContextMenu = $contextMenu
- # Optionally, show a balloon tip (for 5 seconds) to instruct the user
- $notifyIcon.ShowBalloonTip(5000, "Shutdown Scheduler", "Right-click the tray icon to Snooze for 1 Hour or Restart Now.", [System.Windows.Forms.ToolTipIcon]::Info)
- #----- Set up a timer to auto-exit the tray icon after 60 seconds if no action is taken -----
- $timer = New-Object System.Windows.Forms.Timer
- $timer.Interval = 60000 # 60 seconds
- $timer.add_Tick({
- $timer.Stop()
- $notifyIcon.Visible = $false
- $notifyIcon.Dispose()
- [System.Windows.Forms.Application]::Exit()
- })
- $timer.Start()
- # Run the Windows Forms message loop to keep the tray icon active
- [System.Windows.Forms.Application]::Run()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement