OSD: Dynamic Application Installation

In this post I am going to talk about a solution I put together for a customer around OSD and application installation by querying a collection.

Anyone who has used Zero Touch Installation will be familiar with the ability to install applications from SMS packages. In the wizard screen you enter information about each package; the package ID - made up of a site code and a unique number; and the install command line. Then when the task sequence runs ZTIApplications.wsf reads each entry you made and installs the application referenced. This is all well and good but you have to go dig up all the information about a package and enter it into the workbench. If one of the applications changes you need to update the workbench entry again. Plus the person managing BDD may not have enough rights in SMS to to the query.

On the project where I put this solution together the SMS team were responsible for creating application packages and advertising them. The BDD team did not want to have the additional workload of having to manage application updates - which were expected to be frequent. In addition applications would be grouped on core language, business unit or role.

So I wrote a task that would query a named SMS collection, extract a list of adverts, gather the details of each advert - package ID and install command line, sort alphabetically and then pass the list to ZTIApplications.wsf for install.

To be honest this turned out to be surprisingly easy. The hardest bit was working out the permissions required by the script and sorting the list of applications alphabetically.

To make this work you need five things;

  1. The script to do the query. This can be found on my Live Drive Folder in the zCFG-SMSCollectionQuery.zip file. There is only one script in this file. Extract this to the scriptroot directory.

  2. You need a BDD environment variable called SMSMgmtPt. This holds the value of the SMS MP you are going to query.

  3. You need another BDD environment variable, you can call it whatever you want, that holds the name of the collection to query in SMS.

  4. You need a collection in SMS that has some programs advertised to it. (We used an empty collection but they don't have to be.)

  5. Your BDD user, the one you use to connect to the BDD shares etc., must have enough rights to query the WMI name space collections and advertisement objects in SMS.

Once you have all these pieces lined up create a task in your Task Sequence that calls the query script and passes the name of the collection to be queried on the command line. For example;

cscript.exe "%SCRIPTROOT%\zCFG-SMSCollectionQuery.wsf /SMSCOL:<variable_name_that_hold_collection_name>

Now run your task sequence. You should see the applications advertised to the collection being installed.

The script can be run multiple times in a task sequence. This allows you to specify different collections each time and build up a list of applications to be installed. Note that you you must run all instances of this task before you run the ZTIApplications task. Also that applications are only sorted for that run of the script. If you run it multiple times it will not sort the whole of the resultant application list.

The script can be downloaded from my Live Drive folder.

So what happens in the script and how does it work?

NOTE: I am a great believer in verbose logging. Pretty much anything the script does gets logged. If it generates an error I try to make sure this is unique for each test within the script - as you will see below. This greatly helps when trouble shooting. If you hit errors go look in the logs and the error code returned should tell you where in the script it failed. For example error 80 means you have not supplied the /SMSCol switch on the command line, an error of 60 means it can not connect to the WMI name space on the management point.

The first thing the script does is checks that it has all the values it needs. The script runs and checks to see is a value for the SMS MP server (SMSMgmtPt) has been specified. If not it returns an error code 90. Then it checks to make sure you have supplied a value on the cmd line for SMSCol. If not it returns an error code of 80.

Then it queries the BDD env var passed to it on the cmd line to see if that holds a value. If it does not it errors with code 70. This is the name of the collection it is going to query.

Now it sees if there are any packages already defined. If there are it works out how many and starts to add packages at the end of the list. This means you can define packages as normal in BDD Workbench – these will be installed before any this script finds. This is also how we are able to run the task multiple times and not overwrite previous entries.

Now it tries to connect to the WMI names space on the server. If it fails to connect you get an error code 65. If successful it gets the site code from WMI. If it can not do this you get an error code of 60.

Now finally it tries to get the collection. If it can not it returns error 50. If it succeeds it gets each advert in the collection, gets the package ID and install cmd line associated with the package and drops these into a collection called coladverts. Once it has the full list it sorts the collection into alphabetical order, using the function QuickSort.

Once they are sorted the script adds each package to the package list then terminates.

The script can run/tested during an LTI test TS. You would only need the OSD functionality if actually installing the packages. See Ben Hunters blog on how to run up quick little test Task Sequences or run scripts on their own.

This post was contributed by Richard Trusson a Senior Consultant with Microsoft Services UK.


Comments (11)

  1. Anonymous says:

    Hi Guys,

    I’m wondering if you can help me out with something (this may not be the correct post).

    I have 1 image in my environment for my 18 different models (HPs and Panasonics).

    The image works on almost all of them, but the Panasonics don’t always seem to cooperate.

    When they reach the ZTIApplications (apps from make and model database), I randomly get Application VPN 06_01.102 returned an unexpected return code: -1073741819. I’ve tried moving the VPN application up and down in the DB, but that only changes the application that will fail. All my other machines use the same resourceroot and all other machines finish successfully. The same Panasonic might work once, then fail three times in a row (at times, at different applications).

    Any thoughts?



  2. Anonymous says:


    i tryed (without using scripts yet, but simulating the variable values for packages information) from a DVD stand alone image installation process created with SCCM and it works fine 🙂

    Only would want to say it for your information.

    Regards from Spain.


  3. Jeffrey,

    the list of packages is stored in the environment store, Variables.dat, by the line oEnvironment.Item(sPackageVar)=sPackageValue; line 205. Higher up you will see we query the list of packages ( Set cPackages = oEnvironment.ListItem("Packages") line 98 ) to find out how many packages are already listed and then add ours to the end.

    As for ZTIRetValue – you are correct. I have amened the ListAdverts() function and line 151. However I have not tested this. Please let me know if it continues to work!



  4. Anonymous says:


    have you tested or think if this solution can work launching all the deployment process from DVD or USB? In other words, install SCCM Dynamic Packages from DVD or USB?

    And another question: do you think it’s possible (in the case I reinstall a BDP computer in a branch office without any Servers), to first enable the BDP Role during the state restore phase and then install the packages (already populated into the BDP during  the state restore phase) from this re-enabled BDP? …all those actions from a DVD or USB, of course 🙂 (think at 256-512 kbps lan connection).




  5. Hi Erik,

    yes the script would certainly be capable of doing that. It does not at the moment and you would have to add the code to do this.

    What I would do is create a new script that gets the collection information from querying AD. Writes that out to variables.dat using oEnvironment.item("ADGrpCollection")=collection_name then calls the collection query scirpt with the switch /SMSCol:ADGrpCollection.

    hope this helps,

    Rich Trusson

  6. Vince,

    thanks for the update.

    It is great that you shared your experiance with the rest of us.


    Richard Trusson

  7. Vince Rovira says:


    I just throw this idea (without time to test it yet) to Michael Nihaus 2 weeks ago. Glad to hear that the idea works !! 🙂

    Thank you guys!


  8. Vince Rovira says:

    Sorry, i-m not saying that that the idea was mine (hope you didn’t thought that), but i had that idea too 1 or 2 weeks ago (not implemented yet in my project). 🙂

    But I’m happy to having had it too 🙂



  9. Jeffrey T says:


    Shouldn’t "ZTIRetValue" from line 151 really be "iZTIRetValue"?

    Also, where is the "package list" stored?


    Jeffrey T

  10. eriweste says:


    Quick Q ?

    Is the script capable of checking AD group membership for the computer. and based on the result add the application to install list.

    Criteria on collection based on ad group



  11. Hello

    Using the MDT SQL database to store the applciations, the customsettings.ini builds a list of apps to install. The process works correctly but is taking alot longer than SMS OSD. The logs show a 1 minute + time to check for policy…check log:

    Policy complied successfully in WMI ‘rootccmpolicydefaultmachinerequestedconfig’ namespace

    Get Install Directory for SMS Client

    waiting for local policy to take effect

    Policy evaluation initiated

    It is the task/step – waiting for local policy to take effect that takes the time. This happens for each appliation install. I have 40 apps to install…

    Has anyone else expericanced this? Does anyone know why this is happening?



Skip to main content