Laptop Mandatory Reboot Management

Managing laptops in certain environments can be daunting. Reboots are a must every now and then, especially for monthly windows updates. With the sleep and hibernate features being enabled, the chances of a user rebooting a laptop become far less. A laptop can go weeks and even months without a reboot. Working in the legal industry, as I do, adds to the complexity of forcing reboots as you have the issue of not causing a reboot during a hearing or during a client meeting for instance. You want to be as unobtrusive as possible. You might say that this is not needed as SCCM could be setup to automatically perform this same function on a regular schedule. That is true. Where this becomes valuable is when you don't want to force a reboot on users that regularly reboot their machines. If they are already doing this, which we have a fair number of users that do, then there is no need to reboot an additional time that will inconvenience them.

To make this process as unobtrusive as possible, I have written the following two PowerShell scripts that work in conjunction with SCCM 2012 to give users the leisure of a full business day to reboot the machine. One script is the custom detection method and the other is the installer. 

The custom detection method works by reading the last event viewer 1074. It looks at the date of the ID and then sees if it is 14 days or older. This can be set to any number of days other than the 14 my firm has chosen. If it is 14 days old, the script then sets the registry key Rebooted to a DWORD value of 1 and fails the detection method. When the method fails, SCCM will then run the second PowerShell script. 

The second script operates by running the same detection method. Once it detects the same values, it resets the Rebooted Key to 0 and then returns the error code 3010 back to SCCM. SCCM then reruns the detection method. The detection method sees there has been 14 days or more and the Rebooted key is set to 0. It returns and error code 0 back to SCCM with a write-host of "Success". This tells SCCM the application ran successfully and to now process with the soft reboot, which was required by the 3010 return code. 

The final part is to configure the Computer Restart under the SCCM client settings. I configured ours to be 480 minutes, which is 8 hours, with a mandatory dialog window that cannot be closed the final 60 minutes. 

When the system reboots, the custom detection method runs again and sees there is a new 1074 entry in the event viewer, along with the registry key Rebooted being a 0, therefor it shows successfully installed. As the days progress and SCCM reruns the custom detection method, it will rerun the application script to reboot the machine again if the machine is not rebooted in the 14 allotted days. If the user reboots the machine every week, the SCCM application will never reboot the machine. 

Here are the links to the two scripts:

 <#  
.SYNOPSIS
SCCM Reboot Detection Method
.DESCRIPTION
This script will read the last time a system rebooted from the event
viewer logs. It then calculates the number of days since that time. If
the number of days equals or exceeds the RebootThreshold variable, the
script will exit with a return code 0 and no data output. No data output
is read by SCCM as a failure. If the number of days is less than the
RebootThreshold, then a message is written saying the system is within
the threshold and the script exits with a return code of 0. SCCM reads
an error code 0 with data output as a success.
.Author
Mick Pletcher
.Date
30 June 2015
#>

$RebootThreshold = 14
$Today = Get-Date
$Architecture = Get-WmiObject -Class Win32_OperatingSystem | Select-Object OSArchitecture
$Architecture = $Architecture.OSArchitecture
$LastReboot = get-winevent -filterhashtable @{logname='system';ID=1074} -maxevents 1 -ErrorAction SilentlyContinue
if ($Architecture -eq "32-bit") {
if ((Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Reboot") -eq $false) {
New-Item "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Reboot" | New-ItemProperty -Name Rebooted -Value 0 -Force | Out-Null
}
$Rebooted = Get-ItemProperty -Name Rebooted -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Reboot"
$Rebooted = $Rebooted.Rebooted
} else {
if ((Test-Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Reboot") -eq $false) {
New-Item "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Reboot" | New-ItemProperty -Name Rebooted -Value 0 -Force | Out-Null
}
$Rebooted = Get-ItemProperty -Name Rebooted -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Reboot"
$Rebooted = $Rebooted.Rebooted
}
if ($LastReboot -eq $null) {
$Difference = $RebootThreshold
} else {
$Difference = New-TimeSpan -Start $Today -End $LastReboot.TimeCreated
$Difference = [math]::Abs($Difference.Days)
}
#Write-Host "Reboot Threshold:"$RebootThreshold
#Write-Host "Difference:"$Difference
#Write-Host "Rebooted:"$Rebooted
if (($Difference -lt $RebootThreshold) -and ($Rebooted -eq 0)) {
Write-Host "Success"
exit 0
}
if (($Difference -ge $RebootThreshold) -and ($Rebooted -eq 1)) {
Write-Host "Success"
exit 0
}
if (($Difference -ge $RebootThreshold) -and ($Rebooted -eq 0)) {
exit 0
}
if (($Difference -lt $RebootThreshold) -and ($Rebooted -eq 1)) {
exit 0
}




 <#  
.SYNOPSIS
SCCM Mandatory Reboot
.DESCRIPTION
This script will read the last time a system rebooted from the event
viewer logs. It then calculates the number of days since that time. If
the number of days equals or exceeds the RebootThreshold variable, the
script will change the registry key Rebooted to a 0. It then exits with
an error code 3010, which tells SCCM 2012 to perform a soft reboot.
.Author
Mick Pletcher
.Date
30 June 2015
#>

#Declare Global Variables
Set-Variable -Name Architecture -Scope local -Force
Set-Variable -Name Difference -Scope Local -Force
Set-Variable -Name LastReboot -Scope Local -Force
Set-Variable -Name Rebooted -Scope Local -Force
Set-Variable -Name RebootThreshold -Scope Local -Force
Set-Variable -Name Today -Scope Local -Force

$Architecture = Get-WmiObject -Class Win32_OperatingSystem | Select-Object OSArchitecture
$Architecture = $Architecture.OSArchitecture
if ($Architecture -eq "32-bit") {
if ((Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Reboot") -eq $false) {
New-Item "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Reboot" | New-ItemProperty -Name Rebooted -Value 0 -Force | Out-Null
}
$Rebooted = Get-ItemProperty -Name Rebooted -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Reboot"
$Rebooted = $Rebooted.Rebooted
} else {
if ((Test-Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Reboot") -eq $false) {
New-Item "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Reboot" | New-ItemProperty -Name Rebooted -Value 0 -Force | Out-Null
}
$Rebooted = Get-ItemProperty -Name Rebooted -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Reboot"
$Rebooted = $Rebooted.Rebooted
}
$RebootThreshold = 14
$Today = Get-Date
$LastReboot = get-winevent -filterhashtable @{logname='system';ID=1074} -maxevents 1 -ErrorAction SilentlyContinue
if ($LastReboot -eq $null) {
$Difference = $RebootThreshold
} else {
$Difference = New-TimeSpan -Start $Today -End $LastReboot.TimeCreated
$Difference = [math]::Abs($Difference.Days)
}
if (($Difference -ge $RebootThreshold) -and ($Rebooted -eq 0)) {
if ((Test-Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Reboot") -eq $true) {
Set-ItemProperty -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Reboot" -Name Rebooted -Value 1 -Type DWORD -Force
$Rebooted = Get-ItemProperty -Name Rebooted -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Reboot"
$Rebooted = $Rebooted.Rebooted
} else {
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Reboot" -Name Rebooted -Value 1 -Type DWORD -Force
$Rebooted = Get-ItemProperty -Name Rebooted -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Reboot"
$Rebooted = $Rebooted.Rebooted
}
}
if (($Difference -lt $RebootThreshold) -and ($Rebooted -eq 1)) {
if ((Test-Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Reboot") -eq $true) {
Set-ItemProperty -Name Rebooted -Value 0 -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Reboot" -Type DWORD -Force
$Rebooted = Get-ItemProperty -Name Rebooted -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Reboot"
$Rebooted = $Rebooted.Rebooted
} else {
Set-ItemProperty -Name Rebooted -Value 0 -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Reboot" -Type DWORD -Force
$Rebooted = Get-ItemProperty -Name Rebooted -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Reboot"
$Rebooted = $Rebooted.Rebooted
}
Write-Host "System is within"$RebootThreshold" Day Reboot Threshold"
}
Write-Host "Reboot Threshold:"$RebootThreshold
Write-Host "Difference:"$Difference
Write-Host "Rebooted:"$Rebooted

0 Response to "Laptop Mandatory Reboot Management"

Post a Comment