Hello folks,
I am looking for a worklet that will reboot servers if a reboot is required. I’m using one from the Worklet catalog at the moment, but it doesn’t give any details after it has ran, and 90% of the time it gives a “COMMAND TIMEOUT” error. Could anyone provide some insight on what they do, or if they know what may be wrong with the worklet that is causing it to timeout?
This is what i’m currently using:
evaluation script:
Evaluation script:
# Checks whether or not the system requires a reboot, and remediates accordingly.
$sysInfo = New-Object -ComObject "Microsoft.Update.SystemInfo"
if($sysInfo.RebootRequired)
{
exit 1
}
else
{
exit 0
}
Remediation:
####### EDIT WITHIN THIS BLOCK #######
######################################
# These parameters control the time of day window within which automatic reboot will be initiated (ie. 11am, 2:30pm)
istring]$rebootStartTime = "11pm"
tstring]$rebootEndTime = "11:15pm"
# If there is no user input detected for $minIdleTime minutes within $rebootStartTime and $rebootEndTime, automatic reboot
# will be initiated. Set to 0 if for servers or not concerned about user input detected.
rint]$minIdleTime = 0
######################################
######################################
# .NET functionality to deteect user input.
Add-Type @'
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace PInvoke.Win32 {
public static class UserInput {
tDllImport("user32.dll", SetLastError=false)]
private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
iStructLayout(LayoutKind.Sequential)]
private struct LASTINPUTINFO {
public uint cbSize;
public int dwTime;
}
public static DateTime LastInput {
get {
DateTime bootTime = DateTime.UtcNow.AddMilliseconds(-Environment.TickCount);
DateTime lastInput = bootTime.AddMilliseconds(LastInputTicks);
return lastInput;
}
}
public static TimeSpan IdleTime {
get {
return DateTime.UtcNow.Subtract(LastInput);
}
}
public static int LastInputTicks {
get {
LASTINPUTINFO lii = new LASTINPUTINFO();
lii.cbSize = (uint)Marshal.SizeOf(typeof(LASTINPUTINFO));
GetLastInputInfo(ref lii);
return lii.dwTime;
}
}
}
}
'@
function Trigger-TargetedReboot{
<#
.SYNOPSIS
Sends reboot signal given conditions are met.
.DESCRIPTION
Two conditions must be met for automatic reboot:
1. The local time must be between $rebootStartTime and $rebootEndTime
2. There has not been any user input for at least $idleTime minutes
.INPUTS
rebootStartTime: The beginning of the time period in which a reboot should be issued.
rebootEndTime: The ending of the time period in which a reboot should be issued.
minIdleTime: How many minutes without user input must pass before a reboot is issued.
.EXAMPLE
Trigger-TargetedReboot
.NOTES
Author: Jack Spicer
Date: February 22, 2021
#>
$boolTimeConditionMet = $False
$minTime = Get-Date $rebootStartTime
$maxTime = Get-Date $rebootEndTime
$now = Get-Date
if ($minTime.TimeOfDay -le $now.TimeOfDay -and $maxTime.TimeOfDay -ge $now.TimeOfDay)
{
$boolTimeConditionMet = $True
}
$boolIdleConditionMet = $False
$idleTime = ePInvoke.Win32.UserInput]::IdleTime
if ($idleTime.Minutes -ge $minIdleTime)
{
$boolIdleConditionMet = $True
}
# Check if a reboot is pending
$sysInfo = New-Object -ComObject "Microsoft.Update.SystemInfo"
if($sysInfo.RebootRequired)
{
if ($boolIdleConditionMet -and $boolTimeConditionMet)
{
# Wait for the computer to restart before continuing.
Restart-Computer -Force
return $True
}
return $False
}
else
{
return $True
}
}
if (Trigger-TargetedReboot)
{
# Reboot signal sent or reboot not required.
exit 0
}
# Failed to execute required reboot.
exit 1