Nathan Ziehnert

9 minute read

I’m always impressed with the vast availability of Windows as a Service (WaaS) community solutions and tools. The way our community shares solutions without expecting anything in return is just great and in my opinion a major reason why we can all be so successful. Especially as we push our users harder with more frequent updates and upgrades. My new mantra is “Happy Users, Happy Admins.” While we can be successful in getting devices upgraded without regard for the users it will be a miserable existence for us as admins. If we can keep our users happy they’re more likely to help us out by completing things in a timely fashion and maybe complain a little less.

With that said, as I was preparing for my next client (who lives this mantra almost religiously) I knew we needed something a little special. A memory of a script to notify users via text message when their WaaS upgrade was complete flashed before my eyes. I was too lazy to go searching for it and frankly I needed to stretch my PowerShell muscles a bit as I haven’t really done anything for a bit. Credit where credit is due however - I think Gary Blok @gwblok had the first public solution for something like this. You can read it here if you would like: https://garytown.com/send-text-and-email-to-user-from-task-sequence.

This was also a good chance to take the PowerShell Presentation Framework (PoSHPF) out for a spin on a real utility.

 

Upgrade Complete Notification

Okay okay… I know… before you want to even consider using it, you want to see what it looks like.

Mobile Notification

First thing to note - that this dialog is fully customizable. The text is not static nor is the color scheme or header image. Admittedly, this is only half of the solution - the other half is in the notification process itself. That script - while invisible - supports two different potential services:

  1. Email Relay to SMS Relay
  2. Azure Logic Apps / Office Flow

The first one is a pretty common way to send notifications to phones via an e-mail address consisting of the device phone number and a domain suffix depending on the carrier of the device. The message received will look something like this:

Mobile Email Notification

The second one gives you a lot of freedom. You could text a user with one of the integrations available in Logic Apps. You could create a party event in Eventbrite for the user… okay, that’s a bit silly. But there’s a lot you can do once you kick off a Logic App via a POST request! (or in a Flow app… which you might already have licenses for depending on your Office 365 license) An example of an SMS notification might look like similar to this:

Mobile SMS Notification

Neither is incorrect! It all depends on your situation and dreams!

All Your Wildest Dreams Come True

 

Usage

So how do you use it? Well first things first you need to download it.

Before I give you the link… the standard legal jargon:

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

All of the files are available here on my GitHub account under an MIT license - so feel free to steal with pride.

 

Configure the GUI

To configure the GUI we need to make some changes to the settings.ini file. An example is provided for you (Settings.Example.ini) in the repo, or you can start from scratch using the settings.ini file provided. All text in the script is 100% customizable for localization and the window will resize based on the amount of content.

Here’s an example of the settings INI file and the resulting output.

;; Invoke User Notification Settings ;;
BaseTheme=Light;
AccentColor=Steel;
NotificationTitle=NOTIFICATION TITLE TEXT;
NotificationMessage=NOTIFICATION MESSAGE TEXT `n`n USE ``n``n FOR NEW LINES;
MobileNumberLabel=MOBILE NUMBER LABEL:;
MobileCarrierLabel=MOBILE CARRIER LABEL:;
StandardCarrierMessageLabel=STANDARD CARRIER CHARGES TEXT;
NotifyMeButtonText=NOTIFY BUTTON;
CancelMeButtonText=CANCEL BUTTON;

Example notification

Here’s a rundown of the settings available:

  • BaseTheme: Light or Dark
  • AccentColor: You can choose any of the colors available here
  • NotificationTitle: The title bar text
  • NotificationMessage: The message shown in the main block of text
  • MobileNumberLabel: The text displayed next to the mobile number text box
  • MobileCarrierLabel: The text displayed next to the mobile carrier select box
  • StandardCarrierMessageLabel: The text displayed warning the user of potential mobile charges
  • NotifyMeButtonText: The text inside the “OK” button
  • CancelMeButtonText: The text inside the “Cancel” button

That’s most of the configuration, but we also need to configure the list of carriers. This is the “SupportedMobileProviders.csv” file included with the download. Open it up and it should be pretty self explanatory:

CSV File

  • Enable: Put anything in this column and it will be enabled
  • MobileProvider: This is the display name you want shown in the GUI
  • EmailSuffix: The email suffix added to the mobile phone number for sending text messages

Once you’ve configured these items as you desire we can move onto configuring the second script that actually sends the notification.

 

Configure the Notification Script

We configure the notification script similarly to how we configured the GUI. You can actually make use of the same settings INI file if you wish.

;; Send Notification Settings ;;
Message=NOTIFICATION MESSAGE;
Service=Mail; "Azure" or "Mail"
AzureEndpoint=;
MailServer=;
MailPort=;
MailSSL=; "False" or "True"
MailFrom=;
MailUsername=; This is not recommended.
MailPassword=; This is not recommended.
MailSubject=; Needed for Send-MailMessage.

As explained earlier, there are two different service platforms that you can make use of: email or Azure (Logic Apps / Flow). Since Azure is the easiest to configure we’ll cover that first.

Configuring a Logic App / Flow

  • Service: Set it to “Azure” without quotes
  • AzureEndpoint: This is the POST endpoint that the trigger creates (it’s a web address)
  • Message: This is the message you want to send to the end user

The script sends a JSON POST request with the following information:

  • PN: The phone number put into the form
  • MESSAGE: The message configured in the settings ini file

Now we need to configure our Logic App to do something with this data. If you’re unfamiliar with Logic Apps, they’re pretty sweet, and I have plans to write a blog post about them.

Unfortunately this post is not that post, but I’m sure you’re a good googler.

We’ll create a blank logic app with an HTTP request trigger. The JSON request body should look like this:

{
    "type": "object",
    "properties": {
        "PN": {
            "type": "string"
        },
        "Message": {
            "type": "string"
        }
    }
}

From here we can create any logic we want. For my flow I’m integrating with Plivo because they were one of the easiest to setup AND they offer a bunch of free credit for development testing. Once you create the integration it’s as simple as passing the parameters to the correct field:

Plivo Example

After I save the integration I get the “HTTP POST URL” that should be put in the “AzureEndpoint” setting in the INI file. Your script is now configured!

Configuring an E-mail Relay

  • Service: Set it to “Mail” without quotes
  • Message: This is the message you want to send to the end user
  • MailServer: Your e-mail relay/SMTP server
  • MailPort: The SMTP port (defaults to 25)
  • MailSSL: True/False (defaults to False)
  • MailFrom: The e-mail address the message is being sent “from”
  • MailUsername: If your SMTP relay requires authentication, configure the username here. This is not recommended for security.
  • MailPassword: If your SMTP relay requires authentication, configure the password here. This is not recommended for security.
  • MailSubject: The subject of the message. Needed for Send-MailMessage.

Okay, so maybe configuring the Mail Relay was easier then Logic Apps, but it required more settings so I wasn’t totally wrong.

 

Executing the GUI

To successfully execute the GUI in the user context during a task sequence, we need to get a copy of ServiceUI.exe. You’ll want both the x86 and x64 versions (they are available as part of the Microsoft Deployment Toolkit (MDT)). You can get them from an install of MDT here:

C:\MDTINSTALLFOLDER\Templates\Distribution\Tools\x64
C:\MDTINSTALLFOLDER\Templates\Distribution\Tools\x86

Name the files “ServiceUI_x64.exe” and “ServiceUI_x86.exe” respectively. Put these in a folder with the contents of the files you downloaded from GitHub and create a package in ConfigMgr (no program necessary).

The script accepts the following parameters:

  • LogFile: The full path to the log file you wish to create.
  • SettingsFile: The full path to your settings file.
  • maxRuntime: The dialog will close after the specified number of seconds. By default it’s 600 seconds (10 minutes), but you can also specify 0 seconds for unlimited runtime.

Have a look at the “Invoke-UserNotification.bat” script. This is a sample script for launching the “UserNotification.ps1” script through ServiceUI depending on where a TS is executing. We’ll focus on this script to show the notification, but you can also roll your own or execute the script however you see fit.

NOTE: I tried to create the invoke script in PowerShell to be really creative (launch with or without ServiceUI depending on if the script launched in a TS or not, and whether or not it was launched in a boot image. It did not work. If you’d like to look at all the different commands I tried, have a peek here: https://gist.github.com/theznerd/61080ed54af530189b7dc30f307c27bb. For whatever reason PowerShell was getting Access Denied when trying to launch ServiceUI. If you have any thoughts, leave ‘em in the comments so that I can come back to it at a later date.

Now that you have your ConfigMgr package created with your customized INI file, let’s try this sucker out in a task sequence. Add a new “Run Command Line” step. Add the package to the step and call the batch script:

.\Invoke-UserNotification.bat

Run Command Line Step

Boom. Ready to rock.

The output of this script is three different task sequence variables:

  • OSDUCNNotify: Boolean value on whether or not the user requested notification.
  • OSDUCNEmail: The mobile “email to text” address.
  • OSDUCNMob: The mobile phone number.

We’ll use these to populate the send-notification script.

 

Sending the Notification

Sending the notification is even easier. We just need to create a step in the task sequence to launch “Send-Notification.ps1”. I find it easiest to create a “Run PowerShell Script” step but you can launch it however you feel most comfortable.

Run PowerShell Script Step

The script accepts the following parameters:

  • mobileNumber: Use THIS parameter if you’re using Azure instead of Mail. Pass the OSDUCNMob TS variable to this parameter.
  • mobileEmail: Use THIS parameter if you’re using Mail instead of Azure. Pass the OSDUCNEmail TS variable to this parameter.
  • LogFile: The full path to the log file you wish to create.
  • SettingsFile: The full path to your settings file.

Additionally you will want to set a condition on the step to only run if OSDUCNNotify is True, like this:

Run PowerShell Script Conditions

And now you can run your task sequence. All of your users will rejoice. You have done something to make THEIR lives better!

People Rejoicing

 

Closing Thoughts

Let me know if you end up using this in your environment or have any suggestions for improvement! The scripts are available on GitHub and you can also submit PRs if you wish! Enjoy the script and as always…

Happy Admining!

comments powered by Disqus