Windows as a Service: Remind users of pending Windows upgrades using Windows toast notifications, part 3

Introduction

UPDATE: The script used here has been severely updated: https://www.imab.dk/windows-10-toast-notification-script/. The scenario described here is still relevant though, so I recommend that you still read through this ๐Ÿ™‚

This will be a small but exciting contribution to my ‘Windows as a Service’ series!

The usual story here is, that everyone wants to add moreย user-friendliness to the whole experience around Windows Servicing.

End-users generally doesn’t care about new versions of Windows and they also, generally speaking, find interruptions in their work annoying, especially if those interruptions come unexpected.

So we come up with clever solutions to solve those problems and this will be an addition to that; remind the user with a big nice Windows toast notification when a Windows upgrade is pending. This is for the obvious reminder, but also to lure the end-user into a voluntary participation.

Find some of my previous WaaS posts here:

Part 1: https://www.imab.dk/windows-as-a-service-sharing-my-precache-and-in-place-upgrade-task-sequences-part-1/
Part 2: https://www.imab.dk/windows-as-a-service-sharing-my-precache-and-in-place-upgrade-task-sequences-part-2/

What Is This?

What is this and how does it work? I’m not the first person to advocate for the use of the toast mechanism in Windows 10 and I’m most certainly not the last.

Trevor Jones atย https://smsagent.blog/ has again created something inspiring, as well as the guys behindย https://automationsynd.github.io/. Both solutions involves using toast notifications in Windows 10 with SCCM.

Needless to say, I also ended up feeling the urge and put something together which I’m using in my own WaaS setup. The effect of the toast is astonishing. I will elaborate later.

Download

This is the delicious magic. Download the script and open it with your favorite ISE and study it. I will elaborate where necessary in the next section.

IMPORTANT NOTE: The script is tailored to a requirement of having the SCCM client installed. This is the entry in the registry around which app (Read: Software Center) that is doing the notification. If you don’t have the SCCM client installed, the toast won’t display! Alternatively, use something else. I have included an alternative app in the end of the script for uses on devices without a SCCM client.

>> https://gallery.technet.microsoft.com/Windows-10-Toast-9f228eb1ย <<

Run The Script

Simply running above script as is, will yield below result. So far so good. The text is obviously customized by myself and for my needs. The reference to Yammer is for internal use.

Also, I’m afraid the picture I’m using here and which is included in the script as a base64 string is protected by copyright (it’s a paid picture), so I’m kind of preventing you from using it with an annoying watermark. Sorry ๐Ÿ™‚

Software Center

When hitting ‘Install now’, Software Center is launched opening an application, which again is launching the Task Sequence. This is something I have covered in a previous post here, on how to use Powershell App Deployment Toolkit to upgrade Windows 10:ย https://www.imab.dk/how-can-i-in-place-upgrade-to-windows-10-1803-using-powershell-app-deployment-toolkit-and-sccm-system-center-configuration-manager-part-2/

Note: Stating the obvious, I’m usingย Powershell App Deploymentย for recognizability AND some additional user-friendliness.

Software Center is launched because of this line in the script:

Where the ID is obtained in the Software Center following the instructions outlined in below illustration:

Image Used In The Toast

The base64 string for the image is generated using below Powershell. This is directly copied from Trevor Jones:ย https://smsagent.blog/

Note: The image used here in my toast is 360*150 pixels.

More Toast Options

I’ve included some more options in the Powershell script in the very end: Deadline information and snooze action.

Deadline is obviously meant to be aligned with a required deployment in SCCM. The snooze option is self-explanatory, though not something I intent to use.ย If you enable these “features”, the toast will look similar to the example below.

Putting It All To Use

The use case here is all based on my own environment and the way I do Windows Servicing. I’m using the Powershell script creating the toast in a old school package in SCCM. The few details are as following:

  • Save the New-ToastNotification.ps1 onto your source file library
  • Create a package with source files containing the Powershell script
  • Create a Program running the Powershell script in USER context
  • Command line:ย powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -File .\New-ToastNotification.ps1

Here are some screenshots of that process for your convenience, though it’s very basic SCCM:

Deployment

The toast notification is only relevant for computers/users who haven’t run the IPU already, but also computers where all of our Pre-Checks has passed and thus the same collection as we use for deploying the actual IPU TS.

EXCLUDING the collection, where the upgrade has completed (we don’t want to remind users about an installation they already completed):

Run the toast notification on a schedule. For example every day at noon or whatever suits your needs:

RESULT

These numbers are astonishing. The deployment of the Windows upgrade is so far only made AVAILABLE and thus, all of these succeeded upgrades are due to voluntary user participation after 1 day.

Now, this environment is still based on a mid-size company in Denmark, and I only manage 1000 (one thousand) devices roughly, but 18% user-participation is 18% – regardless of the size.

ENJOY!

38 thoughts on “Windows as a Service: Remind users of pending Windows upgrades using Windows toast notifications, part 3”

  1. What is stopping it from spamming the user with multiple notifications.
    If i just take the script and run it over and over again i get multiple notifications.

    So let’s say i leave the computer on over the weekend and when i come back i can have several of them?
    Or if a user just snooze for a week will it build up with one additional everyday?

    • Hey Fredrik, only one toast will be active at a time, though if the first isn’t dismissed the subsequent will displayed immediately thereafter. This is due to the nature of the toast being a reminder and doesn’t dismiss itself. You can change that behavior changing this: toast scenario=”reminder” from reminder to long or short.

      Snooze functionality isn’t well suited for a reminder which requires the user to dismiss it. So you are right, if you run this on a schedule and none of them are dismisses because the computer is left on over the weekend, the user might find several reminders to be dismissed. You will have to work around that, if that’s a scenario you don’t want.

      A great alternative is to use a scheduled task instead with a trigger that doesn’t build up several toast notifications ๐Ÿ™‚

  2. Hi,

    wonderfully simple and elegant solution. Thank you! Something like this should have been baked into SCCM in the first place.

    I can run this with no problem locally (ps admin, exec policy unrestricted) so the script is fine after my tweaks… when putting it to package it does not. I can see blue ps screen flashing rapidly when timer hits.

    PS execution policy is set to bypass in Client Settings.
    Program can run only when user is logged.
    Run mode > run with users rights
    Commandline is like yours.

    Something is wrong… and cant figure it out. Like you said, very basic stuff, but… ๐Ÿ™‚
    Any help appreciated!

      • Hi, it does the same with your original version. Could you show with more details how to do that package & deployment since the problem seems to be there most likely.

        Although it shouldโ€™t be so trivial. But iโ€™m obviously missing something.

        • What in particular are you interested in to see? Have you tried messing around with the visibility? Hidden, normal etc. The flashing PS screen doesn’t sound right. The script is fire and forget and it’s Windows doing the toast.
          You might want to add some troubleshooting steps in there to see how much of the script is actually being executed.
          I cannot reproduce the scenario on two different environments I’m afraid ๐Ÿ™

  3. Hi Martin,
    Thanks for excelent scriptv ๐Ÿ™‚ I’m trying to use your script for reminder to enduser for installation of Office update (monthly channel users). When i run the script localy everything work great; the user get redirected to correct update in Software Center when clicking the ‘Install now’ in the toast message. But when deploying it using SCCM nothing happens when user try to click ‘Install now’ in the notification toast. Any tips?

    • Hey, initial thought is around the context. How’s the Office update deployed vs. how’s the toast deployed. The toast runs in user context and thus browse the Software Center as the user. ๐Ÿ™‚

  4. Thanks for this.

    I’ve made some modifications so it takes parameter input for the Title, Body texts and a PackageID to make it a bit more flexible. The PackageID addition allows it to have it automatically add the deadline to the text rather than having to manually match it with a deployment:

    # Get the deadline:
    $Program = gwmi -namespace ‘root\ccm\ClientSDK’ -query “SELECT * FROM CCM_Program WHERE PackageID = '$PackageID‘”
    $Deadline = $Program.ConvertToDateTime($Program.Deadline)

    Then to ensure it doesn’t pop up when there’s no actual required deployment for the specified PackageID:

    # Display the toast notification
    If ($Program){
    [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($App).Show($ToastXml)
    }

    So now i only need one Package where i can just add/deploy Programs with command lines like this:
    “C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe” -Executionpolicy bypass -file .\New-ToastNotification.ps1 -PackageID “PS100E80” -Title “SomethingSomethingDarkside” -Body1 “This is paragraph 1, where we tell you stuff is happening.” -Body2 “This is paragraph 2, where we show you more text that you probably won’t read.”

  5. Hi Martin,

    Little issue I’ve run into that I’m hoping you fixed somewhere. How did you get past the Application showing as having failed immediately after it’s launched the TS to run the upgrade because the detection criteria for the app (the reg key UpgradeStatus being set to “0”) hasn’t been set at that point so the App thinks it’s failed.

    • Hi Andy, the first thought here was that it should fail and then have the detection method being applied during the TS and then run a application evaluation also during the TS, but I actually changed this in SCCM 1810 seeing we now have the option to repair applications. So I’ve reverted to correctly applying the dection method in the application but also enabled the repair option on the application in case something goes wrong and the TS is not being run. Hope that makes sense ๐Ÿ™‚

  6. Hi Martin,

    Have you thought about adjusting this script to handle Software Updates with Config Mgr? More specifically giving the user the option to choose the reboot time themselves within a deadline.
    The built-in notification system for reboot in the config mgr client needs improvement. I know that a lot of sysadmins who would love this feature.

    Let me know if that’s something you’d consider ๐Ÿ™‚

    • Yeah, the uses for the toast mechanism can be many and I currently have a few plan on expanding the options and flexibility of the script. Thank you for letting me know ๐Ÿ™‚

  7. Thanks for this, really useful.

    One point, I had to remove .\ from the command line for the toast notification to pop up (so it now reads powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -File New-ToastNotification.ps1) Otherwise I was getting an empty PowerShell window appear for a moment and then the package failed.

    One question too, is there a way to add some intelligence to the toast script so that it will only run on 1703? I have deployed to a user collection and it is showing up on computers that already have 1803.

    Thanks ๐Ÿ™‚

    • Thanks! Yes, I will add some logic to the script so it detects the OS. Initially I relied on the collection updating it’s members, but I see how it’s more convenient to have that in the script. Standby ๐Ÿ™‚

  8. Hi Martin.

    Thanks for all your work I will use it for the IPU Windows 10.

    I just have one problem when running the application to run the TS it says it installed en then it finished, it doesn’t start the actual task sequence. When starting this script manual then the actual TS will run.

    Harmen

  9. Hi Martin,

    Thanks for this great script!
    I have a problem with one thing that I cannot figure out.
    When I run this from sccm to a computer, it works when the user is local admin but not when the user don’t have admin rights. Is this by design and would it be possible to get this working for non admin user?

    • Hey, no, this is not something I require in the script. I’ve tested this for non-admin users and everything displays just fine ๐Ÿ™‚

      • Strange,
        Execution is complete for program Run Toast Notification. The exit code is 0, the execution status is Success
        i get this success in sccm log but then i get when i run it manually:
        VERBOSE: No HeroImage file set as parameter. Using local image file
        VERBOSE: No LogoImage file set as parameter. Using local image file
        VERBOSE: Successfully loaded C:\temp\GPFiles\Tools\config-toast-rebootpending.xml
        VERBOSE: Loading xml content from C:\temp\GPFiles\Tools\config-toast-rebootpending.xml into variables
        VERBOSE: Successfully loaded xml content from C:\temp\GPFiles\Tools\config-toast-rebootpending.xml
        VERBOSE: PendingRebootCheck set to True. Checking for pending reboots
        VERBOSE: Running Test-PendingRebootRegistry function
        VERBOSE: Check returned TRUE on ANY of the registry checks: Reboot is pending!
        VERBOSE: Running Test-PendingRebootWMI function
        VERBOSE: Computer has SCCM client installed – checking for pending reboots in WMI
        VERBOSE: Check returned false on checking WMI for pending reboot: Reboot is not pending!
        VERBOSE: Creating the xml for no dismiss button
        VERBOSE: Toast notification is used in regards to pending reboot registry. TestPendingRebootRegistry returned True
        VERBOSE: All good. Displaying the toast notification
        VERBOSE: Something went wrong when displaying the toast notification

  10. I get this error when i run it manually without admin rights and this works when i am admin…

    New-Object : Cannot create type. Only core types are supported in this language mode.
    At C:\temp\GPFiles\Tools\New-ToastNotification.ps1:615 char:17
    + $ToastXml = New-Object -TypeName Windows.Data.Xml.Dom.XmlDocument
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : PermissionDenied: (:) [New-Object], PSNotSupportedException
    + FullyQualifiedErrorId : CannotCreateTypeConstrainedLanguage,Microsoft.PowerShell.Commands.NewObjectCommand

    You cannot call a method on a null-valued expression.
    At C:\temp\GPFiles\Tools\New-ToastNotification.ps1:616 char:5
    + $ToastXml.LoadXml($Toast.OuterXml)
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

    • Sorry for the late reply. I assume if you digitally sign the script and approve the publisher in AppLocker, that would do the trick. I know the script currently runs with restricted language with applocker, but signing and approving the publisher should do it.

      • Tried with signing and approving but the problem is not with the script but rather with __PSScriptPolicyTest*.ps1/psm1 files that are used to determine which Language Mode PowerShell will run in, they are blocked by applocker.

  11. Hello,

    The program is installed as specified inside of the folder programdata. A new task was created as per the instructions. But, the task does not run by itself. I have to manually launch the task. Then, if I hit refresh on the right side, the task stops immediately. Not sure why? And, just did a test installing new windows updates with a pending restart and the toast notification did not pop. Any ideas?

  12. First of thank you for sharing the code and documenting everything, it really helps the community as a whole! By chance has anyone been able to get the Toast Notification to not just launch the Software Center\Task Sequence but launch the ScopeID defined?

    I am trying to get the Install option to launch the “Available” Application\Task Sequence without further User Interaction.

  13. Right but I meant how do you add an actual URL – so they can click on it and go to a URL we specify like an internal web page

    • Oh, that’s something I will have to look into – I haven’t tried that myself. Thanks ๐Ÿ™‚

Leave a Comment

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