Files
management-scripts/Set-RebootSchedule.ps1
T

679 lines
27 KiB
PowerShell
Raw Normal View History

2019-11-11 19:22:39 -05:00
<#
.SYNOPSIS
Provides friendly messages reminding a user to restart their computer based on events that require it.
.DESCRIPTION
The Set-RebootSchedule script is called from any computer management software to notify a user of a required restart.
This script accepts several different parameters which change the messages displayed to the user.
Some logic is used when determining the best time to remind the user to restart.
.PARAMETER SysPerf
The -SysPerf parameter will remind the user to restart due to system performance.
This parameter should be called if the computer has had consistently high memory usage, recurring application hangs, or stuck processes.
If this parameter is used it will simply tell the user that a restart is needed to improve overall stability.
.PARAMETER OSUpdate
The -OSUpdate parameter will remind the user to restart due to operating system updates.
.PARAMETER Uptime
The -Uptime parameter will remind the user to restart due to long uptimes.
This script does not define the length of time the computer has been on, but will display the number of days to the end user.
If the computer has been on for 10 days and this parameter is used, it will tell the user this computer has been on for 10 days.
.PARAMETER AllowMinimize
The -AllowMinimize parameter will let the prompts and reminders be minimized by the user.
By default, the user is not allowed to minimize the window.
.PARAMETER Override
The -Override parameter is used with either the -OSUpdate or -Uptime parameters.
This parameter will override the priority of the existing reminder schedule and overwrite any existing schedule with the one set when -Override is called.
See the NOTES section for additional information on schedule priorities.
.PARAMETER Remove
The -Remove parameter will simply delete any scheduled restart reminder.
.PARAMETER Task
The -Task parameter will allow this script to run without scheduling a task. This switch is called when this task creates a scheduled task of itself.
.EXAMPLE
Set-RebootSchedule -SysPerf
Prompt the user to restart because you've seen problems in multiple areas of the computer.
.EXAMPLE
Set-RebootSchedule -OSUpdate
Prompt the user to restart because Windows was recently updated.
.EXAMPLE
Set-RebootSchedule -Uptime
Prompt the user to restart because the computer has been up for a long time.
.EXAMPLE
Set-RebootSchedule -OSUpdate -Override
Prompt the user to restart because Windows was recently updated, overwriting any existing reminder schedule.
.EXAMPLE
Set-RebootSchedule -Uptime -Override
Prompt the user to restart because the computer has been up for a long time, overwriting any existing reminder schedule.
.EXAMPLE
Set-RebootSchedule -Remove
There is no longer a need to remind the user to restart, or you just want to clear an existing reminder schedule.
.NOTES
Calling this script with no parameters does nothing, the script will just exit without prompting the user for anything.
This is the order of schedule priority when this script is called:
1.) SysPerf
2.) OSUpdate
3.) Uptime
If -Uptime is called but a schedule has already been set by -OSUpdate, the user will not be prompted to schedule a restart.
If -OSUpdate is called but a schedule has already been set by -SysPerf, the user will not be prompted to schedule a restart.
If -SysPerf is called but a schedule has already been set by -OSUpdate, the user will be prompted to schedule a restart and the existing schedule will be overwritten.
The -Override parameter is used to modify this logic such that a lower priority schedule can overwrite a higher priority schedule.
#>
## Define parameters
Param(
[switch]$SysPerf,
[switch]$OSUpdate,
[switch]$Uptime,
[switch]$AllowMinimize=$false,
[switch]$Override,
[switch]$Force,
[switch]$Remove
)
## Add Windows Forms support to this script
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
## Functions and subroutines
#region begin FUNCTIONS {
## Copy this script to a directory where it can be called by a scheduled task
Function Copy-ThisScript {
## Get the current directory path and file name of this script
$ThisDirectory = Split-Path -Parent $MyInvocation.PSCommandPath
$ThisScript = Split-Path -Leaf $MyInvocation.PSCommandPath
## Check to make sure we don't copy this script if it's already been copied to $CopyDirectory
If ( !($ThisDirectory -eq $CopyDirectory) ) {
## Create the destination directory if it doesn't already exist
If ( !(Test-Path -Path $CopyDirectory) ) { New-Item -ItemType Directory -Force -Path $CopyDirectory }
## Delete the existing script in $CopyDirectory
If ( Test-Path -Path "${CopyDirectory}\${CopyFilename}" ) { Remove-Item -Path "${CopyDirectory}\${CopyFilename}" -Force }
## Copy the script to $CopyDirectory\$CopyFilename
Copy-Item -Path "${ThisDirectory}\${ThisScript}" -Destination "${CopyDirectory}\${CopyFilename}"
}
}
## Gets the number of days the system has been up.
Function Get-UptimeDays {
## Get a new instance of the Win32_OperatingSystem WMI object
$WMIOS = Get-WmiObject Win32_OperatingSystem
## Get the last boot time and convert it to a DateTime value
$LastBootTime = $WMIOS.ConvertToDateTime($WMIOS.LastBootUpTime)
## Get the number of days since the last time the system was powered on
[string]$Uptime = (New-TimeSpan -Start $LastBootTime -End $(Get-Date)).Days.ToString()
Return $Uptime
}
## Determines whether the logo can be downloaded or not
Function IsLogoDownloadable {
## Create a web request
$HTTPRequest = [System.Net.WebRequest]::Create($LogoURL)
## Get the response
Try { $HTTPResponse = $HTTPRequest.GetResponse() }
## Catch any error2 when trying to connect to the resource (including 404)
Catch [System.Net.WebException] { $HTTPResponse = $_.Exception.Response }
## Save the status code
$HTTPStatus = [int]$HTTPResponse.StatusCode
## Close the connection, because we're done with it
$HTTPResponse.Close()
## Test to make sure we received a status of 200 "OK" from the resource
If ($HTTPStatus -eq 200) { Return $true }
## If the status code is anything other than 200, return $false so we can do something else
Else { Return $false }
}
## Returns the local path of a file downloaded from a URL
Function Get-LogoPath {
## Get the file name from $url
$filename = [System.IO.Path]::GetFileName($LogoURL)
## Set the destination to download to
$localpath = "${Env:TEMP}\${filename}"
## Make sure the file is downloadable
If ( IsLogoDownloadable ) {
## Try downloading the file
Try { (New-Object Net.WebClient).DownloadFile($LogoURL, $localpath) }
## If you want to handle any download errors, put that code in here
Catch { $_ }
}
## Now that the file *may* be downloaded, check to make sure it exists
If ( Test-Path $localpath ) {
## Return $localpath to the caller
Return $localpath
}
## If $localpath doesn't exist (ie: from a previous execution of this script) then return $false
Else { Return $false }
}
## Base64 encode something
Function Get-Base64($data) {
$bytes = [System.Text.Encoding]::Unicode.GetBytes($data)
$encoded = [Convert]::ToBase64String($bytes)
Return $encoded
}
## Create a scheduled task
Function Create-ScheduledTask([string]$name,[string]$description,$action,$principal,$trigger) {
## Unregister any existing task with the same name as the one we're trying to create
## This needs to be fixed. If the task does not exist, it throws an error.
Try { Unregister-ScheduledTask -TaskName $name -Confirm:$false }
Catch { $_ }
## Configure the task
$Task = New-ScheduledTask -Description $description -Action $action -Principal $principal -Trigger $trigger
## Register the scheduled task
Register-ScheduledTask -TaskName $name -InputObject $Task
}
## Create a task to delete another task
## This will run at boot time to make sure that the user doesn't get unnessarily disrupted by
## a previously scheduled restart task after the computer has already been restarted.
Function Create-DeleteTask([string]$tasktodelete) {
## Create a RunOnce task to delete the specified task in the Task Scheduler
## PROBLEM: How can this occur if the user isn't an admin?
## Will this work the same if we write to HKCU instead?
#Set-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" -Name '!DeleteScheduledRebootReminder' -Value "schtasks.exe /Delete /TN ${tasktodelete} /F"
## Set the task name
$TaskName = "${CompanyAbbr} - Delete Task: ${tasktodelete}"
## Se the task description
$TaskDescription = "This task deletes the task: ${tasktodelete}"
## Configure the task action
$args = "/delete /tn " + '"' + "\${tasktodelete}" + '"' + " /f"
$TaskAction = New-ScheduledTaskAction -Execute "schtasks.exe" -Argument $args
## Configure the user account the task will run under
$TaskPrincipal = New-ScheduledTaskPrincipal -UserId "LOCALSERVICE" -LogonType ServiceAccount
## Configure the trigger to start at the specified time
$Trigger = New-ScheduledTaskTrigger -AtStartup
}
## Create a restart task
#Function Create-RestartTask([datetime]$starttime) {
#
# ## Set the task name
# $TaskName = "${CompanyAbbr} - Computer Restart Task"
#
# ## Set the task description
# $TaskDescription = "This task restarts the computer"
#
# ## Convert $script to Base64
# $EncodedScript = Get-Base64 $RestartComputerTaskScript
#
# ## Configure the task action
# $TaskAction = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-WindowStyle Hidden -NonInteractive -ExecutionPolicy Bypass -EncodedCommand ${EncodedScript}"
#
# ## Configure the user account the task will run under
# $TaskPrincipal = New-ScheduledTaskPrincipal -UserId "LOCALSERVICE" -LogonType ServiceAccount
#
# ## Configure the trigger to start at the specific time
# $Trigger = New-ScheduledTaskTrigger -Once -At $starttime
#
# ## Create a new task to delete the one we're about to create the next time the compter boots
# Create-DeleteTask $TaskName
#
# ## Create the restart task
# Create-ScheduledTask $TaskName $TaskDescription $TaskAction $TaskPrincipal $TaskTrigger
#}
## Create a reminder task
#Function Create-ReminderTask([datetime]$starttime) {
#
# ## Set the task name
# $TaskName = "${CompanyAbbr} - Computer Restart Reminder Task"
#
# ## Set the task description
# $TaskDescription = "This task reminds the user to restart their computer"
#
# ## Convert $script to Base64
# $EncodedScript = Get-Base64 $ReminderTaskScript
#
# ## Configure the task action
# $TaskAction = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-WindowStyle Hidden -NonInteractive -ExecutionPolicy Bypass -EncodedCommand ${EncodedScript}"
#
# ## Configure the user account the task will run under
# $TaskPrincipal = New-ScheduledTaskPrincipal -UserId "LOCALSERVICE" -LogonType ServiceAccount
#
# ## Configure the trigger to start at boot
# $Trigger = New-ScheduledTaskTrigger -Once -At $starttime
#
# ## Create the restart task
# Create-ScheduledTask $TaskName $TaskDescription $TaskAction $TaskPrincipal $TaskTrigger
#
# ## Create a new task to delete the one we just created the next time the compter boots
# Create-DeleteTask $TaskName
#}
## Create a reminder task
Function Create-ReminderTask([datetime]$starttime) {
## Set the task name
$TaskName = "${CompanyAbbr} - Computer Restart Reminder Task"
## Set the task description
$TaskDescription = "This task reminds the user to restart their computer"
## Convert $script to Base64
$EncodedScript = Get-Base64 $ReminderTaskScript
## Configure the task action
$TaskAction = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-ExecutionPolicy Bypass -File `"${CopyDirectory}\${CopyFilename}`""
## Configure the user account the task will run under
$TaskPrincipal = New-ScheduledTaskPrincipal -UserId "LOCALSERVICE" -LogonType ServiceAccount
## Configure the trigger to start at boot
$Trigger = New-ScheduledTaskTrigger -Once -At $starttime
## Create the restart task
Create-ScheduledTask $TaskName $TaskDescription $TaskAction $TaskPrincipal $TaskTrigger
## Create a new task to delete the one we just created the next time the compter boots
Create-DeleteTask $TaskName
}
## Determine if the current time is earlier than the given time
#Function EarlierThan($time) {
#
# ## If it's earlier, return $true
# If ( (Get-Date) -lt $time ) { Return $true }
#
# ## If it's later, return false
# Else { Return $false }
#}
## Get the closest time to schedule a restart
#Function Get-NearestRestartTime {
#
# ## Find out what day it is
# switch ( (Get-Date).DayOfWeek ) {
#
# ## On weekends, the nearest time to schedule a restart will be:
# ## 1.) Lunch time
# ## 2.) Sometime in the afternoon
# ## 3.) About 20 minutes from the current time
# { $WeekendDays -contains $_ } {
#
# ## If it's earlier than $Lunchime, return $LunchTime
# If ( EarlierThan $LunchTime ) { Return $LunchTime }
#
# ## If it's earlier than $AfternoonTime, return $AfternoonTime
# ElseIf ( EarlierThan $AfternoonTime ) { Return $AfternoonTime }
#
# ## If it's after $AfternoonTime, return $ShortTimeFromNow
# Else { Return $ShortTimeFromNow }
# break
# }
# ## Throughout the week the nearest time to remind to restart will be:
# ## 1.) Lunch time
# ## 2.) Close of business
# ## 3.) Late at night
# { $WeekDays -contains $_ } {
#
# ## If it's earlier than $LunchTime, return $LunchTime
# If ( EarlierThan $LunchTime ) { Return $LunchTime }
#
# ## If it's earlier than $CloseOfBusiness, return $CloseOfBusiness
# ElseIf ( EarlierThan $CloseOfBusiness ) { Return $CloseOfBusiness }
#
# ## If it's after $CloseOfBusiness, return $LateAtNight
# Else { Return $LateAtNight }
# break
# }
# default { break }
# }
#}
## Get the next time to remind the user to restart
#Function Get-NextReminderTime {
#
# ## Find out what day it is
# switch ( (Get-Date).DayOfWeek ) {
#
# { $TwoDayReminderDays -contains $_ } {
#
# ## Add 2 days to the current day, then add the $ReminderDelay
# $next = $StartOfBusiness + (New-TimeSpan -Days 2) + $ReminderDelay
# Return $next
# break
# }
#
# { $OneDayReminderDays -contains $_ } {
#
# ## Add 1 day to the current day, then add the $ReminderDelay
# $next = $StartOfBusiness + (New-TimeSpan -Days 1) + $ReminderDelay
# Return $next
# break
# }
# default { break }
# }
#}
Function Get-NextReminderTime {
$next = (Get-Date) + $ReminderInterval
Return $next
}
## Builds the Windows form to display to the user
Function Display-Prompt([string]$message) {
## Set the form's overall parameters
$Form = New-Object System.Windows.Forms.Form
$Form.ClientSize = '400,360'
$Form.Text = $WindowTitle
$Form.TopMost = $true
$Form.MaximizeBox = $false
$Form.MinimizeBox = $AllowMinimize
$Form.FormBorderStyle = 'FixedDialog'
$Form.StartPosition = 'CenterScreen'
## Download the logo
$Logo = (Get-LogoPath)
## Add a picturebox to the form
If ( $Logo ) {
$pbLogo = New-Object system.Windows.Forms.PictureBox
$pbLogo.Width = $Form.ClientSize.Width - 20
$pbLogo.Height = 90
$pbLogo.Anchor = [System.Windows.Forms.AnchorStyles]::None
$pbLogo.Location = New-Object System.Drawing.Point(10,10)
$pbLogo.ImageLocation = $Logo
$pbLogo.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::CenterImage
$Form.Controls.Add($pbLogo)
}
## If the logo isn't available, add label to the form instead of a picturebox
Else {
$lblCompany = New-Object System.Windows.Forms.Label
$lblCompany.Text = $CompanyName
$lblCompany.AutoSize = $false
## The TextAlign enumerations can be found here:
## https://docs.microsoft.com/en-us/dotnet/api/system.drawing.contentalignment?view=netframework-2.0
$lblCompany.TextAlign = 32
$lblCompany.Width = $Form.ClientSize.Width - 20
$lblCompany.Height = 60
$lblCompany.Location = New-Object System.Drawing.Point(10,10)
$lblCompany.Font = 'Microsoft Sans Serif,24,style=Bold'
$Form.Controls.Add($lblCompany)
}
## This is the label that contains the reason for the restart
$lblReason = New-Object System.Windows.Forms.Label
$lblReason.Text = $message
$lblReason.AutoSize = $false
$lblReason.TextAlign = 1
$lblReason.Width = $Form.ClientSize.Width - 50
$lblReason.Height = 180
$lblReason.Location = New-Object System.Drawing.Point(25,100)
$lblReason.Font = 'Microsoft Sans Serif,11'
$Form.Controls.Add($lblReason)
## This is the label that contains a static message about how to proceed
$lblProceed = New-Object System.Windows.Forms.Label
$lblProceed.Text = $ProceedText
$lblProceed.AutoSize = $true
$lblProceed.TextAlign = 1
$lblProceed.Location = New-Object System.Drawing.Point(25,280)
$lblProceed.Font = 'Microsoft Sans Serif,11'
$Form.Controls.Add($lblProceed)
# ## This is the button that displays the nearest time to schedule a reboot
# $btnNearestTime = New-Object System.Windows.Forms.Button
# $btnNearestTime.Text = (Get-Date -Date $NearestRestartTime -Format "hh:mm tt").ToString()
# $btnNearestTime.Width = 130
# $btnNearestTime.Height = 30
# $btnNearestTime.Location = New-Object System.Drawing.Point(45,310)
# $btnNearestTime.Font = 'Microsoft Sans Serif,11'
# $btnNearestTime.Add_Click({
#
# ## Create the "Computer Restart Task" scheduled task
# Create-ReminderTask $NearestRestartTime
#
# ## We're done for now, just close the window.
# $Form.Close()
# })
## This is the button that displays the nearest time to schedule a reboot
$btnNearestTime = New-Object System.Windows.Forms.Button
$btnNearestTime.Text = $RebootNowText
$btnNearestTime.Width = 130
$btnNearestTime.Height = 30
$btnNearestTime.Location = New-Object System.Drawing.Point(45,310)
$btnNearestTime.Font = 'Microsoft Sans Serif,11'
$btnNearestTime.Add_Click({
## Create the "Computer Restart Task" scheduled task
Restart-Computer
## We're done for now, just close the window.
$Form.Close()
})
$Form.AcceptButton = $btmNearestTime
$Form.Controls.Add($btnNearestTime)
## This is the placebo button, it just closes the form when clicked.
## The reminder schedule has already been created, so this button doesn't need to do anything.
$btnPlacebo = New-Object System.Windows.Forms.Button
$btnPlacebo.Text = $PlaceboText
$btnPlacebo.Width = 130
$btnPlacebo.Height = 30
$btnPlacebo.Location = New-Object System.Drawing.Point(225,310)
$btnPlacebo.Font = 'Microsoft Sans Serif,11'
$btnPlacebo.Add_Click({ $Form.Close() })
$Form.Controls.Add($btnPlacebo)
[void]$Form.ShowDialog()
}
#endregion FUNCTIONS }
#region begin SCRIPTS {
## This script is used to remind the user to restart their computer
$ReminderTaskScript = '&{
## code here
}'
#endregion SCRIPTS }
## Define custom company name, logo, window title, and messages
#region begin CUSTOMIZATIONS {
## The following 2 settings are specific to your company
## This is the name of your company.
$CompanyName = "Emberkom"
## This is the short or abbreviated name of your company
## It's used to prefix the scheduled tasks so they're easy to identify
$CompanyAbbr = "EK"
## This is the URL to your company logo.
## If your company logo cannot be downloaded, $CompanyName will be used instead.
## If the image you specify is larger than 380x90, it will shrink to fit that size.
$LogoURL = 'https://emberkom.s3.amazonaws.com/management/scripts/resources/small-web-logo.jpg'
## This script will start by copying itself into a local directory on the computer.
## This will allow the scheduled tasks this script creates to call it later.
## Directory to copy this script into (do not put in an ending "\")
$CopyDirectory = "${Env:ProgramData}\${CompanyName}\Scripts"
## The name of the file this script should have when copied to the $CopyDirectory
$CopyFilename = "Set-RebootSchedule.ps1"
## The following 6 settings control text displayed on the form when prompting the user to choose a time to restart their computer
## The title of the window
$WindowTitle = "Restart Required - ${CompanyName}"
## The message displayed to the user when -SysPerf is called.
$SysPerfText = "It looks like your computer isn't performing like it should.`n`nRestarting it will help to resolve some of the problems its been having."
## The message displayed to the user when -OSUpdate is called.
$OSUpdateText = "Good news!`n`nYour computer has recently installed some updates and it needs to be restarted soon."
## Thhe message displayed to the user when -Uptime is called.
$UptimeText = "It looks like your computer has been on for more than $(Get-UptimeDays) days.`n`nIt's probably best to restart soon so it doesn't start causing problems for you."
## This is the message displayed just above the buttons - it should ask the user how they want to proceed
$ProceedText = "When can we make this happen?"
## This is the text for a placebo button. Regardless of whether the user clicks this button or not,
## a reminder has already been created. Clicking the button will just close the form.
## This is simply because I don't want the user to be able to dismiss restarting their
## computer, but I still want them to feel like they're involved and have some control
## over the situation. Automatically reminding them some other time won't hurt anything.
$PlaceboText = "Remind me later"
############### NEW SETTINGS ###############
## The message on the button that immediately restarts the computer
$RebootNowText = "Restart Now"
## When to begin notifying the user they need to reboot their computer
$StartReminderAt = Get-Date -Hour 9 -Minute 0 -Second 0
## When to stop notifying the user to reboot.
## If the next notification to restart is scheduled to happen after this time,
## it will be automatically rescheduled until $StartReminderAt of the following day.
$StopReminderAt = Get-Date -Hour 16 -Minute 50 -Second 0
## The amount of time between restart notifications
$ReminderInterval = New-TimeSpan -Hours 2 -Minutes 45
## This is some small amount of time in the future where the user can schedule a reboot. This isn't used often, but is used
## The formula used here will add 20 minutes to the current time and round it to the nearest 5 minute mark.
## I referenced the code by Tony Hinkle in this post:
## https://stackoverflow.com/questions/39728485/rounding-down-minutes-to-the-nearest-10-minutes#39728699
$ShortTimeFromNow = (Get-Date).AddMinutes(-(((Get-Date).Minute % 5) - 20))
## The following 5 settings configure the date and time this script will use to schedule reminders and restarts
## All times will be today's date at the hour, minute, and second specified.
## Specify the business start time.
## This time is used to remind the user to restart their computer. The reminder won't show up until at least the value defined here.
## The $ReminderDelay time will be added to $StartOfBusiness to come up with the time to remind the user to restart their computer.
$StartOfBusiness = Get-Date -Hour 8 -Minute 30 -Second 0
## Specify the lunch time
## This time is used to schedule a restart all through the week and weekends.
$LunchTime = Get-Date -Hour 12 -Minute 0 -Second 0
## Specify the afternoon time
## This time is used to schedule a restart only on the weekends and is based on $LunchTime
$AfternoonTime = $LunchTime + (New-TimeSpan -Hours 2 -Minutes 30)
## Specify the close-of-business time. In reality this should be a little bit before the actual close of business time.
## This time is used to remind to restart only during the weekdays. This should be just before everyone starts leaving the office.
$CloseOfBusiness = Get-Date -Hour 16 -Minute 50 -Second 0
## Specify the late-at-night time
## This time is used to schedule a restart only during the weekdays. You should use a time when users are least likely to work
$LateAtNight = Get-Date -Hour 22 -Minute 0 -Second 0
## Specify delay after the $StartOfBusiness when the user will be reminded to restart
## If the user does not restart, this is used to delay the reminder until most people are in the office
## For example: if $StartOfBusiness is 8am, but most people aren't in the office until 8:30am,
## you'll want to specify a value of 30 minutes here.
## They probably don't want to come in and immediately see a reminder to restart their computer. Let them get coffee first :-)
$ReminderDelay = New-TimeSpan -Minutes 40
## The next two settings define the week for your customer.
## If their weekend is not Saturday and Sunday, define that here.
## Weekend days
$WeekendDays = @("Saturday","Sunday")
## Week days
$WeekDays = @("Monday","Tuesday","Wednesday","Thursday","Friday")
## The next two settings define the 2-day reminders and the 1-day reminders.
## On the day this script is run, a reminder is automatically created.
## If the user closes the window or clicks the placebo button, the reminder is already created
## for either the next day, or 2 days from now.
## If you changed the previous 2 settings to specify different weekend and week days,
## you'll probably want to change this setting too.
## The idea behind this is to guide the user to restarting their computer sooner rather than later.
## The default options will push them towards restarting at the end of the work week, but if the
## script runs on the weekend, the reminder won't bother them again until the start of the work week.
## Specify the 2-day reminder days (user will be reminded 2 days after the days in this setting)
$TwoDayReminderDays = @("Monday","Tuesday","Wednesday","Saturday")
## Specify the 1-day reminder days (user will be reminded the day after the days in this setting)
$OneDayReminderDays = @("Thursday","Friday","Sunday")
#endregion CUSTOMIZATIONS }
## This is where we do everything needed to either prompt or remind the user to restart their computer
## This will involve copying the script locally, checking for existing reminder priorities, etc...
#region begin PREFLIGHT {
## Copy this script to $CopyDirectory if it isn't being run from $CopyDirectory
If ( $MyInvocation.PSCommandPath -ne "${CopyDirectory}\${CopyFilename}" ) { Copy-ThisScript }
## Disallow this script to display to the user before we check the parameters
$AllowDisplay = $false
## If the last argument is -Task, then make sure we allow this script to display to the user
If ( $args[$args.Count - 1].ToString() -ieq "-Task" ) { $AllowDisplay = $true }
## If the last argument isn't -Task, then we need to create a scheduled task for 10 seconds from now to run this script
Else {
Write-Host "No Task"
}
#endregion PREFLIGHT }
## This is where we gather the necessary info and prompt the user to restart
#region begin DISPLAY_FORM
## Get the nearest time to schedule a restart
#$NearestRestartTime = Get-NearestRestartTime
## Get the next reminder time
$NextReminderTime = Get-NextReminderTime
##
## Display the form
If ( $AllowDisplay ) { Display-Prompt $SysPerfText }
#endregion DISPLAY_FORM