The scenario of dynamically installing Applications based upon a variable list (CustomSettings.ini or Dynamic Variables) during OS Deployment is not something new and has been around for ages. When you integrate MDT with ConfigMgr, you get tons of extra features and great additions. The section in an MDT integrated Task Sequence called Install Applications includes a VB-script from MDT that converts a variable list that is later on used in the next step called Install Applications. This works great, however as you may have noticed I’m not a fan of VB, so I’ve re-written the VB script in PowerShell. In this post I’ll walk you through how the script works and how to implement it in different scenarios.

How it works

Before we start talking about the script that I’ve written, let’s just walk through how the whole process works when you want to install Applications based upon a variable list. Instead of adding a step to install a single or up-to 10 Applications in a regular “Install Application” step, you could leverage the Install Application step to install Applications based upon something called a Base Variable. In your CustomSettings.ini file located in the MDT Settings package (created by default when you create a new MDT Task Sequence in ConfigMgr) or with a Dynamic Variables step in the Task Sequence, you define a variable list with values of the applications that you want to be installed. Let me illustrate that to be more clear.


In your CustomSettings.ini file, you would add something like the following to a section of your choice:


Dynamic Variables

If you’re not comfortable with using the CustomSettings.ini file (you should learn how it works though), you can use a step called Set Dynamic Variables that are native in ConfigMgr. In the picture below you can see that I’ve defined the same three variables as I did in CustomSettings.ini:


My version of the ZTICoalesce.wsf script from MDT basically works in the same way as the original, by reading all APPLICATIONS (notice that it’s matching on the variable name only, not the suffix) variables in the TS Environment. When all the variables have been detected, it adds them to an re-ordeded array list and creates a new variable list called COALESCEDAPPS (default base variable list used in the MDT integrated ConfigMgr task sequence). The end result is that the COALESCEDAPPS variable list will contain the Applications specified either in your CustomSettings.ini or a Set Dynamic Variables step. The picture below illustrates where the COALESCEDAPPS base variable list is used within the task sequence:


Just like the original script, my version supports you to define the RuleVariableName variable (the one that you specify in CustomSettings.ini or a Set Dynamic Variables step) and the BaseVariableName (what’s specified in the Install Applications step). If no parameters are given to the script upon execution, the default value for RuleVariableName would be APPLICATIONS and the default value for BaseVariableName is set to COALESCEDAPPS. I’ve designed the script for easy use, so if you don’t want to use custom variable names, simply just run the script without any parameters.

I should also mention that, if you for some reason have now defined chained suffixes, e.g. 001, 002 and 003, but instead 001, 002, 004 my script will re-order it correctly so that the Task Sequence won’t break because of that. In addition, the script will log it’s output in the current path where the Task Sequence is logging to smsts.log in a file called DynamicApplicationsList.log.

Download the script

I’ve uploaded the script to my GitHub repository, but you can also download it from the link below:


Implement the script

Now that you’ve seen how it works, lets walk through how you can implement this in your environment. This process is quite simple and consists of creating a legacy Package and then replacing a couple of steps in your task sequence. First of all, you should download the script from the link above or grab it from my GitHub repository.

1. Start by creating a Package without a Program and set the content source to a location where you’ve downloaded the script.
2. Distribute the package to your Distribution Points.
3. Edit your MDT integrated Task Sequence and locate the Install Applications group.
4. Select the ‘Convert list to two digits’ step and select Add – General – Run PowerShell script.
5. Name the new step e.g. Set Dynamic Applications List, select your package with the PowerShell script and enter the script name. Remember to select the Execution Policy to Bypass.
6. Remove or disable the Convert list to two digits step, and make sure that the default base variable in the Install Applications step is set to COALESCEDAPPS.
That’s it! You have now modernized your task sequence a bit with PowerShell instead of legacy VB-scripts.


Nickolaj Andersen
Principal Consultant and Enterprise Mobility MVP since 2016. Nickolaj has been in the IT industry for the past 10 years specializing in Enterprise Mobility and Security, Windows devices and deployments including automation. Currently working for TrueSec as a Principal Consultant. Awarded as PowerShell Hero in 2015 by the community for his script and tools contributions. Creator of ConfigMgr Prerequisites Tool, ConfigMgr OSD FrontEnd, ConfigMgr WebService to name a few. Frequent speaker at conferences and user groups.


  • Ravi
    Posted at 22:22 June 9, 2016

    Good Very intersting

  • Simon
    Posted at 15:55 August 7, 2016

    Very good. Works as advertised. However how does this fit if you have the applications set up in a role within MDT? I can’t seem to get it to work this way. I have tried adding the application names on their own, eg:
    app3 etc

    and I have also tried
    APPLICATIONS003:app3 etc

    I’m clearly missing something here…

  • Simon Bond
    Posted at 17:51 August 7, 2016
    Simon Bond

    Apologies…as happens 99% of the time I write these things, I fix it two minutes later. Not using your script in this instance but just the standard way with ZTICOALESCE.wsf. No idea why it wouldn’t work this way last time I tried but there you go.
    Not sure whether your script was designed to work using the ConfigMgr2012 Applications tab in MDT but couldn’t get it working with that. Feel free not to publish these comments as they don’t really help anyone.
    Loving your work though and your ConfiMgr Pre-Reqs checker is life saver.

  • Sandy
    Posted at 10:13 November 29, 2016

    Do you accept feature request? 🙂 Script works nicely, how ever, kind of needed priority few application install by orders, expample if I need MBAM client install a first always as Applications001.

  • Sandy
    Posted at 10:43 November 29, 2016

    Hi, no need to post my comments. Just figured it out. I use another script to sort the RuleVariableName before run your script. something like that:
    if ($Apps -ne $null)
    Write-Host “Searching applications to install…”
    $ApplicationName = ($Apps | where-object {$_.LocalizedDisplayName -match “MBAM”}).LocalizedDisplayName
    Write-Host ” $AppId $Applicationname”

    $Count = 2
    foreach ($App in ($Apps | where-object {$_.LocalizedDisplayName -notmatch “MBAM”}))

    $Id = “{0:D2}” -f $Count
    $AppId = “APPLICATIONS$Id”
    $ApplicationName = $app.LocalizedDisplayName

    Write-Host ” $AppId $Applicationname”
    $Count = $Count + 1


  • Leave a Reply