We have seen lots of requests over the past couple of years for a wizard pane that allows you to select from a list of roles that should be applied to a machine, where those roles are defined in the MDT database.  There are a few examples of this available on the web, implemented in different ways.  I’ll throw another one into the mix, this one using an ADO.NET Data Services web service to get the needed data.  (If you didn’t read my previous posting about this setup, click here.)

<?xml version="1.0" encoding="utf-8"?>
<Wizard>
  <Global>
    <CustomStatement><![CDATA[
' ***************************************************************************
' File:	Roles.xml
' Author:	Michael Niehaus
' Version:	1.0
' Purpose:	Display a list of roles from the MDT database, retrieved
'	using an ADO.NET Data Services.web service.  One
'	or more roles can be selected.  After they have been
'	chosen, CustomSettings.ini needs to be re-processed
'	to pick up the new settings.  Ideally this would be done
'	after the wizard is complete (just in case someone 
'	navigated back to the screen after initially making
'	changes), but that requires changing LiteTouch.wsf.
'
' NOTE:	Be sure to modify the web service URL below
'
' ***************************************************************************
Function InitializeRoleList
	Dim sScript
	Dim oDataService
	Dim oRole
	Dim sRoles
	' Make sure that ZTIDataAccess.vbs is available since it isn't loaded by Wizard.hta
	sScript = oFSO.OpenTextFile(oUtility.ScriptDir & "\ZTIDataAccess.vbs", 1, false).ReadAll
	On Error Resume Next
	ExecuteGlobal sScript
	On Error Goto 0
	' Call the web service
	Set oDataService = New WebService
	oDataService.WebService = "http://localhost:62932/MDTDatabase.svc/RoleIdentity"
	oDataService.Method = "REST"
	Set oResult = oDataService.Query
	' Process the roles to populate the list of checkboxes
	sRoles = ""
	For each oRole in oResult.SelectNodes("//d:Role")
		sRoles = sRoles & "<input type=checkbox name=Roles id=Roles enabled value='" & oRole.Text & "'>" & oRole.Text & "</input><br>"
	Next
	' If no roles were found, set the div to indicate that
	If sRoles = "" then
		sRoles = "<label class=errmsg style='display: inline;' >No roles could be found."
	End if
	' Update the pane
	RoleList.InnerHTML = sRoles
End Function
Function ValidateRoleList
	' Flush the value to variables.dat, before we continue.
	SaveAllDataElements
	SaveProperties
	' Process full rules (needed to pick up the role settings, apps, etc.)
	sCmd = "wscript.exe """ & oUtility.ScriptDir & "\ZTIGather.wsf"""
	oItem = oShell.Run(sCmd, , true)
	ValidateRoleList = True
End Function
]]></CustomStatement>
  </Global>
  <Pane id="Roles">
    <Body><![CDATA[<H1>Select the roles to be assigned to this computer.</H1>
<br>
<div class=TreeList id=RoleList style="height: expression( GetDynamicListBoxSize(this) );">
<label class=errmsg style="display: inline;" >Loading roles...
<!-- List goes here -->
</div>
]]></Body>
    <Validation><![CDATA[ValidateRoleList]]></Validation>
    <Initialization><![CDATA[setTimeout GetRef("InitializeRoleList"), 0]]></Initialization>
  </Pane>
</Wizard>

While this is set up as a stand-alone wizard, you can insert this into an existing deployment wizard using the MDT Wizard Editor by following these steps:

  1. Launch the MDT Wizard Editor.
  2. Open the DeployWiz_Definition_ENU.xml file.
  3. Click on the “Global” pane.  Click “Add” on the “Settings” pane and choose to add a new “CustomStatement”.
  4. Select the new “CustomStatement” at the end of the “Settings” list.
  5. Select the VBScript code above (from the first comment line to the last End Function line) and copy it to the clipboard.
  6. Paste the copied VBScript code into the text box in the MDT Wizard Editor.  Edit the web service URL to specify your ADO.NET Data Services web service URL.
  7. Select a wizard pane (the new pane will be inserted after this one, so select appropriately).
  8. Select all the text above from “<Pane” through “</Pane>” and copy it to the clipboard.
  9. Right-click on the selected pane name in the MDT Wizard Editor and choose “Paste”.

What, your MDT Wizard Editor doesn’t have a “Paste” option?  Well, you need to download a new version from http://mdtwizardeditor.codeplex.com/, as I just added the paste capability tonight (along with other general usability improvements – I forced myself to actually use the program to create the rules wizard pane above and fixed all the behaviors I didn’t like while I was at it).

A few notes to mention:

  • Because the wizard runs after CustomSettings.ini has been processed, the role settings, applications, etc. wouldn’t be processed as the “Gather” process isn’t run again.  To work around this, I added logic above to run ZTIGather.wsf again.  This could add a delay when clicking “Next”, so you might choose to do this later (possibly by modifying LiteTouch.wsf).  The other problem with running ZTIGather.wsf from this wizard pane:  If you navigate back to this wizard pane and uncheck an item, it’s too late – the settings for that role have already been added into the task sequence environment.
  • The MDT 2010 wizard hypertext application (Wizard.hta) doesn’t load the ZTIDataAccess.vbs script needed to make web service calls from a wizard pane.  To work around this, I added logic above to dynamically load the file.  The other alternative would be to edit Wizard.hta to tell it to include the file.
  • The role list is populated asynchronously so that the wizard doesn’t appear to be hung.  This is done by the “setTimeout” initialization statement above.  Note that the “Next” (or “Finish”) button will be enabled even while this is happening, so if you don’t want to wait you can probably go ahead and click the button to move on to the next pane.
  • If you don’t have the ADO.NET Data Services web service set up and working, don’t expect this wizard pane to somehow magically fix it :-)