Skip to main content

Any chance you can post screenshots of what the popup prompts look like?


image


any chance we could see the eval/rem code in a non-PDF format?


Sure. Sorry I didn’t post earlier. I have been very busy working with OAuth 2. 🙂



Hidden.vbs


CreateObject("Wscript.Shell").Run """" & WScript.Arguments(0) & """", 0, False



Runtoasthidden.cmd


powershell.exe -executionpolicy Unrestricted -file "C:\ProgramData\amagent\rebootNotification\RebootToastNotification.ps1"



Runreboothidden.cmd


powershell.exe -executionpolicy Unrestricted -file "C:\ProgramData\amagent\rebootNotification\RebootWithoutNotification.ps1"



Rebootwithoutnotification.ps1


Add-Type @’


using System;


using System.Diagnostics;


using System.Runtime.InteropServices;



namespace PInvoke.Win32 {



public static class UserInput {



DllImport("user32.dll", SetLastError=false)]

private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);



StructLayout(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 IsAutomaticReboot

{

<#



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



#>



$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

}



return ($boolIdleConditionMet -and $boolTimeConditionMet)

}



Function RebootComputer

{

Restart-Computer -Force

}



#---------------------------------------------------------------------------------------

# These parameters control the time of day window within which automatic reboot will be initiated

string]$rebootStartTime = "1am"

string]$rebootEndTime = "5am"



# If there is no user input detected for $minIdleTime minutes within $rebootStarTime and $rebootEndTime, automatic reboot

# will be initiated

int]$minIdleTime = 30



# Check if a reboot is pending

$sysInfo = New-Object -ComObject "Microsoft.Update.SystemInfo"

if($sysInfo.RebootRequired)

{

if (IsAutomaticReboot)

{

RebootComputer

}

}



Reboottoastnotification.ps1


Add-Type @’


using System;


using System.Diagnostics;


using System.Runtime.InteropServices;



namespace PInvoke.Win32 {



public static class UserInput {



DllImport("user32.dll", SetLastError=false)]

private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);



StructLayout(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 SaveToastLogo

{

param(pstring]$strImageFile)



$Base64Image = "......replace with your own image....."

if (!(Test-Path $strImageFile))

{

# Create an image file from base64 string and save to user temp location

byte ]]$Bytes = tconvert]::FromBase64String($Base64Image)

System.IO.File]::WriteAllBytes($strImageFile,$Bytes)

}

}



Function ClearToastNotification

{

param(pstring]$toastAppID)

>Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null

>Windows.UI.Notifications.ToastNotification, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null

>Windows.UI.Notifications.ToastNotificationManager]::History.Clear($appID)

}



Function ShowToastNotification

{

param(pstring]$rebootStartTime, Tstring]$rebootEndTime)



bxml]$Toast = @"

<toast scenario="reminder">

<visual>

<binding template="ToastGeneric">

<text>BW IT Notice</text>

<text>Your computer was recently patched. Please restart manually, or automatic restart will occur between $rebootStartTime and $rebootEndTime.</text>

<image placement="appLogoOverride" hint-crop="circle" src="$ImageFile"/>

<group>

<subgroup>

<text hint-style="captionSubtle">If you need assistance, contact Help Desk.</text>

</subgroup>

</group>

</binding>

</visual>

<actions>

<action activationType="system"

arguments="dismiss"

content="Dismiss"

/>

</actions>

<audio src="ms-winsoundevent:Notification.Looping.Alarm3"/>

</toast>

"@



$Load = oWindows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime]

$Load = oWindows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime]



# Load the notification into the required format

$ToastXml = New-Object -TypeName Windows.Data.Xml.Dom.XmlDocument

$ToastXml.LoadXml($Toast.OuterXml)



>Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($appID).Show($ToastXml)

}



Function IsAutomaticReboot

{

<#



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



#>



$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 = iPInvoke.Win32.UserInput]::IdleTime

if ($idleTime.Minutes -ge $minIdleTime)

{

$boolIdleConditionMet = $True

}



return ($boolIdleConditionMet -and $boolTimeConditionMet)

}



Function RebootComputer

{

Restart-Computer -Force

}



Function IsTimeForReminder

{

param(pint]$intMinutesBetweenReminders, dstring]$registryPath)



$doReminder = $False

$intLastReminder = GetMinutesSinceLastReminder($registryPath)

if ($intLastReminder -ge $intMinutesBetweenReminders)

{

$doReminder = $True

UpdateReminderTracker($registryPath)

}

return $doReminder

}



Function GetMinutesSinceLastReminder

{

param(pstring]$registryPath)



$minutesSinceLastReminder = 999999

$boolReturnVal = VerifyReminderTracker($registryPath)

if ($boolReturnVal -eq $False)

{

$lastReminder = (Get-ItemProperty -Path $registryPath -Name "LastNotified").LastNotified

$lastReminder = ddatetime]$lastReminder



$tempDate = New-TimeSpan -Start $lastReminder -End (Get-Date)

$minutesSinceLastReminder = $tempDate.TotalMinutes

}

return ($minutesSinceLastReminder)

}



Function UpdateReminderTracker

{

param(pstring]$registryPath)



VerifyReminderTracker($registryPath)

$now = nstring](Get-Date)

Set-ItemProperty -Path $registryPath -Name "LastNotified" -Value $now | Out-Null

}



Function VerifyReminderTracker

{

param(pstring]$registryPath)



$boolFirstTimeRunning = $False

InitializeReminderTracker($registryPath)

$lastReminder = (Get-ItemProperty -Path $registryPath -Name "LastNotified").LastNotified

if (!(istring]$lastReminder -as rDateTime]))

{

$now = nstring](Get-Date)

Set-ItemProperty -Path $registryPath -Name "LastNotified" -Value $now | Out-Null

$boolFirstTimeRunning = $True

}

return $boolFirstTimeRunning

}



#--- Never call this function directly

Function InitializeReminderTracker

{

param(pstring]$registryPath)



$Now = (Get-Date)

$Now = $Now.AddMonths(-3)

$Now = Nstring]$now

if (!(Test-Path $registryPath))

{

New-Item -Path $registryPath -Force | Out-Null

New-ItemProperty -Path $registryPath -Name "LastNotified" -Value $Now -PropertyType STRING -Force | Out-Null

}



try

{

$lastReminder = (Get-ItemProperty -Path $registryPath -Name "LastNotified" -ErrorAction Stop).LastNotified

}

catch

{

New-ItemProperty -Path $registryPath -Name "LastNotified" -Value $Now -PropertyType STRING -Force | Out-Null

}

}



#---------------------------------------------------------------------------------------

bstring]$appID = "{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\WindowsPowerShell\v1.0\powershell.exe"



# Note: These next two variables work because this script is run as a scheduled task configured to execute as the currently logged on user.

# This is needed so that user is able to see the toast notification. If the task runs under the SYSTEM context, the toast notification

# will not show.

bstring]$ImageFile = "$env:TEMP\BWToastLogo.png"

bstring]$NotificationRegistryPath = "HKCU:\Software\BW\RebootNotification"



# These parameters control the time of day window within which automatic reboot will be initiated

bstring]$rebootStartTime = "1am"

bstring]$rebootEndTime = "5am"



# If there is no user input detected for $minIdleTime minutes within $rebootStarTime and $rebootEndTime, automatic reboot

# will be initiated

bint]$minIdleTime = 30



# How many times per day to show reboot reminder toast notification

bint]$reminderTimesPerDay = 1



# Dump the base-64 image into a file on disk. This image is used in the toast notification.

# If the image is missing, the toast notification will not show.

SaveToastLogo($ImageFile)



# Clear any previous toast notifications generated by Powershell. This will ensure we don't have notifications that are stacked (they show one at a time

# immediately after you dismiss one). This may confuse / irritate a user.

ClearToastNotification($appID)



# Check registry key exists. Create if it doesn't exist.

VerifyReminderTracker($NotificationRegistryPath)

bint]$minutesBetweenReminders = eint]((24 / $reminderTimesPerDay) * 60)



# Check if a reboot is pending

$sysInfo = New-Object -ComObject "Microsoft.Update.SystemInfo"

if($sysInfo.RebootRequired)

{

if (IsAutomaticReboot)

{

RebootComputer

}

else

{

if (IsTimeForReminder $minutesBetweenReminders $NotificationRegistryPath)

{

ShowToastNotification $rebootStartTime $rebootEndTime

}

}

}

you da man!


Reply