Building An Even Better Task Sequence

03/12/2019 – This post has been updated to support changes in 1901 TP and (I assume) 1902 CB to the TSProgressUI.exe ConfigMgr client component used for the custom described dialog below.

Note: You must be running ConfigMgr/SCCM 1810 or higher to use the 
_SMSTSLastActionName variable included in this post. However you can use the same concepts and error dialog with previous versions (but seriously, upgrade already!), you just can’t display the name of the failed step as described here. Also, go upvote the UserVoice item to have the product do this natively (Thanks Nash!).

In my Building A Better Task Sequence post, I discussed how to use the new _SMSTSLastActionName Task Sequence variable to capture the name of a failed step and still gracefully exit the Task Sequence. At MMS Desert Edition last week, Mike Terrill used some of my concepts for his MVP Showcase. After the session, Andreas Hammarskjöld from 2 Pint Software suggested that we should be able to customize the error message that is displayed after a failure. I saw him the next morning at the AZSMUG meeting and we quickly chatted about the dialog again. I had about 1.5 hrs before I was scheduled to speak so I figured, why not try to build, test and demo a custom error dialog in that time. Somehow, it worked, so thanks Mike and Andreas for the inspiration. Here’s yet another take on this idea (I have a few more I think. Maybe I need to just number my posts now…). 

This post also relies on concepts from my previous
Using SCCM Task Sequence Variables as Scripts post, so if you get lost, go check it out. My goal here isn’t to create some beautiful error dialog, but to give you another option to use to build your solution out.

Picking Up Where We Left Off

The problem we want to solve is this ugly mess of dialog boxes when the Task Sequence fails. One problem is that the error dialog is mostly generic and it hides the ProgressUI, so users may never see our cool modified dialog and we will end up back at the same problem – not getting good info at the time of failure since most users will just screenshot the error dialog and send it in for support.

Example of both dialogs, with the error dialog moved to reveal the Progress UI where the real info is.

In the last post, I showed how to customize the ProgressUI. Now we will hide the ProgressUI and show a custom dialog with the same information that we need from the failed step.

Show/Hide ProgressUI

You may be aware that when you deploy a Task Sequence, you have the option to deploy it silently by unchecking the Show Task Sequence progress on the User Experience tab of your Task Sequence Deployment. The problem with this option is that it hides ALL of the dialogs, which may not be something you want to do — I know my users don’t like to find out they have a new OS installing by having their machine randomly reboot with no warnings! However, if you want to display one of the many custom dialogs available from the ConfigMgr community, unchecking the box may be beneficial. Full list at the end.

Uncheck Show Task Sequence Progress to hide all progress and error dialogs

Another option to consider is the TSDisableProgressUI variable. You can use it anywhere in your Task Sequence to toggle the dialog on or off. Simply add a Set Task Sequence Variable step before or after any step you want to change the dialog display for, then set the value to True or False depending on the desired display mode. Once the variable is set, ProgressUI will stay on or off until you toggle it again.

Toggle ProgressUI On by setting TSDisableProgressUI=False
Toggle ProgressUI Off by setting TSDisableProgressUI=True

Custom Error Dialog

Disabling ProgressUI, allows us to fully control the Task Sequence dialogs. For example, if you wanted to suppress the default dialog and put up a splash screen or simply customize the ProgressUI itself – though that would require adding a step to update the dialog in between each step, which isn’t really the best. I have worked on a script to monitor the TS progress and update the dialog, but it’s quite unstable and unreliable. All that to say, you CAN do it, you just may not want to.

The final result.

Putting it All Together

For my sample Task Sequence, I’m reusing the one from the previous post and just modifying a few steps to give us the desired result. Full TS is is available for download at the end.

03/12/2019 – These steps have been updated for SCCM 1902 CB functionality. The WMI Condition and additonal “Set Custom Dialog” should only be needed if you are running this TS in an environment with 1810 AND newer clients. The change to TSProgressUI.exe is an additional argument has been added to the ShowErrorDialog Method.

The basic TS structure
Sample step that will case the TS to fail with exit code 12345

Condition on the Custom Error Dialog group to only run if there was a failure.

1810 Clients Only

WMI NameSpace: root\ccm
WQL Query: Select ClientVersion from SMS_Client where ClientVersion < '5.00.8772.1000'

1810 Clients Only – Setting the CustomDialog variable to our new PowerShell code block.

1901 TP or 1902 CB Clients and Newer

WMI NameSpace: root\ccm
WQL Query: Select ClientVersion from SMS_Client where ClientVersion >= '5.00.8772.1000'

1901 Clients and Newer – Setting the CustomDialog variable to our new PowerShell code block.

Remaining Shared Steps

Disable the progress dialog to suppress the default dialogs.
Run Command Line step to run the code block that we stored into the CustomDialog variable.

As you can see, the main changes from the previous post are that we are now toggling ProgressUI off and instead of using a variablized step name as the final step and we are going to call the PowerShell to show the custom dialog, but only AllStepsSucceeded = False.

One more note on this – Instead of customizing the built-in error dialog, you could make your own custom message that provides the user with options to email IT or retry the TS, etc. You get the point.

You can download the full sample Task Sequence from my GitHub.

Community Progress Dialogs

Additionally, check out Gary Block’s post that talks about the _SMSTSUserStarted variable. You can use it to only show the dialog if a user initiated the TS.


  • Reply
    December 17, 2018 at 1:19 pm

    can you put a screenshot of the capture failed step variables step?

  • Reply
    [email protected]
    January 17, 2019 at 7:05 am

    is it possible to insert the “Better Task Sequence” into a MDT-Task Sequence with UDI in SCCM and where is the position?


    • Reply
      Adam Gross
      January 17, 2019 at 8:25 am

      You would use this structure to design your TS. This isn’t a ready-made TS, just an example of how to build your structure.

  • Reply
    Jeff Poling
    April 10, 2019 at 12:16 pm

    I am trying this out. . . but the custom dialog never launches. The TS gets into the “Cleanup” group after I force it to fail, then it successfully completes all the clean up steps and then boots to the OS. Have you seen that before? I know that all of this is completely dependant on my environment, TS, etc. 🙂

    • Reply
      Adam Gross
      April 10, 2019 at 12:19 pm

      It is most likely due to your error code being negative. I haven’t had a chance to update the code yet. Here’s what you need:

      The changes bit is here:

      I’m working on a better option for this but it works for now.

      • Reply
        May 2, 2019 at 5:11 pm

        Thanks for this information. Could you paste the updated code that works with negative error codes somewhere else as the formatting has been messed up. I’ve tried adding the backticks and changing the failed variable names but my command is still failing.

  • Reply
    Evgeny Korneev
    May 15, 2019 at 5:23 am

    When getting an exit code in hex, for example 80004005 from “Check Readiness” step, _SMSTSLastActionRetCode is set to -2147467259. This number cannot be automatically converted by Powershell and throws an error:

    Cannot convert argument “4”, with value: “-2147467259”, for “ShowErrorDialog” to type “System.UInt32”

    Easy workaround is to replace argument 4 with 1.
    This will force dialog box close with code 1, but then it will be overwritten by “real” return code.

    Full code:

    %SYSTEMROOT%\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -Command ” & { $TSEnv = New-Object -ComObject Microsoft.SMS.TSEnvironment -ErrorAction Stop; $TSProgressUI = new-object -comobject Microsoft.SMS.TSProgressUI -ErrorAction Stop; $TSProgressUI.ShowErrorDialog($TSEnv.Value(\”_SMSTSOrgName\”),$TSEnv.Value(\”_SMSTSPackageName\”),\”Windows Installation Error.\”,\”An error occurred while installing Windows. Please contact your Line of Business Help Desk and provide the following information:rnFailed Step Name: $($TSEnv.Value(\”FailedStepName\”))rnFailed Step Error Code: $($TSEnv.Value(\”FailedStepReturnCode\”))\”,1,$Tsenv.Value(\”SMSTSErrorDialogTimeout\”),0,0); Exit $TSEnv.Value(\”FailedStepReturnCode\”)}”

    • Reply
      Adam Gross
      May 15, 2019 at 5:38 am

      Check the previous comments for the fix. Sorry haven’t had time to update the post/TS

  • Reply
    Evgeny Korneev
    May 15, 2019 at 6:31 am

    My point is that you dont have to modify values in your script at all(with math::abs). Just replace argument 4 (which is $TSEnv.Value(\”FailedStepReturnCode\”)) by 1. That’s it.

    • Reply
      Adam Gross
      May 15, 2019 at 6:39 am

      Oh I see. Yes that certainly is a possible solution. I actually have begun working on converting the error code to a MS error code in the 0x0 format instead so that the error will be displayed in a more search friendly format.

      Also, with the changes in 1902, unless you just NEED to have a custom dialog, you can simply trigger the built in error dialog instead now since it provides the error name and error code by default now.

    • Reply
      SCCM User
      June 28, 2019 at 9:01 am

      Hi – I have tried to do this but still its not working, have also copy and pasted the text sample and hasn’t worked. Could you advise on how it will display negative numbers.

  • Reply
    May 16, 2019 at 2:21 pm

    How would you go about trigging the built in error dialog instead?

    • Reply
      Adam Gross
      May 16, 2019 at 2:30 pm

      Add a new run command line step as your last TS step. Set the step name to be the failed step name like %FailedStepName% and set the command line to be cmd /c exit %FailedStepReturnCode%.

      • Reply
        June 3, 2019 at 12:06 pm

        Unless I am misunderstanding, I tried to set the name of my last task sequence step to %FailedStepName% (this value is set by a step earlier in the TS), but it doesn’t show the variable, it literally shows up as %FailedStepName%?? Did I do something wrong?

        • Reply
          June 26, 2019 at 4:22 pm

          I’m actually seeing the same thing. i did a powershell dump of the variables and can confirm that the variable ‘failedstepname’ is correct and captured, but it shows up literally rather than the variable. change from 1810 to 1902 maybe?


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