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:
One of the new features in the .NET Framework 3.5 SP1 is ADO.NET Data Services. This enables you to expose the contents of a data source, e.g. a SQL Server database, through something that looks roughly like an RSS feed, accessed in a similar manner to a web service. That’s nice but why do you care as an IT pro? Well, it’s a convenient way of making the contents of the MDT database available to programs or scripts without forcing them to use ADO to access SQL Server directly.
The best part of ADO.NET Data Services: You really don’t need to write any code. Just walk through a few Visual Studio 2008 wizards and you’re done – almost. There are two lines of code that I added, one to day that all the selected tables and rows can be accessed read-only, and a second that generates detailed errors if something doesn’t work. The basic process is described at http://msdn.microsoft.com/en-us/data/cc745957.aspx. (So I lied – you have to write two lines of code.)
The harder part of this is deploying the resulting ADO.NET Data Services project to an IIS server. You need to have .NET 3.5 SP1 installed, then IIS and ASP.NET need to be installed. You might need to run “ServiceModelReg.exe –i” to get the ADO.NET Data Services and WCF logic registered in IIS, see http://msdn.microsoft.com/en-us/library/ms732012.aspx for details. You will definitely need to edit the database connection string in the Web.Config file to point to your server (and optionally the instance) as well as the database (Initial Catalog) that needs to be used. And you might need to grant access to SQL Server, the database, and the database tables and views. (See http://msdn.microsoft.com/en-us/library/ms998320.aspx if SQL Server is on the same machine.) Really, it’s not that bad :-)
The actual ADO.NET Data Services files need to all be dropped in a directory. After doing this, set up an application in IIS that points to this directory. At that point, if everything is set up right, you should be able to access the the web service via a browser. To test it out, try a URL like this:
http://yourserver/YourApplicationName/MDTDatabase.svc
If that gives you a list of objects available in the database (you might need to tell IE not to display the result in RSS Reader view to see the real contents – in IE8, that’s configured on the “Content” tab from the “Feeds and Slices” settings dialog), you know at least IIS, .NET, and ADO.NET are fine. Then try a more specific URL to request all the computer records:
http://yourserver/YourApplicationName/MDTDatabase.svc/ComputerIdentity
That should result in something that looks like this:
Yes, kind of weird looking, but pretty easy to consume in a script. So that’s the next step – making use of this data. More on that in the next posting.
The full solution (Visual Studio project, source, binaries, etc.) is attached.
For those of you who customize the MDT wizards, you may want to check out the new version of the MDT Wizard Editor at http://mdtwizardeditor.codeplex.com. The latest version 2.0, uploaded today, includes a few fixes (e.g. properly encoding XML file entries in CDATA sections), adds support for MDT 2010, and includes a few new features.
The first change you will notice is that there is now a menu bar:
Use the “File” menu to open menu definition files (XML files), save your changes, and to exit the program. Use the “Wizard” menu to test a wizard definition file after you have made changes.
The testing process is the most significant change in this new version. It will gather information from the machine (running ZTIGather, as long as it can find it) and then display all of the variable values before starting the wizard:
You can modify variables, remove variables, add variables – whatever you would like to do. When you are ready to run the wizard, click the “Run” button. Once you have completed the wizard, the dialog will be updated to show you the variables that were set after the wizard completed:
In this case, you can see the additional variables that were defined for keyboards, applications, BitLocker, etc.
If you find any issues with this release, or if you have any suggestions on how to improve the release (subject to my available time), please use the CodePlex “Issue Tracker” to submit new items.
When MDT 2010 replicates content to a linked deployment share, you can choose whether to copy “standard folders” as part of that replication process. These folders (Scripts, Tools, $OEM$, USMT) might be required by one or more of the task sequences being replicated, so we give you that option. In the case of media, we always copy these four standard folders; you don’t get a choice as we assume everything in those folders is required by the current deployment share and therefore is also required by the media.
We have periodically received requests to allow for the replication of additional folders to linked deployment shares, as well as the inclusion of additional folders when creating media. As a result of those requests, we added a mechanism for specifying a list of extra folders. But there’s one challenge for that: We didn’t provide a user interface for configuring those, so you have to use PowerShell to do it. Unfortunately the documentation doesn’t even mention that this is possible, so consider this blog entry a documentation addendum :-)
From a PowerShell session, you would first need to load the MDT PowerShell snap-in (“Add-PSSnapIn Microsoft.BDD.PSSnapIn”) and then connect to the deployment share (simplest way is “Restore-MDTPersistentDrive” to get all the drives connected that you use in the Deployment Workbench). In the case of linked deployment shares, you can get all the current properties like so:
Then setting the ExtraFolders property (which is empty by default) is achieved using “Set-ItemProperty”:
Because the ExtraFolders property is a list (array), you always need to specify the values as I did, using the PowerShell syntax of @(“Value1”, “Value2”). If you only have a single value, it would look like @(“Value1”).
Media works the same way:
The folders you specify need to exist at the top level of the deployment share. In my examples above, my deployment share is “C:\DeploymentShare” so the folders that must exist are “C:\DeploymentShare\MyFolder1” and “C:\DeploymentShare\MyFolder2”. Make sure you specify folders that actually exist – otherwise you’ll get errors when MDT tries to copy those folders.
After doing this, you’ll notice an additional line in the output, highlighted below, telling you how many extra folders were copied:
In MDT 2008, we provided unknown computer support for ConfigMgr 2007, since it didn’t provide that capability – you first had to import new computers into the ConfigMgr database before you could install an OS, so MDT helped automate that process. When ConfigMgr 2007 R2 was released, it included unknown computer functionality, so we have now removed most of that from MDT 2010.
One of the useful parts of this unknown computer process was a pre-execution hook that would run a wizard, leveraging the same wizard framework that we used for MDT 2010 Lite Touch deployments. This was useful because we provided all the pieces to make it work: the TSCONFIG.INI file that tells ConfigMgr what to run, the script that gets executed by ConfigMgr (referenced in TSCONFIG.INI), the rules processing logic to gather information from WMI and other data sources, and the wizard files themselves.
With MDT 2010, we’ve left these pieces in place, but set them up to do something more basic: prompt for a new computer name. This is provided as a sort of general purpose “sample”, showing how to hook this into ConfigMgr. While you might not find the sample particularly useful, you can edit the wizard definition (using Notepad or something like the MDT Wizard Editor, http://mdtwizardeditor.codeplex.com/) to add additional panes.
All the files related to this general purpose sample are located in the “C:\Program Files\Microsoft Deployment Toolkit\SCCM” directory:
So if you wanted too do some customization, the files you would want to change are the “Deploy_SCCM_Definition_ENU.xml” (to add or change wizard panes) and “Deploy_SCCM_Scripts.vbs” (to specify additional initialization or validation logic).
To actually get these pieces added into a boot image, you can check the “Add media hook files to enable the Deployment Wizard for this boot media” checkbox when running either the “Create Boot Image using Microsoft Deployment” wizard (which creates only new boot image which you would then need to configure the task sequence and ISOs to use) or the “Create Microsoft Deployment Task Sequence” wizard (which can create a new boot image as part of the task sequence creation process).
Booting from this boot image, you should see a wizard that looks like this:
You can then specify the computer name you want, which will set the OSDComputerName task sequence variable. Like I said, pretty simple, but provided as a starting point for your own customizations – just edit the XML and VBS files, create a new boot image, and then deploy. (Remember that all of these files are actually embedded in the boot image WIM file, so when you make changes you either need to create a new boot image or mount the existing one to change those files. Update the distribution points after making changes.)
I’ve also attached a short video that shows the startup process (including the initial ConfigMgr wizard screen that can be used for specifying static IP information and for typing in the media password).
People have made fun of ConfigMgr, and every version of SMS before that, for being “slow moving software”. For those of you who try to deploy software to a machine and then wait for it to actually happen, you know what I mean: it was guaranteed to take two minutes from the time you advertised it to the time the first clients acted on it.
With ConfigMgr SP2, a significant portion of that delay (which was actually happening on the client side, not on the server) was removed. Now, I can add a new machine into a collection, then go to the machine and initiate a machine policy retrieval cycle and see a popup for new advertisements within a few seconds. The first time that happened I was a bit startled by the result – surely something must be wrong. But it wasn’t, the advertisement really was available that quickly.
ConfigMgr SP2 is still available as an RC through http://connect.microsoft.com, so you can try it out in your lab if you want. It is expected to be released by the end of October.
Yes, I’ve been promising this blog posting for quite some time. And I’ve been working on this for quite some time, but kept getting distracted either by new releases (Windows 7, Windows Server 2008 R2, MDT 2010, SCVMM 2008 R2, etc.) or by the addition of new features to the PowerShell scripts that I’ve been using. But I’m determined to get this first part finished today. Shame sometime can be a motivator :-)
First you need some additional background information. I did a presentation at the Microsoft Management Summit, TechEd US, and TechEd Australia where I talked about how to use MDT 2010, ConfigMgr 2007, and SCVMM together for two main purposes:
So this posting is covering the first part, using MDT 2010 Lite Touch together with SCVMM to create an image factory. Here’s more of a logical picture of what I am talking about:
So imagine that you have created a deployment share in MDT 2010 Deployment Workbench, imported your operating systems and all the other required files, and created multiple task sequences to build your reference images. Now you want a quick and easy way to run all of those task sequences, without having a pile of hardware (so virtual machines are good) and without needing to manually initiate the process on each machine (automating the wizard). That’s where the “image factory” comes in.
To implement this, I created a set of PowerShell scripts to initiate the step-by-step process above. The scripts and their purpose:
These scripts need to know some details from your environment. Rather than hard-coding that information in the scripts themselves, this information is stored in a separate XML file named “MDTImageFactorySettings.xml.” This file contains the following settings:
So what is required to set this up in your environment? First, make sure that your environment is functional, as these scripts won’t magically fix things:
Once that’s done, you can perform the following setup steps:
You should then see that connections are made to the MDT deployment share, the MDT database (the settings for the database are retrieved from the deployment share), and the SCVMM server. A virtual machine will be created for each enabled OS deployment task sequence in the specified folder (and subfolders, recursively), and then the specified number of VMs will be started. As the first VMs complete they will shut down (as long as the task sequence finishes successfully) and new ones will be started, until all task sequences are finished.
As part of the VM creation process, new MDT database entries are created specifying the computer settings, associated to the MAC address of the network adapter for that VM. These settings include:
SkipWizard=YES SkipFinalSummary=YES TaskSequenceID=<the ID of the task sequence to run> AdminPassword=P@ssword DoCapture=YES ComputerBackupLocation=<deployment share UNC>\Captures BackupFile=<task sequence ID>.wim FinishAction=SHUTDOWN
So that specifies to skip all the wizards, run a specific task sequence, use a constant local admin password, capture an image to the deployment share using the task sequence ID to name the WIM file, and to shut down the VM when the whole process is complete.
Here’s what you might expect to see while the VMs are being created:
and while they are running:
That display will keep repeating until all task sequences are complete and the virtual machines shut down.
As the virtual machines complete, there will be two “outputs”: the WIM file that is written to the “Captures” directory of the deployment share, and the VHD file that is still attached to the VM. You can turn that VHD into an SCVMM template and use that when creating new VMs. If you do that, be sure to disconnect the ISO file from the virtual DVD drive and to configure the NIC to specify a dynamic MAC address. (More on that topic in a future blog post when we talk about virtual machine customization.)
That’s pretty much the whole process, but it is worth mentioning a few things in closing:
The “Part 2” blog posting will describe how to perform the same scenario using System Center Configuration Manager 2007 (with or without MDT), but it will take me some time to recover from this posting before I get to that one.
If I messed up the instructions or left something out, please let me know via e-mail, mniehaus@microsoft.com. The scripts attached to this blog entry are provided as-is, and are not supported by Microsoft. See the scripts for the full disclaimer.
Both MDT 2010 Lite Touch and ConfigMgr 2007 run the same task sequencer. This task sequencer can run any command that you want, just specify the command line to use. That’s the simple part – the harder part is figuring out what this command line should do. Often the command, a VBScript or PowerShell script, needs to get information from the task sequence itself, accessing variables in the task sequence environment. Remember, these task sequence variables aren’t environment variables – they are distinctly separate, so you can’t use the PowerShell “Env:” drive.
If you are using MDT, building a VBScript that includes the ZTIUtility.vbs script makes accessing task sequence variables pretty simple, as you can then reference something like this in your script:
sValue = oEnvironment.Item("MYVAR")
But PowerShell is now the rage – what if you wanted to do the same thing using PowerShell? Fortunately that’s not too difficult either. Here’s a simple example that gets the value of a particular variable:
$tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment Write-Host $tsenv.Value("_SMSTSLogPath")
You would then need to set up a task sequence step that ran that PowerShell script. In the Lite Touch case, I would suggest saving the file in the “Scripts” directory on the deployment share, for example as “Test.ps1”. You could then create a “Run command line” step in the task sequence that executes this command:
PowerShell.exe -File "%SCRIPTROOT%\Test.ps1"
If you were using MDT 2010 integrated with ConfigMgr, the same thing would work, but you would need to add the file to the “Scripts” directory of the MDT toolkit package. Alternatively, you could create a new software distribution package containing the PowerShell script, specify to use that package on the “Run command line” step of the ConfigMgr task sequence, and then specify a command line that assumes the script is in the working directory:
If you want to change a task sequence variable (or set a new one), you use the same “Value” method:
$tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment $tsenv.Value("MyVar") = "My Value"
Maybe you want to do something a little more involved, like create an transcript (log) of the execution of your script. You can use the _SMSTSLogPath variable to determine where to place the file:
# Determine where to do the logging $tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment $logPath = $tsenv.Value("_SMSTSLogPath") $logFile = "$logPath\$($myInvocation.MyCommand).log" # Start the logging Start-Transcript $logFile # Insert your real logic here Write-Host "We are logging to $logFile" # Stop logging Stop-Transcript
# Determine where to do the logging $tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment $logPath = $tsenv.Value("_SMSTSLogPath") $logFile = "$logPath\$($myInvocation.MyCommand).log"
# Start the logging Start-Transcript $logFile
# Insert your real logic here Write-Host "We are logging to $logFile"
# Stop logging Stop-Transcript
Another useful example is a script that logs the values of all task sequence variables:
# Determine where to do the logging $tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment $logPath = $tsenv.Value("_SMSTSLogPath") $logFile = "$logPath\$($myInvocation.MyCommand).log" # Start the logging Start-Transcript $logFile # Write all the variables and their values $tsenv.GetVariables() | % { Write-Host "$_ = $($tsenv.Value($_))" } # Stop logging Stop-Transcript
# Write all the variables and their values $tsenv.GetVariables() | % { Write-Host "$_ = $($tsenv.Value($_))" }
Or you could use the same technique to turn all the task sequence variables into PowerShell variables:
# Determine where to do the logging $tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment $logPath = $tsenv.Value("_SMSTSLogPath") $logFile = "$logPath\$($myInvocation.MyCommand).log" # Start the logging Start-Transcript $logFile # Convert the task sequence variables into PowerShell variables $tsenv.GetVariables() | % { Set-Variable -Name "$_" -Value "$($tsenv.Value($_))" } # Write out a specific variable value Write-Host $_SMSTSMDataPath # Get all the variables Dir Variable: # Stop logging Stop-Transcript
# Convert the task sequence variables into PowerShell variables $tsenv.GetVariables() | % { Set-Variable -Name "$_" -Value "$($tsenv.Value($_))" }
# Write out a specific variable value Write-Host $_SMSTSMDataPath # Get all the variables Dir Variable:
(Take out all the extra stuff and this could be reduced to two lines, the one that creates the COM object and the one that calls GetVariables.)
A few other notes worth mentioning:
You’ve probably gone through this cycle if you are using WDS to PXE boot computers to start bare metal Lite Touch deployments:
Fortunately, with the new “update” process in MDT 2010, described in more detail at http://blogs.technet.com/mniehaus/archive/2009/07/10/mdt-2010-new-feature-17-customizable-boot-image-process.aspx, it’s pretty simple to add a script to automate this process. First, the script:
Option Explicit Dim oShell, oEnv Set oShell = CreateObject("WScript.Shell") Set oEnv = oShell.Environment("PROCESS") If oEnv("STAGE") = "ISO" then Dim sCmd, rc sCmd = "WDSUTIL /Replace-Image /Image:""Lite Touch Windows PE (" & oEnv("PLATFORM") & ")"" /ImageType:Boot /Architecture:" & oEnv("PLATFORM") & " /ReplacementImage /ImageFile:""" & oEnv("CONTENT") & "\Sources\Boot.wim""" WScript.Echo "About to run command: " & sCmd rc = oShell.Run(sCmd, 0, true) WScript.Echo "WDSUTIL rc = " & CStr(rc) WScript.Quit 1 End if
Option Explicit
Dim oShell, oEnv
Set oShell = CreateObject("WScript.Shell") Set oEnv = oShell.Environment("PROCESS")
If oEnv("STAGE") = "ISO" then
Dim sCmd, rc
sCmd = "WDSUTIL /Replace-Image /Image:""Lite Touch Windows PE (" & oEnv("PLATFORM") & ")"" /ImageType:Boot /Architecture:" & oEnv("PLATFORM") & " /ReplacementImage /ImageFile:""" & oEnv("CONTENT") & "\Sources\Boot.wim""" WScript.Echo "About to run command: " & sCmd
rc = oShell.Run(sCmd, 0, true) WScript.Echo "WDSUTIL rc = " & CStr(rc)
WScript.Quit 1
You’ll need to update the image name in the string above if you’ve changed it from the default of “Lite Touch Windows PE (x86)” and “Lite Touch Windows PE (x64)” since the script doesn’t know what you’ve changed the values to. Save the edited script as something like “C:\Scripts\UpdateExit.vbs”. Then, edit the “C:\Program Files\Microsoft Deployment Toolkit\Templates\LiteTouchPE.xml” file so that these lines:
<!-- Exits --> <Exits> <Exit>cscript.exe "%INSTALLDIR%\Samples\UpdateExit.vbs"</Exit> </Exits>
Instead look like this:
<!-- Exits --> <Exits> <Exit>cscript.exe "%INSTALLDIR%\Samples\UpdateExit.vbs"</Exit> <Exit>cscript.exe "C:\Scripts\UpdateExit.vbs"</Exit> </Exits>
Then make a change that requires re-generating the WIM and ISOs, e.g. change something in bootstrap.ini. You’ll see in the “Update Deployment Share” output the generated WDSUTIL command that updates the boot image in WDS. If WDS is located on a different server, you’ll need to update the command in the script above to add “/Server:WDSServerName” to the command. (WDSUTIL must also be available on the machine, so you may need to install the RSAT WDS tools.)
Extra credit for someone who can convert this into a PowerShell script and look up the right boot image name :-)
I’ve been distracted while we worked on fixing the remaining bugs in MDT 2010, which was finally released today. Now it’s time to get back to the discussion on new features in MDT 2010. Next up on the list: improved driver management.
This is really a combination of two features we had already discussed:
with some capabilities added in that we haven’t already discussed. First, there are new options available in a Lite Touch task sequence’s “Inject drivers” step:
Now there are two options when injecting drivers:
You might choose the first option, you might choose the second – it just depends on how you want to do it. You might also choose to do both: you could create multiple “Inject driver” steps and specify different options and different selection profiles on both. For example, you might have one “always apply” selection profile with all the printer drivers that you support (whether currently attached or not) and an “only matching” selection profile for everything else. You could also set up multiple steps and place conditions on them, using different selection profiles and injection options based on the conditions (e.g. make and model).
Of course, if you want the process to be more dynamic, you can override the settings on the fly. I would foresee this being a very common scenario, where you either specify a different selection profile on the fly, or maybe instead specify a list of folders that should be used. To do this, you need to understand the available task sequence variables that can be configured through CustomSettings.ini:
It’s important to understand that these parameters have an “additive” effect. For example, if you specify a selection profile of “Everything” (all folders) and then specify “DriverGroup001=Toshiba\Tecra M400” the net result will be everything. But if you specified a selection profile of “Nothing” (no folders) and “DriverGroup001=Toshiba\Tecra M400” then the result would be just the one folder you specified. (DriverPaths values would be additive as well, but those aren’t recommended.)
So you have options. You can create multiple selection profiles and choose which one to use dynamically, something that gets messy if you just want one folder per selection profile (e.g. per model) since every new folder would require a new selection profile. Or you can choose the “Nothing” selection profile and then specify one or more folders via “DriverGroup”. I believe that will be the most common approach, as you can then do things like:
DriverSelectionProfile=Nothing DriverGroup001=%Make% DriverGroup002=%Make%\%Model% DriverGroup003=Peripherals
If you’ve already experimented with this and have some best practices to share, comments about challenges while implementing this, or just general questions, feel free to e-mail me at mniehaus@microsoft.com.