Many of IT deployment professionals out there have a need of supporting multiple deployment shares. Whether it is for different departments, customers or environments the classic approach is that each deployment share means generation of a new boot image. Maintaining WDS, supporting all network and storage drivers for WinPE as well as enforcing consistency across all images is a real headache. The key is, of course, amending DeployRoot variable in bootstrap.ini. But this post is not about what to change, but more about HOW – the challenge is calling the script at a right place.
You have most likely figured out that leaving DeployRoot not specified will cause MDT wizard to prompt you to specify the path. In large organizations this is not a favoured approach as typically engineers doing the actual OS deployments not necessarily have knowledge of environmental setup, nor they need to know it (or credentials to each of the shares). In organization I work for the standard approach is to have an audit trail for every machine being imaged – and this needs to be captured before a Task Sequence is selected as some of builds being deployed by us are managed by third parties that don’t include (or don’t care for) our processes.
My favourite way of achieving this is via a custom HTA script, but you might as well use a crude batch file or a fancy PowerShell script – it’s up to you. In my implementation the HTA script sits in \Deploy\Scripts folder. I took liberty of linking Wizard.css found in the same directory and tweaking window behaviour – since it is also used by MDT wizard it ensures a consistent user experience and impression that everything is actually part of a one solution.
<head> <title>MDT share selector v0.1.4</title> <meta content="text/VBScript" http-equiv="content-script-type" /> <link href="Wizard.css" type="text/css" rel="stylesheet"> <HTA:APPLICATION ID="oWizard" APPLICATIONNAME="" ICON="Wizard.ico" SCROLL="no" SELECTION="no" INNERBORDER="no" BORDER="normal" SINGLEINSTANCE="no" SYSMENU="yes" exitbutton="No" MAXIMIZEBUTTON="no" MINIMIZEBUTTON="no" /> </head>
Further on VBScript kicks in and takes the user through relevant steps enforcing internal processes and creating an audit trail. Based on information entered by the user, the script goes to central server to pick relevant details, builds UNC path to deployment share and populates bootstrap.ini as required. Again, how you gather your information is up to you and your needs.
The trick is knowing how to call your script. Most likely you have already tried the usual suspects such as startnet.cmd and winpeshl.ini, but it turned out that MDT wizard kicks in first. Even though your script overwrites bootstrap.ini, the details have been already processed by the wizard so any changes don’t have any effect. There is a third place where Windows PE is implicitly looking for custom scripts: Unattend.xml. The file is located on root of your boot image and you will find it contains one command: wscript.exe X:\Deploy\Scripts\LiteTouch.wsf. All you need to do is to call your script(s) as synchronous command before that. The XML syntax also supports asynchronous command: the difference is synchronous command waits for completion before executing next command, while asynchronous does not. All being well, your new Unattend.xml should look somewhat like this:
<?xml version="1.0" encoding="utf-8"?> <unattend xmlns="urn:schemas-microsoft-com:unattend"> <settings pass="windowsPE"> <component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State"> <Display> <ColorDepth>16</ColorDepth> <HorizontalResolution>1024</HorizontalResolution> <RefreshRate>60</RefreshRate> <VerticalResolution>768</VerticalResolution> </Display> <RunSynchronous> <RunSynchronousCommand wcm:action="add"> <Description>Init</Description> <Order>1</Order> <Path>cmd /c X:\Deploy\Scripts\start.cmd</Path> </RunSynchronousCommand> <RunSynchronousCommand wcm:action="add"> <Description>CDM</Description> <Order>2</Order> <Path>MSHTA.exe X:\Deploy\Scripts\index.hta</Path> </RunSynchronousCommand> <RunSynchronousCommand wcm:action="add"> <Description>Lite Touch PE</Description> <Order>3</Order> <Path>wscript.exe X:\Deploy\Scripts\LiteTouch.wsf</Path> </RunSynchronousCommand> </RunSynchronous> </component> </settings> </unattend>
In my example I first call a batch file that imports few registry keys and synchronizes time with domain controller, then I call my HTA that amends bootstrap.ini as necessary. All being well – MDT will connect to required deployment share.