Automated Driver Import in MDT 2013

As a follow up to my previous post, I also have developed a script to automate the import of drivers into MDT 2013.  This PowerShell script takes a source folder structure and duplicates the top two levels of folders in the MDT Deployment Share “Out-of-box drivers ” branch.  The script then imports all drivers found in the source directories to the matching folders in MDT.

All we have to do is extract all drivers for a given computer model into an appropriately named folder in the source directory, and then run the script.

2015 Update:
Added parameter validation, and a check to prevent updating of the “supported models” output file if the script is not being run against the production deployment share. Also applied minor code tweaks to support Windows 10.

Advertisements

Rethinking Driver Management in MDT 2013

We have been using the Microsoft Deployment Toolkit (MDT) in LTI/Lite Touch mode here at the University for a long time now.  Why, we used it to deploy XP back when MDT still was called the Business Desktop Deployment Solution Accelerator (BDD).  In this time, we have gone though several different driver management methods.  Gone are the nightmare days of dealing with OEMSETUP files, $OEM$ directories, can elaborate “DriverPack” injection scripts for XP (thank goodness).

With the release of Vista, we moved from a PnP free-for-all model of driver detection.  After Windows 8.0, we found we really needed to separate our drivers by operating system.  Thus, we created Win7, Win8, and WinPE driver selection profiles.

But now we are finding that driver sprawl is becoming a major issue again.  On many new systems we run though a seemingly successful deployment, but end up with a non-responsive touch screen, a buggy track pad, and (sometimes) a very unstable system.

Starting this week, we are trying a new hybrid driver management approach.  We will create a driver folder for each computer model sold though our computer depot.  I have developed a custom bit of VBScript to check to see if the hardware being deployed to is a known model.  Driver injection will be restricted to this model if a match is found.  The script contains additional logic to detect support for both Windows 7 and Windows 8 variants, and to select the most current drivers detected.  Unknown models will fall back on the PnP free-for-all detection method.

Here is how it works…

  1. Create a new group in your OS deployment task sequence named “Custom Driver Inject”, or something similar.  Grouping all actions together will allow easier transfer of these custom actions to other Task Sequences:
    DM-DriverInjectGroup
  2. Under this new group, add a new action of type “Set Task Sequence Variable”.  Name the variable “TargetOS”,and set the value to the OS that you are deploying from this task sequence.  You must follow the same naming convention that you use in your Out-of-box driver folder.  I use Win(X), where (X) is the major OS version of the drivers in the folder.  In this example, I have chose “Win8”:
    DM-SetTargetOS
  3. Add an action of type “Run Command Line”.  Name this action “Supported Model Check”.  Under the Command line field, enter “cscript “%SCRIPTROOT%ZUVMCheckModel.wsf”.  (We will import this script into the deployment share later on.)
    DM-RunModelCheckScript
  4. Add a sub-group named “Supported Model Actions”.  Under the “Options” tab, add a condition of type “Task Sequence Variable”.  Use the variable “SupportedModel”, the Condition “equals”, and the Value “YES”.  (The SupportedModel variable gets set by the CheckModel script run in the previous step.):
    DM-ConditionalGroup
  5. Under this new group, add a new action of type “Set Task Sequence Variable”.  Name this task “Set Variable DriverGroup002”.  Under “Task Sequence Variable”, set “DriverGroup002”, and set the value to “Models%TargetOS%%Model%”.  (Note:  You could use “DriverGroup001”, but I already am using this variable to hold a default group of drivers that I want added to all systems.  The value “%TargetOS%%Model%” defines the path to the driver group in the deployment share.  If you use a different folder structure, you will need to modify this path.):
    DM-SetDriverGroup
  6. Create a new task of type “Inject Drivers”.  Name this task “Inject Model-Specific Drivers”.  For the selection profile, select “Nothing”.  Be sure to select “Install all drivers from the selection profile”.  (NOTE: The dialog implies that we will be injecting only divers from a selection profile.  In fact, this step will inject drivers from any paths defined in any present “DriverGroupXXX” Task Sequence variables.)
    DM-InjectModelDrivers
  7. Now, under our original Custom Driver Inject group, add a new task of type “Inject Drivers”.  Choose from the selection profile “All Drivers”, or use a different fallback selection profile that suits the needs of your task sequence.  This time, select “Install only matching drivers from the selection profile”:
    DM-InjectUnsupported1
    Under the “Options” tab, add the condition where the “Task Sequence Variable” named “Supported Model” equals “NO”:
    DM-InjectUnsupported2
    This step will handle injection of matching drivers into hardware models for which we do not have a pre-defined driver group.
  8. Optionally, you now can open the “CustomSettings.ini” file and add the following to your “Default” section:
    DriverGroup001=Peripherals
    (I have a “Peripherals” driver group configured which contains USB Ethernet drivers used in our environment.  These are a necessity when deploying to hardware that does not have an embedded Ethernet port, such as the Dell XPS 12 and XPS 13.  You also could add common peripherals with complicated drivers such as a DisplayLink docking station or a Dell touch screen monitor.)
  9. Add the “ZUVMCheckMedia.wsf” script to the “Scripts” folder of your deployment share.  The code for this script is included below.  I think the script should be fairly easy to adapt for your environment.
  10. Finally, structure your “Out-of-Box Drivers” folder to contain a “Models” folder, and a single folder for each matching hardware model in your environment.  I get most of our driver collections from Dell:
    http://en.community.dell.com/techcenter/enterprise-client/w/wiki/2065.dell-driver-cab-files-for-enterprise-client-os-deployment.aspx
    (NOTE:  Thanks Dell!)
    The real challenge of maintaining this tree is in getting the model names right.  Use “wmic computersystem get model” to discover the model string for any new systems in your environment.  A table of a few current models I have been working with is included below.

Dell Marketing Model Name to WMI Name Translator Table:

  • Dell XPS 12 (first generation) – “XPS 12 9Q23”
  • Dell XPS 12 (second generation) – “XPS 12-9Q33”
  • Dell XPS 13 (first generation) – “Dell System XPS L321X”
  • Dell XPS 13 (second generation) – “Dell System XPS L322X”
  • Dell XPS 14 – “XPS L421Q”
  • Dell Latitude 10 – “Latitude 10 – ST2”
  • VMware Virtual Machine – “VMware Virtual Platform”
  • Microsoft Hyper-V Virtual Machine – “Virtual Machine”

A fun nuance we encountered last week was a Latitude E5430 model that contained “no-vPro” after the model number. Dell does not provide separate driver CABs for vPro/non-vPro models, so I added a regular expression test for Latitudes, and strip any cruft after the model number. There is one more problem down…

The following site contains a list of older model name translations:
http://www.faqshop.com/wp/misc/wmi/list-of-wmic-csproduct-get-name-results
As you can see, most Latitudes and Optiplexes follow sane and predictable model name conventions. I wish the same were true for the XPS.

Finally, I am indebted to the following sources for their generously detailed posts on driver management. Without their help, I doubt I would have been able to make this solution fly:

Jeff Hughes of the Windows Enterprise Support Server Core Team:
http://blogs.technet.com/b/askcore/archive/2013/05/09/how-to-manage-out-of-box-drivers-with-the-use-of-model-specific-driver-groups-in-microsoft-deployment-toolkit-2012-update-1.aspx

Andrew Barnes (aka Scriptimus Prime), whose posts on MDT driver management give the basics DriverGroups and model selection:
http://scriptimus.wordpress.com/2013/02/25/ltizti-deployments-injecting-drivers-during-deployment/
AND, of automating driver import into MDT (written for MDT 2012… some changes required for 2013):
http://scriptimus.wordpress.com/2012/06/08/mdt-2012-creating-a-driverstore-folder-structure/

The incredible Michael Neihaus, who in this post discusses the use of DriverGroups and Selection Profiles:
http://blogs.technet.com/b/mniehaus/archive/2009/09/09/mdt-2010-new-feature-19-improved-driver-management.aspx

And finally Eric Schloss of the “Admin Nexus”, who give me the idea of developing a fallback for systems that do not match a known model. It was this key bit of smarts that gave me the confidence to move forward with a model-specific driver grouping strategy:
http://adminnexus.blogspot.com/2012/08/yet-another-approach-to-driver.html

ZUVMCheckModel.wsf script:

(NOTE: The filename in GitHub is assigned a “.vbs” extension, but you should use “.wsf” when saving it. This was done to allow for useful syntax highlighting of the GitHub Gist.)

Note: Post updated Fall 2015 to correctly handle Windows 10 operating systems.