Deploy Service Announcement Toast Notifications in Windows 10 with MEMCM

You may have seen that many apps these days use “Toast Notifications” to inform the user of an event or to ask them to do something. If you have moved your workload to Intune for Windows Update Policies you would have encountered them for sure. UWP and Desktop Apps can leverage the ToastNotification and ToastNotificationManager Class from the Windows.UI.Notifications Namespace to create ToastNotifier objects to send a Toast Notification similar to below

Side Note: We can also send notifications from Intune to iOS/iPadOS and Android Devices in the form of Push notifications https://docs.microsoft.com/en-us/mem/intune/remote-actions/custom-notifications

Background

If you are reading this post, you will have seen some Toast Notifications and thought “Cool, can I do that?” and that is where my journey started. Rewind a whole bunch of months and we were discussing how we cold reduce our software portfolio to make management easier and bring down our running costs at the same time. One piece of software in our portfolio was used to send notifications to our user base to inform them of issues that affected the whole company e.g. Email Down / Phones Down / Coffee Machine Down

And so the challenge began. Could I create my own Toast Notifications, on the fly, and deliver them using ConfigMgr – and the answer is yes!

Feeling Toastie

Toast Notifications are flexible in their appearance and actionable states. Toasts can be delivered from a variety of predefined Toast Template types. They can range from simple text notifications to text with images.

Learn more about the different Toast Template Types at https://docs.microsoft.com/en-us/uwp/api/windows.ui.notifications.toasttemplatetype?view=winrt-19041#fields

The Toast itself is built and styled from from an XML. In the XML we specify the various visual elements and actionable elements within our Toast. Do we want images, titles, text, buttons etc. Here is an example of what a basic, text only, Toast XML might look like using the Toast Template Type ToastText02

or we can get funky and include a Badge Image using Toast Template Type ToastImageAndText03

Why does the example above display the text Windows PowerShell? This is known as the Attribution property and is visible as we start to use more advanced Toast Template Types. The attribution property will be the name of the UWP or Desktop app that we use to call the Toast. For Windows Anniversary update and later, we can append to this value by modifying an element within our XML

So you can see we can add different properties into our XML to style the Toast the way we want it to look. In the PowerShell script this post, we are using another binding template called ToastGeneric. More information on how to style your Toasts can be found at https://docs.microsoft.com/en-us/windows/uwp/design/shell/tiles-and-notifications/toast-ux-guidance

Images

Images are interesting. We can have Badge Images (also know as App Logo Override Images), Hero Images and Inline Images. More information on all of these, including size and dimension restrictions can be found at https://docs.microsoft.com/en-us/windows/uwp/design/shell/tiles-and-notifications/adaptive-interactive-toasts#image-size-restrictions

In the Toaster

This post could very easily turn into a how to build a Toast tutorial so I will stop at this point. As I said at the beginning of the post, we had a very specific task we wanted our Toast to perform. The Toast, in our late example, will display a header image, known as a Hero Image, a Badge Image, some custom titles and text and two action buttons – one that opens the Service Portal Announcement page and the other that dismisses the Toast Notification. This will be used so the Service Desk can notify the user base of impending doom or “Systems Down”. I believe this requirement and style of Toast could very easily apply to other organisations. We wanted to be able to send our users notifications for organisation events that affect either everyone or groups of people. So maybe this is a good point to introduce a Toast limitation.

Toasts must be run in the USER context

It would have been neat to be able to target devices but Toasts will only pop if ran in the users context. This means our delivery mechanism must target users. This immediately rules out the way I would have liked to have pushed Toasts out – and that was via the “Push Script” feature in ConfigMgr. Sure, given a few hours/days in the engine room we could muster this in the script to deploy as SYSTEM – happy to collaborate if anyone has any ideas.

As we saw earlier, we have to specify which UWP or Win32 Desktop application we are going to use to “Pop the Toast” – man I love that term. I wanted to be able to “Pop a Toast” to our users, giving them some initial information and then have them access the ICT Service Portal to find more information and updates. If you are using a Desktop App, that App MUST exist in the Apps Start-Up folder in Windows. You will need the AppID of the App you choose to “Pop Your Toast”. In the following example, I chose MSEdge. I had originally tried two other very plausible Desktop Apps and these worked well too:-

  • Microsoft.SoftwareCenter.DesktopToasts
  • {1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\WindowsPowerShell\v1.0\powershell.exe

Because I was launching a web page with an action button in my toast, using MSEdge as the app that handled my custom Toasts meant the browser would fire up in focus with the URL I specified in my Toast action argument.

You can find a list of available Apps and associated AppIDs by running the following command:-

Note: Toasts can launch a browser when you specify Protocol on your action button as the activation type. If you want to run a custom action then you must register your own protocol to do this and that is outside of the scope of this blog post.

Spreading Code on our Toast

Hopefully you understand some of the structure required to a “Pop a Toast” now. We have covered the XML requirements and how we want our Toast to look but we haven’t discussed how we deliver it to our users. We are wrapping our XML styling in a PowerShell script. As with all scripts I write, anything that “could” change I like to pass as a parameter. It is safe to assume that if you want to send a notification to users, you may want to change the wording at each catastrophe. I don’t really want the Service Desk guys and gals modifying scripts and updating content for the application. So we needed a way to read Toast text on the fly. In our example, we are doing this with another XML file. This file will be stored on a server accessible by everyone. The PowerShell script will read the XML elements in and set them as variables. Cool. We can have an XML that the service desk folks change each time or we could have multiple, pre fabricated XML’s for various scenarios. We created XML’s for the more common scenarios like “Email Down”, “Phones Down”, “Coffee Machine Down” etc.

Here is an example of what our XML will look like

Lets look at each of these elements briefly:-

  • ToastTitle – The Title of our Toast
  • Signature – The text beside the attribution field (only visible in Anniversary update or higher)
  • EventTitle – Title of the Event we are bringing to our users attention
  • EventText – Details of the event and instructions to the user
  • ButtonTitle – Our Single, actionable button Title
  • ButtonAction – Web page / Service Desk Portal to load

And here is where the elements (in red) appear on the Toast Notification:-

Let’s have a look at our PowerShell code and bring this together. The script will allow us to pass two parameters XMLScriptDirSource and XMLOtherSource, only one can be passed.

  • XMLScriptDirSource – The Custom Content XML is in the same content source folder with the PowerShell script and packaged together with the script
  • XMLOtherSource – The Custom Content XML is on a file share

This is the first iteration of code and may be improved. Source https://github.com/byteben/Toast/blob/master/Toast_Notify.ps1

We are doing some basic checks like does the XML exist, is it a valid, readable XML, get the current user name (Domain Joined clients Only) for a more custom experience and load the assemblies to run the Toast etc. I will keep the ReadMe.md updated on GitHub.

Building the Package

The very nature of a Toast Notification is to “Set and Forget” it. In our script, we are setting the Toast duration to Long which means it will stay open for 25 seconds. Once the Toast disappears it remains in the Notification Center for 3 days. At the moment, I couldn’t think of a suitable way to set a detection method for this script because there is no payload. The best option I have found for now is to deliver the Toasts using packages – arghhh..run for the hills and chase him with a pitch fork. Please contribute if you can think of a better way to do this.

To create the package in MEMCM, you will need the following files in your Package Content Source Directory

  • Toast_Notify.ps1
  • BadgeImage.jpg
  • HeroImage.jpg (364 x 180px, 3MB Normal Connection / 1MB Metered Connection)
  • CustomMessage.xml

Absolutely use your own Hero and Badge Image. The dimensions and size for the Hero Image are quite strict. All of these files are available in my Git repository so go grab them for your test labs. You will also find some other Custom Message XML’s too to play with https://github.com/byteben/Toast

1. From the ConfigMgr Console, navigate to Software Library > Packages > Create Package

2. Enter a Name e.g. “Toast Notifications

3. Select This package contains source files and browse to the content source directory that contains the files listed above

4. Click Next

5. Ensure Standard Program is selected on the Create Program Type page and click Next

6. Enter the following Information:-

Name: Custom Toast Notification
Command Line: PowerShell.exe -File “Toast_Notify.ps1” -XMLOtherSource “\\MyFileServer\Toast Notifications Custom Message\CustomMessage.xml”
Run: Hidden
Program Can Run: Only when a user is logged on
Run Mode: Run with user’s rights

7. Click Next

8. Select This program can run only on specified platforms and select All Windows 10(64-bit)

9. Set Estimated disk space to 52kb

10. Set Maximum allowed run time (minutes) to 15

11. Click Next and then Click Close

You can create multiple programs for the same package if you want to use the predefined XML’s on my Git. Just change the Name and Command Line to identify the correct XMLs to pass to the script.

Deploy to Users

Now all that left to do is deploy our Toast package to our test user group. Remember, we must deploy to a User Collection

1. Right click the newly created Program Custom Toast Notification and choose Deploy

2. Click Browse and choose the User Collection you wish to deploy the Toast Notification to

3. Click Next

4. If you haven’t already done so, choose which Distribution Point or Distribution Point Group to add the package to and Click Next

5. Ensure the Purpose is set to Required

6. Click New in the Assignment Schedule pane and Select Assign Immediately after this event > As soon as possible (or a schedule of your choice)

7. in the Rerun behaviour drop down, Select Always rerun program

8. Click Next four times and then Click Close

At the next User Policy Refresh Interval, your clients should receive the Toast. You can always force a User Policy Notification refresh from your device node in the ConfigMgr console

You can monitor the script deployment in the Ccm32BitLauncher.log file

Summary

That was a whistle stop tour of deploying Toast Notifications with MEMCM. I wanted to give you an introduction into how Toast Notifications are formed and how I deploy them using MEMCM. Most of the complex work is in the script which I hope to develop. If you want to contribute on GitHub, I would be more than happy to work with you on Pull requests and suggestions.

I spent a good chunk of my spare time making it my goal to understand how Toast Notifications work in Windows. This is the end result – a labour of love.

I wouldn’t be doing the community justice if I didn’t mention Martins work on Toast Notifications too. He has really developed a neat solution. Go and check it out https://www.imab.dk/windows-10-toast-notification-script/

Gary Block also has a really neat example in his GitHub repository too and uses Base64 to encode his images – so cool! https://github.com/gwblok/garytown/blob/master/Office365/CI_ToastLaunch_Remediate.ps1

Thanks too to Chris Roberts and Guy Leech for helping with some background work and coding conundrums, I valued your input.

6 thoughts on “Deploy Service Announcement Toast Notifications in Windows 10 with MEMCM”

  1. Hi Ben,

    This is a fantastic powershell script and corrosponding article, breaking down the layers of Windows notifications. I’ve recently created a similar (but more simple) version and deployed to our fleet. I was wondering if you encountered a problem of notifications being at the forefront during full screen events (such as delivering a presentation via Powerpoint or in a video call in Zoom/Teams etc)?

    Once again, well done
    James

    1. Hey James, thanks for the feedback. I’ve not tried but toggling the Focus assist / notification settings in Windows may alleviate some of those pain points. The notifications are coming from the MSEdge app in my script so this is where you would need to play in those control panel areas.

    1. Thanks for the positive feedback.

      Martin and I are friends, I can assure you I have not “ripped off his work”.

      If you took the time to read the Microsoft articles and understood how Toasts work you will know that Toast Notification creation using the Windows built in assemblies will probably look similar across each coded solution.

      Have you not looked at other, similar, solutions before posting your comment?

      I have given kudos to Martin and his solution and advised others to check his blog both here and on Twitter – on several occasions.

      I took the time to research the technology and code and built the solution from the ground up before taking inspiration from others who have produced Toast scripts to give a personalised Toast experience.

      I took the time to create this post as a tutorial for others who are looking for inspiration to create their own Toast solution – not for monetary gain but because I, and many others, value the contributions from the Microsoft community.

      As I tell my children, if you have nothing nice to say then don’t say it.

      I bid you good day

Leave a Reply to Jeps Cancel Reply

Your email address will not be published.

Time limit is exhausted. Please reload CAPTCHA.

 

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