ConfigMgr 2012 SP1 with MDT 2012 Update 1, UDI Task Sequence and Bitlocker Error 6767

Redmond, we have a problem.  The “Client Task Sequence” template when used with Configuration Manager 2012 SP1 does not work too well when UDI is enabled and we want to Bitlocker our devices.

When we are performing a User Driven Installation, the MDT 2012 Update 1 template makes use of the ConfigMgr “Pre-provision Bitlocker” step, which adequately pre-provisions Bitlocker on the Operating System drive on a ‘used space only’ basis.  This is a good thing.   Later on in the Task Sequence we have an MDT specific step that uses the ZTIBde.wsf script which SHOULD configure and enable the protectors – but you may find that this will fail, resulting in an exitcode of 6767.  Tracing this error in the ZTIBde.wsf script takes us into a failure of the function that enables the Bitlocker protectors.  So what is going wrong?

Let us first understand that the ZTIBde.wsf was designed for MDT deployments primarily – with added ConfigMgr integration as an afterthought.  The ZTIBde.wsf script ON ITS OWN is capable of pre-provisioning Bitlocker in Windows PE AND ALSO, later (in the OS phase) configuring and enabling the protectors.  It’s a great little script.  In the MDT Client Task Sequence template however, the ZTIBde.wsf script is not used within the Windows PE phase to Pre-provision Bitlocker and instead the in-built ConfigMgr function is used.  The ConfigMgr function will pre-provision Bitlocker, however it does not then configure the appropriate variable that the ZTIBde.wsf Pre-provisioning function would and this is needed and consumed later by the ZTIBde.wsf script when it comes to Enabling the Bitlocker Protectors in the OS Phase.

The ZTIBde.wsf script has a section which checks if Bitlocker is enabled on the drive (IsBDE = TRUE) and also if the drive has NOT been pre-provisioned earlier (IsBDEPreProvisioned <> TRUE).  This test is used to accommodate the refresh scenario when the existing suspended protectors of a Bitlocker drive can simply be turned back on without having to configure any.  In the absence of the IsBDEPreProvisioned variable (or if it doesn’t equal TRUE) then this section of code will cause the script to skip over the configuration of any required protectors (specified in the UDI wizard) and simply try to enable any existing protectors, of which there are none – resulting in the error 6767 spat out by the EnableProtectors function.

So what do we need to do about this?  Well you could amend the script – but that wouldn’t be supported by Microsoft and your modifications could well be wiped out by any future revision (which may or may not address its shortcomings.  There are a few (non-exhaustive) alternatives that I could propose;

  1. If you are using the UDI Wizard AND you want the Bitlocker options to come through from it, then you should replace the “Pre-provision Bitlocker” step in the task sequence that uses the ConfigMgr function with the ZTIBde.wsf script – the very same script used later on to “Enable Bitlocker”.  This keeps the Pre-provisioning process and the Enable Bitlocker process solely in the MDT camp.  However, if you want the Recovery Key to be backed up to Active Directory then you will need to use a script afterwards to do that, or implement MBAM.
  2. If you are using the UDI Wizard AND are removing the Bitlocker configuration page but still want Bitlocker enabling then replace the “Enable Bitlocker” step in the task sequence with the ConfigMgr function – as you can specify the protectors used and also escrow the Recovery Key to Active Directory automatically.
  3. If you are NOT using the UDI Wizard but want to implement Bitlocker in your Task Sequence, then stick with the ConfigMgr step for pre-provisioning Bitlocker and replace the ZTIBde.wsf method for Enabling Bitlocker with the ConfigMgr function – for the same reasons as above.  In this scenario, you would need to ensure that your partitioning layout is suitable for Bitlocker.

Have fun with that!


MDT Task Sequencing: Where are my unattend.xml Local User Accounts?

I have been digging deeper and deeper into the functionality and relationships between ConfigMgr Task Sequencing, the unattend.xml/unattend.txt files and the MDT Scripts to better understand how these all come together – as opposed to just referring to all of it as ‘Witchcraft’.

A simple task, you might think, would be to automate the creation of additional local user accounts during an integrated MDT task sequence, so you could imagine my frustration when it seemed that the Local Accounts portion of the unattend.xml file I was pushing down with my ‘Apply Operating System Image’ step was being ignored completely.

It transpires, that the MDT “ZTIConfigure.wsf” script was working against my efforts and removing my customisations related to Local User Accounts, and we can see why within the script;

I can immediately understand the need to remove any AutoLogon and Run-Once entries, as we do not really want anything interfering with the Task Sequence steps – however the action of removing any local account entries perplexes me and I cannot think of any reason why this has been stipulated.

I commented out the offending lines in the ZTIConfigure.wsf, as shown above, saved my changes, updated the MDT Toolkit Files package on my DP’s and re-ran my task sequence – et voila; additional user accounts!

I investigated and contemplated other solutions prior to this, such as using task sequence ‘Run Command Line’ steps with the relevant ‘NET USER / LOCALGROUP’ commands, however I was not so keen on having the desired account password in plain text.  Another suggestion was to use a masked Collection Variable containing the password and referencing this variable during the task sequence – however this would not be practical in environments which have multiple OSD collections.