Drivers are a big part of getting Windows to work properly. Anyone who has ever had to troubleshoot a piece of hardware on Windows knows this. When generalizing an installation of Windows for capture with sysprep, all but the most basic drivers are removed. This makes the captured image applicable to many different types of hardware. During a task sequence, MDT runs a plug and play check, for hardware at a couple of different points to determine what drivers, if any, are needed. When a matching driver is found, it is injected into the image before it is applied to the computer’s hard drive. To do this, MDT has a folder/section in the deployment share that is dedicated to organizing and storing drivers. It is called “Out-of-Box-Drivers” (OOBD).
The basic INF files are what MDT needs for driver injection. Many drivers are distributed as packages, which come in the form of an executable. This is not what we need. If an executable is the only way a driver is available, it must be imported as an application into MDT, and installed via task sequence. Fortunately, OEMs like Dell, Lenovo, HP, and even Microsoft make bulk downloads of model-specific drivers available from their sites. Dell hardware drivers come in the form of a CAB file, which can be opened with the expand command, or with a compression/decompression utility like 7-zip.
Bulk-driver Download Sites for Dell, Lenovo, HP, and Microsoft (Surface)
I create a folder structure on the MDT server similar to “Drivers\Windows ##\Vendor\Model.” For example: D:\Drivers\Windows 7\Dell\OptiPlex 990
I do not delineate between x86 and x64 versions of drivers in my folder path because nearly all of my OS deployments are 64-bit. Dell combines x86 and x64 drivers in the same download. Many Dell drivers can be used on both platforms. Lenovo drivers will try to extract to their own, specified path, but that can be changed at runtime. Complete, downloaded driver packs can be between 300MB and 1,000MB in size, except for WinPE driver packs which are very small.
Using the expand command, I’ll extract the drivers to my folder structure.
expand C:\Users\jasonrw\Downloads\990-OptiPlex-ABCDE.cab -f:* “D:\Drivers\Windows 7\Dell\OptiPlex 990”
The command prompt window will scroll really quickly and end with the prompt returning. Now, we can import them into MDT. MDT is able to handle drivers in different manners. The basic default option is to throw all drivers into the same folder at the root OOBD directory. With that, a deployment task will search the entire OOBD store for the right drivers. This increases the chance of the wrong driver being selected. WMI is great, but it is not perfect. Another option is to break down the OOBD store by manufacturer/vendor or by operating system version. Creating folders for Windows 7 and Windows 10, respectively can help minimize the chance of a wrong driver being installed. I take it one step further, actually a couple of steps further. I still use MDT’s WMI hardware-querying capabilities, but I tell it exactly where to look.
I create a specific folder structure under OOBD that matches a specific WMI query I pass on to the deployment task. For example, Windows 7: Out-of-box-drivers\Windows 7\Dell Inc.\OptiPlex 990
The bottom two folder tiers each correspond to variable in a WMI query, Make and Model. To find the make or manufacturer of an OEM PC, run the following command from a command prompt.
wmic computersystem get manufacturer
The returns for Dell and Lenovo are “Dell Inc.” and “Lenovo”
To get the model, run the same command as above, but replace “manufacturer” with “model” Top that off with a folder for OS version and platform, and you have something to use. In the task sequence, a task variable can be inserted into the PreInstall phase, before the inject drivers step to tell the task sequence exactly where to look. The variable is “DriverGroup001”, and the value is “Windows 7 x64\%Make%\%Model%” This will allow a task sequence to correctly use a WMI query to find the drivers for the exact make and model being imaged.
The Inject Drivers step has its own settings that needs to be configured. For our purpose, the selection profile has to be set to “Nothing” with all drivers from the selection profile being used.
Selection profiles are the ultimate step toward driver control. They are a pre-defined selection of drivers that may encompass and individual model, or manufacturer. MDT ships with a few pre-defined selection profiles, but more can be created to suit any need. Given the exact control this approach provides, there is one detraction, it limits task versatility. Since a selection profile tells a task sequence exactly which drivers to use, MDT doesn’t query for them. The default setting for Inject Drivers is to query the entire OOBD store, but when “Nothing” is set, they querying is off. If it is desired that a task sequence only serve one or two makes of computers, this might be a good approach. I support about a dozen different models from two manufacturers, and I’d like my task sequences to be applicable to all.
I do use a selection profile to organize the drivers I use for my MDT Windows PE ISO/WIM files. Dell and Lenovo make drivers just for Windows PE available as a download too. I use the same approach as above to download, extract, and import the Windows PE drivers into MDT. Then, I create a selection profile for the Windows PE drivers and use that for my ISO/WIM file drivers.
To import drivers into OOBD, make your folders as desired, right-click the folder for the computer model, and choose “Import drivers.” A wizard will open, walking you through the process of importing the drivers from where they were extracted. It is real easy.
After the driver import, the deployment share must be updated. By default, MDT uses the all network and system drivers it has in the OOBD store for the Windows PE ISO/WIM file. This can be changed, as I described above, with a custom selection profile, but it is not mandatory. Still, note, that each time drivers are added and removed, the deployment share should be updated for those new drivers to be used. Some drivers are clearly depicted whether or not they are x86 or x64. In reality, many single drivers can be used on both platforms, but the descriptor files do not always indicate that to MDT. Thus, MDT will import the driver and override the specified platform. This is noted after all of the drivers have been imported for that operation.
I, personally, write down the name of each driver with a warning, and disable them after the wizard ends. Disabling/deleting a driver is easy, just right-click it in the MDT workbench and choose the appropriate option. Drivers must be disabled from their property sheet. Disabling a driver is a safe approach before it is determined that deletion is necessary. Only ever delete a driver from the MDT workbench. DO NOT go into the driver store via the file system and delete it that way.
Again, when disabling or deleting a driver, you must update the deployment share to take it out of Windows PE.
Finding, downloading, extracting, and importing drivers into MDT is a big part of MDT configuration, which takes a great deal of time. If it is done with forethought and planning, it can minimize the driver problems a deployment share might have, and need only be done once. I note the name and date of the driver files that I download and import into MDT. Then, I can periodically check for updates from the vendor’s web-sites. The older a model is with the manufacturer, the less-frequent they tend to update the drivers packs for that model. If the manufacturer does not make a driver pack available for your model, it is possible, though very tedious, to download each driver, and extract them individually. I try to avoid doing that.
Did you create the folder structure as in the first pic, or was it system generated, and you added the folders
under oobe ?
Again thanks a million for this post, and for taking the time.
I created the folder structure myself. Example: Windows 10 x64 \ %Make% \ %Model%
Windows 10 x64 \ Dell Inc. \ OptiPlex 9020
%Make% = the WMI hardware vendor name
%Model% = the WMI model name
wmic computersystem get model from the cmd.exe (elevated)
Great post, very insightful, thank you!
Jason, have you ever had a computer not load MDT? I have a few that will pxe to the server and load the files but won’t get to credentials screen. It’s a blank screen with the mdt background. Any thoughts?
Is the PE client pulling an IP address from DHCP? Press F8 on the screen, at any time, to open a cmd.exe session and run ipconfig /all If not, you may need to add some PE drivers to your MDT Windows boot drive ISO. Dell and Lenovo both make packages specifically for Windows PE.
Is DNS working properly? Can the PE client contact a DNS server that can resolve the hostname to IP address of your MDT server? Ping the host name of the MDT server from a cmd.exe session.
Does the MDT Deployment share have the correct permissions set to allow SMB access, both share perms and NTFS perms? If a firewall sits between the MDT server and the PE client, SMB ports will have to be opened up in the firewall for client access.
I have been accomplishing what you have here via the customsettings.ini file but that has become hard to managed. I will be experimenting with your method to simplify things. The one question I have is what is your experience with a model computer you have no driver folder for? For example, I have model computers old enough that the Windows 7 Pro media will load the computer with all drivers from Microsoft using my customsettings.ini method if no driver directory to fulfill the WMI call MDT runs under Default instead of version or model.
One additional question same drivers across multiple form factors (minitower and small form factor for example). What is your method for handling those situations? I ask because we use Lenovo and model name is unique for each form factor within the same model line unlike Dell. With Dell a OptiPlex 960 is the same no matter what form factor you have, Lenovo a M710 model number is different based on form factor so my MT model# is different from my SFF even though they use the same driver set.
I have some older hardware for which OEMs do not make Windows 10 drivers. The Dell OptiPlex 990 is a good example. Fortunately, Windows 10 is pretty good at picking up hardware with its own built-in drivers, much better than Windows 7. I noticed this with test deployments of Windows 10 to hardware before having set up a driver store. For the most part they all worked out. One of my last steps in the Windows deployment task sequence is to run the OEM’s update utility (Dell Command Update, Lenovo System Update) to get the latest apps/drivers for the installed hardware. Keep in mind, the ‘latest’ driver might not be the best fit for Windows. With that, I only focus on drivers for the chipset and the NIC. Those two will get a deployment by enough to complete and allow for the OEM’s software update app to run. Another option for Windows 10 is a live export of drivers from a running operating system with PowerShell. Convenient as this may be, PowerShell exports every driver in Windows most of which comes with Windows 10. It is not hard to wind-up with an exported driver store 20GB-25GB in size. I’d do that as a last resort after nothing else works. Drivers for a particular piece of hardware on the PC can be extracted by browsing the driver store folder and looking for additions which are recent. This gets you the driver. If there’s an app that comes along for using the hardware the drivers powers, you’ll have to add those through the task sequence. Lastly, you could play it completely safe and stick only to the operating systems your hardware’s OEM supports.
To be sure you have the bases covered with your drivers and the Lenovo platforms, their ThinkVantage Update Retriever can download/export drivers based on product family, 10AA for example as opposed to 10AAA0MRUS. This will grab any device driver and software package specified, as opposed to just the hardware it is run upon.
After that, you can use a selection profile which targets each family and assign that profile through CustomSettings.ini, SQL database, or task sequence variable
Great Post! Very helpful content and well explained
I have problem to extract drivers for Latitude 7414. I downloaded the .cab file from vendor site, but MDT just can’t extract drivers from it – it quickly exit saying ‘successfully…’ (i.e. no error) and there is no drivers added in MDT workbench.
I’ve tried with different versions (A02 to A06) of .cab and also tried to store the .cab in different locations, but no luck.
You need to extract the contents of the CAB file to a local directory before MDT will be able to import those drivers. I use the “extract” command from the cmd prompt.
Ex: extract D:\Source\Path\Drivers.cab -f:* D:\Destination\Path\Directory
Thanks for your articles. Good stuff! I am just getting started with MDT and hope to be using it this summer to deploy our W10 Pro machines for staff/students for next year. I have been using WDS for the past so many years (loosing track of time!). Anyways, I like this way of doing drivers that you describe. Although I have one issue. I have a whitebox that I get from Bytespeed LLC out of Minnesota. They do a great job for us and many public schools.
My issue is when I run this wmic command: wmic computersystem get model
I get nothing. Is this going to be a problem? Is there a way around this for me to get the procedure you describe to work?
For manufacturer I get: Bytespeed LLC (which is ok).
Any help you can provide would be great!
How are you currently managing the Bytespeed drivers for Windows 7? There are a couple of options. One is to set up Windows 10 on a Bytespeed PC and use PowerShell to do a live export of all the existing drivers in use. That’s a complete approach, but often winds-up in a large driver export (15-20GB in some cases). This is because the export command includes all of the drivers Windows provides from the install media and from Microsoft Update. Bytespeed lists the components they use in their products on their website. You could compile a list of the components in your area and get the drivers from the component’s manufacturers website. Depending of the diversity of models in your areas, this could be a big project. Bytespeed does make drivers available from their website (https://www.bytespeed.com/support/drivers-downloads/), but chances are these are not meant for MDT, but are just regular installers. Again, you can install these drivers on an example PC and pull them out with PowerShell, or add them to MDT as applications and use a WMI filter to assign them to the correct hardware during deployment. Other option, Windows 10 has successfully deployed to most Dell and Lenovo PCs (those with NVMe/M.2 SSDs) in my shop with no MDT-assigned drivers at all, using only what Windows provided during the install. This is something Windows 7 wouldn’t do. At the bottom of all of it, you need a NIC driver so PE/Windows can connect to the MDT deployment share, and you may need a chipset driver for USB support (if running MDT completely from USB, no server). This is why using good and up to date Windows PE drivers in your PE builds is essential. I’m seeing ASUS and Intel drivers among Bytespeed’s offerings. Just get the latest drivers from each vendor for Windows 10 and import them into MDT and you should be fine.
Best intro and description I’ve read on how to do this.
I assume the variable ‘DriverGroup001’ is well documented and used in the task sequence for injecting drivers.
My question is I see some examples set this variable in customsettings.ini eg:
[HP EliteBook 840 G5]
DriverGroup001=Windows 10 x64\%model%
But in what case would you define (I assume) each device model in customsettings.ini?
Is this so you don’t modify the task sequence in any way?
I assume very little and seek to find out what the story truly is. Defining the model/driver relationship in the CS.ini is one way to force specific drivers upon the matching hardware. This could be helpful if there were only a small amount of different hardware models in use. This same step can be done in the task sequence, under the “Inject Drivers” step, or if you use MDT with a SQL database.
I have had similar issues with off brand type devices. What I end up doing is taking an OEM unit and running BGINFO on it no special config just display everything available 50% of the model field is populated. When bginfo fails me my second option open the BIOS screen see what is listed in the Model field. I have yet to find a maker that did not list the model info in BIOS even when WMIC does not display it.
Entering wmic computersystem get model from an administrative command prompt will divulge the WMI name for the computer’s model.
That is awesome post Jason, thanks for a so much useful post
Hi, great explanation but could you answer the following.
I have created within the Out-of-box-drivers the following tree structure (to keep it neat).
Out-of-box drivers / Dell Inc / Optiplex / 790 / Win10 / x64
Regarding the DriverGoup001 – I have the following command line in there..
Win10 x64 v1803/%Make%/%Model%
Would this work? or do i also need to instruct it to find the drivers within the specific model directory /Win10/x64
In terms of Dell, what do we do with the WinPE 10 CAB? Does that go into Out-of-Box Drivers as well? Or somewhere else?
The WinPE CAB can be extracted into Out-of-box drivers, and placed into a selection profile which would be used solely by Windows PE. That’s what I do.
You would need to provide the full path of the driver folder(s) to MDT so it can find the drivers. MDT/WinPE will not browse through sub-folders.
Very helpful. Thanks. Can you describe the way that you set up WinPE drivers in OOBD and in task sequences?
I use a folder structure folder under Out-of-box drivers called “WinPE”, and “Windows 10 x64”. Under each of those I have sub-folders for each OEM manufacturer I support (Dell & Lenovo). “Windows 10 x64\Dell Inc.” and “Windows 10 x64\Lenovo” each have a sub-folder for each model I support from that manufacturer, ex: “Windows 10 x64\Dell Inc.\OptiPlex 7050”. It follows the WMI naming convention of “Windows 10 x64\%make%\%model”. “WinPE\Lenovo” and “WinPE\Dell Inc.” just have the 64-bit PE drivers, downloaded from each manufacturer’s website. I’m not in the 32-bit OS business anymore. Then, I create a selection profile for Windows PE, encompassing the drivers from each manufacturer and assign it to the Driver profile for Windows PE.
Nice, thanks. And where should I place the selection profile within the task sequence?
What a thorough write-up! Thanks!
I’m set up about identical to yours, but one thing always confused me. During import of drivers, when I specify the directory where to import drivers from, there is a check box option of “Import Drivers even if there are any duplicates…”
Do you check this box, or leave it unchecked? If a duplicate is found, how do you handle this? The perfect case for this scenario is if you were updating the entire driver package from the manufacturer.
I only opt to import a duplicate if I’m looking to overwrite an older driver with a newer version and to make sure that newer version persists. The easiest way to do wholesale driver updates is to remove all of the old and import all of the new.
You don’t have to place it anywhere. It is available as an option from the “Inject Drivers” step in the preinstall phase.
When the driver cab files are extracted they are in sub folders by Class. Are you saying that because each class is in a subfolder of its own MDT will not find the drivers if the path is only to the model? I have always recreated the cab file folder structure in MDT and imported the drivers in their class folder. It sounds like in order for me to use the driver injection by model I will have to move all of my current drivers out of their respective class folders and dump them into a single model folder.
Out -of-Box Drivers
Windows 10 64-bit
So if my variable value is Windows 10 64-bit\%Make%\%Model% MDT will not see the drivers? Also, regarding the Task Sequence Variable, does it have to be named DriverGroup001 or can I name it what I want such as DriverSet?
I have never tried the approach you have described, but I think it would work but not the way it was intended. I believe since the path given would not allow MDT to find any drivers, MDT would look in sub-folders. That’s an estimate based on years of watching what MDT does, and after imaging thousands of computers with MDT. While highly organized, it would seem as if your design might involve more work than is necessary, especially with Windows 10. I’m no fan of Windows 10, but I’ll fully admit it works great with many types of hardware. This behavior is much different than Windows 7’s interaction with MDT and hardware. I would ask how many different models of PC do you need to image? If that is a small number, you could create profiles for each model and assign them through a WMI query. That approach would take the decision further out from MDTs hands and closer into yours. I wanted an MDT setup where one task sequence can be used to image all of the PCs I support, and a SQL database does the driving. Very little deciding, more doing. An environment with many different makes and models would work better with an MDT setup that was as general as could be, hence allowing MDT to decide which drivers to install instead of me telling it which drivers to install. A firmer option which would not drastically increase your administrative overhead, would be a separate task sequence for each make. One t/s for Dells, another for Lenovos and such. There, the driver injection step can be made to either decide which drivers to use or be told to use a profile which encompasses all of that make’s models. Pretty safe. You could actually build that type of difference into a single t/s.
I work for state government and we use many different model computers. The state employees have a total of 5 models. But we contract out a lot of construction contract work. The contractor is responsible for providing the laptops for their consultants. We then image them and join them to our network. I don’t know what make or model machine I will get until it arrives. I then create the TS for that make/model if I don’t already have one. For this reason I am trying to implement the single TS as you described that will inject drivers based on make/model leaving me to only need to add the make/model drivers and not have to create and additional TS. We have 3 images (basic, construction, design) which each have specific software per user function. So I would actually have 3 TS’s. The only reason I recreated the cab file folder structure in MDT was because I thought it would make it easier to locate problematic drivers by only having to search the specific class folder rather than a single folder full of all drivers. If you think that using a single make/model folder is better then I have no problem changing my current layout and moving the drivers into the single folder as this would not result in MDT having to re-inject the drivers into the boot wim which can take a while. My goal is to have just the 3 TS’s (basic, construction, design) and let MDT handle the rest. My current situation results in 3 TS’s per make/model because each machine can be built with either one of the 3 images determined by the user’s function.
One other question. I saw that you responded to a Dell WinPE question regarding where to place it in the TS.
Jeff Kitterman says:
October 9, 2018 at 5:14 pm
Nice, thanks. And where should I place the selection profile within the task sequence?
October 15, 2018 at 12:55 pm
You don’t have to place it anywhere. It is available as an option from the “Inject Drivers” step in the preinstall phase.
But initially you stated that the “Inject Drivers” step needed to have “Nothing” selected.
Hey Jason, I went ahead and cleaned up my Out-of-Box-Drivers by creating sub-folders by model and then moved all drivers for that model into the respective folder. Using DriverGroup001 works great. After seeing how easily this uses the “Model” variable to select and inject drivers instead of creating Selection profiles I thought it would be great to also use variables to copy drivers to the target machine. What we do is extract the driver cab file into a folder on the finished machine ex: c:\temp\Drivers\HP ZBook 14u G5. I was hoping to make this as simple as injecting the drivers with DriverGroup001. What I did was create a batch script called “CopyDrivers.bat” in the scripts folder of the deployment share.
for /f “tokens=*” %%f in (‘wmic csproduct get name /value ^| find “=”‘) do set “%%f”
cmd.exe /c xcopy /e %SCRIPTROOT%\CustomScripts\CopyDrivers\”%name%” C:\Temp\Drivers\”%name%”\
This assigned the exact correct model name to the variable %name% and then copies that folder to the target machine. Simple right? Well I tested this in windows and it worked. Had to change the executable a little in the batch file:
cmd.exe /c xcopy /e D:\DeploymentShare\Scripts\CustomScripts\CopyDrivers\”%name%” C:\Temp\Drivers\”%name%”\
However it doesn’t work as a run command pointing to CopyDrivers.bat in the TS. The command line in the TS is: cmd.exe /c %SCRIPTROOT%\CustomScripts\CopyDrivers\CopyDrivers.bat. I don’t get an error, it just doesn’t copy anything. Have you ever tried this or can you shed some light on what I may be doing wrong?
Does the folder structure after the %Make%\%Model% need to contain all the drivers?
Or will it work if I have different sub-folders such as:
while the task sequence variable is still setting it to %Make%\%Model% only ?
I guess is it doing recursive check or just getting drivers from the full path only
Regarding WinPE drivers. Do I put all the WinPE drivers for different brands (Dell, Lenovo, etc) in the WinPEx64 folder together? Will it cause any problems if I create subfolders for Dell, Lenovo, etc?
What a great write-up! Thanks!