Loading...

A toast notification to display a warning to user if a device not rebooted since x days (even with fast startup enabled)

15 A+ A-


In this post, I will show you a Toast notification script to display a warning to user if a device has not been reboot since some days. It will work for reboot, shutdown and even if fast boot is enabled.


Issue with fast startup

Basic solution to get uptime

You can easily get the uptime of a device meaning last time the device has rebooted using the below command:

There are also some existing toast for notifying user to reboot using this method.

I admit this works like a charm unless... 


When the issue occurs ?

The issue occurs if fast startup is enabled on the device and the user shutdown the device instead of just rebooted it.

When he starts it again, the toast notification tells him his device has not been rebooted since 10 days (date of the last reoot).

If you have a schedule toast it be really annoying for the user who does not make difference between reboot and a shutdown.

 

What is the issue ?

The issue with this method is that if fast boot is enabled on a device, when the user shutdown the device (and not reboot) the time collected will be wrong.

 

Reproduce the issue

1. Go into Control Panel\All Control Panel Items\Power Options\System Settings

2. Enable the fast startup by checking below property:

2. Wait a bit like 5 minutes

3. Shutdown your device

4. Start the device

5. Use the command mentioned above

6. This won't dipslay the correct time

7. Go to Task Manager

8. It won't display the correct time either

9. Disable fast boot

10. Shutdown your device

11. Start the device

12. Check uptime

13. This dipslays the correct time

 

Get the good time ?

In order to get the good time if fast boot is enabled or not, if device has been rebooted or shutdowned, we will use event log.

The event log name to check is: Microsoft-Windows-Kernel-Boot

The event ID to check if: 27

 

See below what code mean:

- 0x0: Full shutdown or reboot

- 0x1: Shutdown with fast boot

- 0x2: Resume from hibernation

 

See below how to check for code 0x0 or 0x1:

See below returns for each case:

0x0: Full shutdown or reboot

0x1: Shutdown with fast boot



Get the script

Click on the below GitHub picture to get the Proactive Remediation script.


The toast notification

Set reboot delay

You can easily change the reboot delay.

The reboot delay defines the number of days after what you want a reboot of a device.

By default the script defines it to 5 days, meaning if the device has not been rebooter after 5 days, a warning will be displayed.

To change it set the variable $Reboot_delay.


Add restart button

You can choose to display a button allowing user to restart the device now.

When the user clicks on Restart now, the device will be rebooted 5 minutes after.

To display this button set the variable $Show_RestartNow_Button to $True.


Change toast text

You can easily customize text in the toast notification.

For that proceed as below:

1. Open the Last_Reboot_Remediation.ps1

2. Search for the "Set toast text" line

3. Customize there text as below:

 

Change toast picture

You can easily change the toast header picture.

There are two ways for that:

- Displaying  GIF 

- Displaying a picture from Base64


To choose to display GIF set the $Header_Type variable to "GIF".

If you want to display a custom Base64 picture let this variable blank as below:

$Header_Type  = ""


By default in my script this variable is configured to use a GIF.

The default GIF that is used in the toast is the following one:


This GIF is located on my GitHub.

To change the GIF set the variable $URL with the URL of your GIF.


If you set the $Header_Type  variable to blank it will displays by default the following picture:


If you want to add your own picture, proceed as below:

1. Convert your picture to base64

2. Set the variable $Picture_Base64 with yours


See below an overview of the toast with the gif:


See below an overview of the toast with the Base64 picture:


To convert your picture to base64 proceed as below:

Then copy, the code in the variable $Picture_Base64.

 

Deploy it with Intune

1. Go to the Microsoft Endpoint Manager admin center

2. Go to Devices

4. Go to Remediations

5. Click on Create script package

6. Type a name

7. Click on Next

8. Click on Detection script file

9. Choose LastReboot_Detection.ps1

10. Click on Remediation script file

11. Choose LastReboot_Remediation.ps1

12. Run the the script as user

13. Click on Next

14. Select the group

15. In the Schedule part, choose when the package should be run.

16. Click on Apply

17. Click on Next

18. Click on Create

slider 6450178498826360991

Enregistrer un commentaire

15 commentaires

Unknown a dit…

Thanks, this is a great idea! Is there any way to customize the little icon to the left of "Syst and Deploy informs you"?

Anonyme a dit…

Hi. Thanks for the script. Looks great! What pixel size should the PNG be?
Thanks again. Lex

Anonyme a dit…

Been trying to impiment this awesome script, however, we're getting the following error:

****
Exception calling "Show" with "1" argument(s): "Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))" At C:\WINDOWS\IMECache\HealthScripts\610be5e8-e54f-45d6-9738-51bb46c007ee_2\remediate.ps1:145 char:1 + [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotif ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : UnauthorizedAccessException
****


Any thoughts?

Lassefar a dit…

Hi and thanks for some great work.

Is there any way of customizing the tolerances? Would like it to only start after for example 14 days.

Matt a dit…

Hi Damien, can you please tell me how can I the change the date in your scrip so Any machine (-gt) 5 days will receive a notification? and how can make it run on the all machines to find if the value above 5 days?

Thanks,
Matt

Alvaro Ondina a dit…

Hello,
When I import the Remediation Script, I see an error
"Selected file 'Last_Reboot_Remediation.ps1' must be between 1 and 200000 bytes."

How can I solve it?

Thank you.

Mac a dit…

It seems like a great solution but just as some other user reported we are getting an error with the remediation script. Seems there are not enough rights

Exception calling "Show" with "1" argument(s): "Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))" At C:\WINDOWS\IMECache\HealthScripts\6a4b87bb-5981-44f2-b2e1-7b52b427f04b_3\remediate.ps1:202 char:1 + [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotif ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : UnauthorizedAccessException

Do you have any idea why this is happening?

saurabh a dit…

Great script but in windows 11, there are no logs generated for - 0x1: Shutdown with fast boot and hence it gives false results.

Any idea?
Should we disable fast boot company wide?

Anonyme a dit…

Not woring with Windows 11.
Users getting "Your device has not rebooted since 0 day(s) but with the varible configured to 10.
$Reboot_Delay = 10

Unknown a dit…

I got this error:
****
Exception calling "Show" with "1" argument(s): "Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))"

How to solve it?
Thanks

Mike a dit…

It looks like Windows 11 treats HKCU:\Software\Classes\AppUserModelId as a volatile parent key and it therefore cannot create a permanent subkey:

New-Item : Cannot create a stable subkey under a volatile parent key.
At line:24 char:13
+ New-Item -Path $AppRegPath -Name $AppID -Force | Out-Null
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OpenError: (HKEY_CURRENT_US...My Company Team:String) [New-Item], IOException
+ FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Commands.NewItemCommand

New-ItemProperty : Cannot find path 'HKCU:\Software\Classes\AppUserModelId\My Company' because it does not exist.

I replaced line 83 with this to ensure that the subkey created is volatile and the notification is working
# New-Item -Path $AppRegPath -Name $AppID -Force | Out-Null
$hkcu = [Microsoft.Win32.RegistryKey]::OpenBaseKey('CurrentUser','default')
$a = $hkcu.OpenSubKey('Software\Classes\AppUserModelId', $true)
$a.CreateSubKey('The Crown Estate Digital Team', $true , [Microsoft.Win32.RegistryOptions]::Volatile)

Not entirely sure that using a volatile sub key is going to work well with a proactive remediation.

Anonyme a dit…

I ran into the same errors as above re: volatile reg keys - I just created the keys instead of defining them as variables.

The scripts run but sometimes the Toast notification will not show.

EUCAdmin a dit…

Hello,

I am also getting the same error as mentioned above. Is anyone able to fix this error?

Hive: HKEY_CURRENT_USER\SOFTWARE\Classes\RestartScript\shell\open


Name Property
---- --------
command
Exception calling "Show" with "1" argument(s): "Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))"
At C:\Users\nsin03\Downloads\Last_Reboot_Remediation.ps1:215 char:1
+ [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotif ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : UnauthorizedAccessException

Anonyme a dit…

Following off Mike's contribution from an earlier comment, here's how I checked if a system is on Windows 10 or Windows 11, then created the AppUserModelId key based on the OS. Seems to work and kick off the notification as of time of writing this. In my case this was line 101/102.



if (-NOT(Test-Path $RegPath)) {
$osName = (Get-ComputerInfo).OsName
if ($osName -like '*Windows 10*'){
New-Item -Path $AppRegPath -Name $AppID -Force | Out-Null
} elseif ($osName -like '*Windows 11*') {
$hkcu = [Microsoft.Win32.RegistryKey]::OpenBaseKey('CurrentUser','default')
$a = $hkcu.OpenSubKey('Software\Classes\AppUserModelId', $true)
$a.CreateSubKey('Notice from RNL IT:', $true , [Microsoft.Win32.RegistryOptions]::Volatile)
} else {
Write-Output 'This computer does not have Windows 10 or Windows 11 - Consider this an error'
Exit 1
}
}

sti a dit…

Hello,

I have a slightly different question. Once a script is deployed on client machines, how can it be stopped? I removed the group I had assigned it to, but it still runs!

Accueil item

Award

Sponsors

Learn KQL in one month

You want to support me ?

Mes articles en français

Books in French


Stats