Michael Niehaus' Windows and Office deployment ramblings
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>
<?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
]]></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:
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:
Hi there,
I am trying to have this up and running on my test enviroment (Windows 2008 R2, WDS, MDT) but I am stuck on last 3 points.
If I will past <Pane>..</Pane> in same window where the functions are I am receiving Wizard Error - Cannot have ']]>' inside an XML CDATA block. Can you please advice what I am doing wrong?
My Custom Statment looks as follows:
oDataService.WebService = "http://server_name/MDTDatabase.svc/RoleIdentity"
Thank you in advance,
Tomasz Zajaczkowski
Hi Tomasz,
The code example above is meant to exist as a standalone wizard with the file name being Roles.xml. If you plan to add this to your existing wizard you will probably want to copy the code from <pane>...</pane> into your xml file and the functions into your vbs file.
As you can see from Michael's example above, he was able to include the functions within the xml file by using this statement:
<CustomStatement><![CDATA[ FUNCTIONS HERE ]]></CustomStatement>
Hope this helps!
P.S. Thanks for the great example Michael, didn't realize you could dynamically load vbs files in this manner.
Hi,
My mum alwyas said: read it twice, stupid!
I was able to add custom statment and Role pane to DeployWiz_Definition. Unfortunately when tested from from both Windows XP (litetouch script) and wizard itslef Wizard 'hangs' on Roles seletion with Loading Role and error message:
Line: 1
Char: 1
Error: Object required 'oResult'
Code: 0
URL: file://\\my_server\deploymentshare$\Scripts\Wizard.hta
Do you want to conitue running scripts on this page?
I am able to open http://my_server/MDT/MDTdatabase.svc/RoleIdentity from WDS/IIS server wihtout any problem but it's not accessible from Windows XP box.
Tomasz
If you're running a refresh or a custom deployment from inside an operatingsystem which isn't the server that hosts the web service you'll run into a cross site scripting (XSS) issue which either prevents the web service from running or pops up a warning.
You'll want to ensure that the site is in the local intranet zone and then you'll have to allow XSS for that zone. I do that by using two functions.
Call AllowCrossDomainScripting before the actual web service call.
Dim gXSS
Function AllowCrossDomainScripting
Dim oShell
Dim iVal
Dim strKey
strKey = "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1\1406"
Set oShell = CreateObject("WScript.Shell")
iVal = oShell.RegRead(strKey)
If Err = 0 Then
gXSS = iVal
End If
oShell.RegWrite strKey, 0, "REG_DWORD"
Set oShell = Nothing
Function ResetCrossDomainScripting
If IsEmpty(gXSS) Then
oShell.RegDelete strKey
Else
oShell.RegWrite strKey, gXSS, "REG_DWORD"
Another question:
I'm doing a only rule role installation of Windows 2008 R2.
I've just 2 screens: computername and role selection.
I've got a error on drivers injection. After debugging i found that sTargetBuild was nothing (it must be 5 or 6)
I had in LTIDriver.wsf if null then 6
but i don't know why it doesn't init.
when i tried by computer rule it works.
Thanks for your help (if you have a idea)
JCP
Are you sure about this:
... "<input type=checkbox name=Roles id=Roles" ...
because it wasn't init Role properties like this
I changed Roles by Role like this
... "<input type=checkbox name=Role id=Role" ...
After this last change it works (but i'm not sure it's this change which make it works. To be sure i've to rebuild my MDT environment)
Validate ?
this is very good but i am having minor issues. where i can see the roles but if i add application in the roles its not getting installed.
Am i missing sth??? thx
Nice, but have you an Update for MDT2012?