Safe Restart Script

This is a script that reboots if day and time criteria are met and if the uptime is less than a given number of days.PoSh

I had, what I thought, was a simple request.   I wanted any servers that had not rebooted as part of the monthly SCCM patch cycle to reboot at the end of the maintenance window.  This way I know that the servers don’t have any unfinished patching and the servers have a reboot in the last 30 days.  These are Windows servers and I’m old school, I like to routinely reboot them.

What I ended up with was a command file that ran a shutdown /r.  This was added to each patch collection as a required deployment at the end of the maintenance windows.  It worked, but had a couple issues.  First and most significant; under certain, easily repeatable circumstances, this deployment would run outside the maintenance window.  This caused some unexpected reboots at inopportune times.  It also ran even if the server had a clean restart after patches were applied.  This was just unnecessary.

I created a script that would use logic before it rebooted to prevent these issues.  My goal is to prevent reboots outside a defined time (2 to 4 AM), I also want it to reboot only on a given day of the month.  The first two lines of the script below  gets the current day of the month and hour when the script runs.

[int]$day = get-date -format dd
[int]$hour = get-date -format HH

Next, I don’t want to reboot if it already has as part of the patching process.  To do that, I first need to identify how long it has been running.  The next two lines of code gets the uptime by number of days.  If the server has been running for less than 24 hours it returns 0.

$os=Get-WmiObject win32_operatingsystem
$uptime = ((get-date) - ($os.ConvertToDateTime($os.lastbootuptime))).Days

The next two lines set the day the server can reboot ($rebootDay).  In this example it will only reboot on the 19th of the month.  The reboot age ($rebootAge) sets the minimum number of days the server has to be running to get rebooted.  With the reboot age of 1, the server uptime needs to be longer than a day to qualify for a reboot.

[int]$rebootDay = 19
[int]$rebootAge = 1

Lastly, the script will check three conditions and if none of them are met, it will reboot the server.   I added the parameters for the reboot hour into the script, but that could easily be a variable.   For testing I changed the -force parameter on the restart-computer command with -whatif.

Future plans are to write the output to the event log for better diagnostics.  I will publish once finished.

Full Script:

#get the current day of the month and hour
 [int]$day = get-date -format dd
 [int]$hour = get-date -format HH
#get the number of days the server has been running. Returns "0" if less than 24 hours
 $os=Get-WmiObject win32_operatingsystem
 $uptime = ((get-date) - ($os.ConvertToDateTime($os.lastbootuptime))).Days
#declare the day of the month for a reboot
 [int]$rebootDay = 19
#set the minimum days before reboot
 [int]$rebootAge = 1
If($hour -lt 2 -or $hour -gt 4){ Write-Host "Will not reboot, outside of maintenance hours" }
 ElseIf($day -ne $rebootDay) { Write-Host "Will not reboot, outside of maintenance day" }
 ElseIf($uptime -lt $rebootAge) { Write-Host "Will not reboot, rebooted within 24 hours" }
 Else{
(restart-computer -force)
}

*This script is “as is” with no warranties.  Test it before you trust it!

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.