MDT 2012

Last week I did a post about pre-provisioning user applications, based on group membership, during OS deployment, which I already thought was pretty cool. I got some nice positive feedback on that post, including a comment of my very well respected colleague and ConfigMgr MVP Kim Oppalfens. He said, “Nice find, but what if you have twenty applications?”. Well, my idea of last week would mean two task sequence steps per applications, so that’s not really an option for a lot of applications… I had to come up with something better.

The biggest challenge about this is that Orchestrator can only return static variables, it’s not possible to return dynamically named variables from a runbook. This meant that the only option left, to really achieve my new goal, was to manually edit the ZTIExecuteRunbook.wsf –script from MDT to turn a static variable into multiple task sequence variables. So in rough lines my runbook has to return one string with all application groups and MDT has to turn it into multiple task sequence variables.

Prerequisites

The prerequisites are the same as last week, but to be complete I will sum them up again. This post is based on one basic functional requirement and that’s, that Active Directory (AD) –groups are used to determine whether a user gets and application or not. For the rest of the post the following technical requirements are prerequisites and not further described:

The Microsoft Deployment Toolkit 2012 Update 1 –package is created.

The Nework Access Account is member of OrchestratorUser –group.

Note: By default the Execute Runbook –step will use the credentials of the Network Access Account to connect with Orchestrator.

User device affinity is configured to Allow user device affinity with automatic approval in the PXE –tab of the Distribution Point Properties.

Runbook

Like last week let’s start with configuring the runbook that, in this case, will check all the group memberships. The biggest challenge about this runbook was to find a good way to return the group memberships. The runbook, that I ended-up with, returns a comma separated string with all groups and contains five activities with the following configuration:

Add an Initialize Data –activity and double-click it. In the Details Information click Add and a new parameter named Parameter 1 will be added. Now click Parameter 1, change the name to UserName, click Ok and click Finish.

Add a Get User –activity, link it with the previous activity and double-click it. In the Filters click Add. In the Filter Settings –popup, select as NameSam Account Name, select as RelationEquals, right-click the field next to Value and select Subscribe > Published Data. In the Published Data –popup, select with ActivityInitialize Data, select UserName and click Ok, click again Ok and then click Finish.

Add a Get Organizational Unit –activity, link it with the previous activity and double-click it. In the Filters click Add. In the Filter Settings –popup, select as NameOrganizational Unit, select as RelationEquals, set as Value<aOUName>, click Ok and then click Finish.

Note: This is an optional activity that I use for the next activity to only get specific groups used for application distribution. An other option might be to check on specific group names, or anything that makes the groups differ from other groups.

Add a Get Group –activity, link it with the previous activity and double-click it. In the Properties click Optional Properties…. In the Add/Remove Property –popup select Search Root, click >> and click Ok. Right-click the field next to Search Root and select Subscribe > Published Data. In the Published Data –popup, select with ActivityGet Organizational Unit, select Distinguished Name and click Ok. Then select Filters andclick Add. In the Filter Settings –popup, select as NameMember, select as RelationEquals, right-click the field next to Value and select Subscribe > Published Data. In the Published Data –popup, select with ActivityGet User, select Distinguished Name, click Ok and click again Ok. Then select Run Behavior, select Flatten and click Finish.

Add an Return Data –activity link it with the previous activity and double-click it. In the Details right-click the field next to APPId and select Subscribe > Published Data. In the Published Data –popup, select with ActivityGet Group, select Sam Account Name, click Ok and click Finish.

Note: To get the APPId String in the Return Data –activity go to the Properties of the runbook and add it in the Returned Data. Also keep in mind that the runbook has to return APPId, to be functional, as the MDT –script (ZTIExecuteRunbook.wsf) will specifically check for that (see the next paragraph for an explanation).

MDT

Now let’s take a look at the MDT –script (ZTIExecuteRunbook.wsf) that is used to execute a runbook via a task sequence. By default this script will just get the returned data from the runbook and make it into a task sequence variable, via this line of code:

oEnvironment.Item(sName) = sValue

As I wanted to keep the default behavior of the script, I adjusted the script to check for a specific name (APPId) in the returned data of the runbook. When the script finds it, the script will cut its comma separated value into pieces and create a new task sequence variable for every piece. These variables are based on the task sequence base variable (see the next paragraph) and can be used, in the task sequence, to install applications according to a dynamic variable list. This all means that I replaced the previous line of code for the following code snippet (don’t forget to update the Distribution Points after updating the script!):

Task Sequence

Now let’s start with configuring the task sequence. The task sequence needs three adjustments (five steps), one to set the User Device Affinity, one to execute the runbook and one to install the applications based on a base variable. For these adjustments follow the next steps:

Add a Set Task Sequence Variable –step, set Task Sequence Variable to SMSTSAssignUsersMode and set Value to Auto.

Add a Set Task Sequence Variable –step, set Task Sequence Variable to SMSTSUdaUsers and set Value to <DomainName>\%PrimaryUser%.

Note: PrimaryUser is a variable that I use to set the primary user for a device (User Device Affinity) and to find the group memberships. There are many methods to set this variable and during this testing I used a computer variable for that.

Add and Execute Runbook –step, fill in with Orchestrator Server<anOrchestratorServer> and Browse with Runbook to the just created runbook. Then select Specify explicit runbook parameters, fill in with UserName%PrimaryUser%, and select Wait for the runbook to finish before continuing.

Note: APPId is the variable that is returned by the runbook of the previous step. After the modifications to the ZTIExecuteRunbook –script it captures that variable and turns it’s value into multiple task sequence variables. Those variables now all contain the base variable name plus a number suffix starting at 01.

Result

Like last week, after all the configuring it’s now time to take a look at what the results are when the task sequence is done. This time I will show the results of how the application groups are passed on from the runbook to the task sequence. The first picture shows the application groups in the Output Parameters of the runbook in the Orchestrator Console. Then the second picture shows how the Execute Runbook –step (ZTIExecuteRunbook.log) processes the multiple groups into multiple task sequence variables and at last the third picture shows how the Install Application –step (SMSTS.log) processes the task sequence variables into applications that have to be installed.

Note

In case the name of the groups are not equal to the applications, that need to be installed, and it’s not possible to easily extract the application name from the group name, then it might be necessary to use a Map Published Data –activity in the runbook. This way it can easily turn a group name into an application name, but the biggest down-side is that it will be a static list.then.

To end this post, I would like to thank my colleague Bart Timmermans for helping me better understand the (un-)logics of Orchestrator.

The power of Orchestrator 2012 to automate actions is getting bigger and bigger, as the community for it grows and by that the number of Integration Packs (IPs). Of course there are also IPs for ConfigMgr, from both Microsoft itself and the community (via CodePlex). Besides that there wasn’t a real integration between ConfigMgr and Orchestrator, yet, but with MDT 2012 Update 1 a really nice new cool feature was introduced. This feature is the Execute Runbook –step during a Task Sequence. It gives anyone, with or without real programming skills, more robust options during a Task Sequence, as long as an IP exist for the action anyone wants to perform. Just remember, lots of these IPs are created by the community. So deliver useful feedback on them, or even better add your own actions, or IPs.

Prerequisites

In this post I want to show this new feature by creating a runbook for, an often requested script, or step, to move a(n existing) computer to a different OU. For the rest of the post the following points are prerequisites:

A Microsoft Deployment Toolkit 2012 Update 1 –package. This package contains the necessary scripts to execute a runbook during a task sequence.

The Nework Access Account needs to be “Orchestrator User”. By default the Execute Runbook –step will use the credentials of the Network Access Account to connect with Orchestrator.

Register, Deploy and Configure the Active Directory IP from Ryan Andorfer. I used this one, because it was easy to set up and, even more important, it works (even with Orchestrator 2012 SP1 BETA)!

The account used in the Connection Credentials needs to be at least member of the Account Operators –group in the Active Directory (AD). Otherwise it can’t move an object in the AD.

Runbook

Let’s start with configuring this nice and basic runbook. This runbook will contain three steps with the following configuration:

Add an Initialize Data –activity and double-click it. In the Details Information click Add and a new parameter named Parameter 1 will be added. Now click Parameter 1 and change the name to ComputerName click Ok and click Finish.

Add a Get Object DistinguishedName –activity, link it with the previous activity and double-click it. In the Properties, fill in with DomainName<aDomainName> and fill in with Object Classcomputer. Then right-click the field next to Object Name select Subscribe > Published Data. In the Published Data –popup, select with ActivityInitialize Data, select ComputerName, click Ok and then click Finish.

Add a Move AD Object –activity, link it with the previous activity and double-click it. In the Properties right-click the field next to Source Object LDAP Path select Subscribe > Published Data. In the Published Data –popup, select with ActivityGet Object DistinguishedName, select Object_LDAP_Path and click Ok Then fill in with Destination Container OU LDAP Path<aOULDAPPath> and click Finish.

Note: Of course the Destination Container OU LDAP Path can also be (partly) filled with a Published Data. This basic sample is just to show the possibilities.

Task Sequence

Now let’s start with the configuring the task sequence. To execute the runbook from the task sequence add the following steps and configuration:

Add and Execute Runbook –step, fill in with Orchestrator Server<aOrchestratorServer> and Browse with Runbook to the just created runbook. Then select Specify explicit runbook parameters, fill in with ComputerName%_SMSTSMachineName% and click Ok.

Note: By doing this the ComputerName –parameter from the Initialize Data –activity will be set to the computer name of the system running the task sequence.

Result

The default ConfigMgr task sequences are not able to move a computer object to an OU when it already exist in the AD. Running this task sequence will now result in the computer object being moved to the OU specified in the Move AD Object –activity, even when the computer object already existed in the AD. There are multiple places to look for the results of this action. Think about the log files (smsts.log and ZTIExecuteRunbook.log), the AD and the Orchestration Console. Of this last option I’ll show the results here:

This week, for me, was all about deploying Windows Server 2012 (which is currently still in RC), with ConfigMgr 2012 SP1 (which is currently still in CTP) and MDT 2012 Update 1 (which is currently still in BETA). So it was one big test case, but it showed a lot of possibilities for the coming releases.

For those who follow me on twitter this post will contain a lot more information about the short tweets that I already did the last week. For instance, the need for running your own Build-and-Capture Task Sequence got a lot smaller with Windows Server 2012 (and Windows 8), because the default install.wim will install on the C-drive ánd ConfigMgr 2012 brings Offline Servicing. So when you’re used to deploy a thin image, you can use the default WIM -image and schedule the Updates on that image through ConfigMgr 2012 (without running a Build-and-Capture).

But what I really want to show in this post are the different possibilities for deploying Windows Server 2012 including some random Roles and Features. The three most used options are Powershell, DISM and MDT. The next examples will all install the same role (WDS Transport Server) and the same feature (BranchCache). Why these features? Well, actually just because they fitted nice together in a screenshot with the MDT –method.

Powershell

The first method that I want to show is deploying Windows Server 2012 and install Roles and Features via Powershell. This can be done quickly, by performing the following steps:

Create a Install an existing image package –Task Sequence, with the mentioned packages of the previous steps (no need for the steps State Migration, Include Updates and Install Updates).

Edit the new Task Sequence and add a Run Command Line –step (see picture). Now add the command line Powershell.exe Install-WindowsFeature –Name WDS-Transport, BrancheCache.

Note: To find the name of the features that you want to install, just use: Powershell.exeGet-WindowsFeature. Also good to know, in Powershell you don’t have to specify the top-level role/ feature before you can install a sub-level feature.

Dism

The second method that I want to show is deploying Windows Server 2012 and install Roles and Features via Dism. This can be done quickly, by performing the following steps:

Create a Install an existing image package –Task Sequence, with the mentioned packages of the previous steps (no need for the steps State Migration, Include Updates and Install Updates).

Edit the new Task Sequence and add a Run Command Line –step (see picture). Now add the command line Dism.exe /Online /Enable-Feature /FeatureName:Microsoft-Windows-Deployment-Services /FeatureName:Microsoft-Windows-Deployment-Services-Transport-Server /FeatureName:PeerDist.

Note: To find the name of the features that you want to install, just use: Dism.exe /Online /Get-Features. Also good to know, in Dism you do have to specify the top-level role/ feature before you can install a sub-level feature.

MDT 2012 Update 1

The third method that I want to show is deploying Windows Server 2012 and install Roles and Features via MDT 2012 Update 1 (which is currently still in BETA). This can be done quickly, by performing the following steps:

Create a Install an existing image package –Task Sequence, with the mentioned packages of the previous steps (no need for the steps State Migration, Include Updates and Install Updates).

Edit the new Task Sequence and add a Use Toolkit Package –step. Now add a Install Roles and Features –step. Here you can select the Operating System, the Roles and the Features (see picture).

Note: During my testing I noticed that this doesn’t work with Windows Server 2012 RC, yet, as I get an Unknown OS Current version error in my logs. I’ll assume that this is fixed with the full releases of both products.

For those who didn’t read it on Twitter, Facebook or mail yet, MDT 2012 B1 is available for download! Some of the best things that are mentioned in the release notes, are that it supports ConfigMgr 2012 B2 and also still supports ConfigMgr 2007 SP2! Besides that it also supports the deployment of ALL operating systems from Windows XP and Windows Server 2003 until now. So it only delivers extra’s! For more information, read here the mail of Microsoft Connect:

Thanks for your ongoing interest and participation in the MDT beta review program. We hope you’ll take the time to preview and provide feedback on MDT 2012 Beta 1.

Microsoft Deployment Toolkit (MDT) 2012 Beta 1 rides the next wave of System Center releases with support for System Center Configuration Manager 2012. For Lite Touch installations, MDT 2012 improves the overall client-side user experience, while also providing behind-the-scenes enhancements for partitioning, UEFI, and user state migration. These features, combined with many small enhancements, bug fixes, and a smooth and simple upgrade process, make MDT 2012 Beta 1 more reliable and flexible than ever.

Tell us what you think!We value your input. Download the beta on Connect and tell us what you think!Please submit your feedback through Connect and direct any support questions you may have to satfdbk@microsoft.com.

AvailabilityThis program is now open. The beta review period will run through August 2011.

MDT works with the Microsoft Assessment and Planning Toolkit and Security Compliance Manager to help you plan, securely deploy, and manage new Microsoft technologies—easier, faster, and at less cost. Learn more at http://www.microsoft.com/solutionaccelerators.

Thank you for your interest in the development of MDT. We look forward to receiving your feedback!

Award

Subscribe to updates

About

I’m Peter van der Woude, born in 1983 and I’m living together with my wife and two sons in the Netherlands.

Currently I work for KPN Consulting. At this moment my main focus is Enterprise Client Management via Microsoft Intune and/ or System Center Configuration Manager (ConfigMgr 2007/ 2012/ CB) and I love it!