February 15, 2012 1 Comment
ConfigMgr OSD does a great job of injecting drivers ‘on the fly’ into your OS Deployment process. For example, you can create task sequence steps with conditional statements to apply drivers for a specific model. That’s great for your standard build, but how do you handle those one-offs, those non-standard builds? Here’s a process that you can you for those non-standard builds, or for that hardware that you’re testing, but haven’t quite committed to being a standard yet. All we need is a vbScript, raw drivers, and an additional step in your task sequence (haven’t tested with MDT, but should work there as well). The following process ONLY works on Windows 7 and Windows Server 2008 R2. If there is enough demand, I’ll create a similar script for previous Operating System versions.
Step 1 – Create a USB folder with raw drivers for the desired hardware.
- Create a folder in the root of a USB drive named “ExportedDrivers”
- Copy desired drivers to this folder. You can create subfolders to help with organization if you’d like. Please note that *everything* in the ExportedDrivers AND ALL SUBFOLDERS will be processed, so try to keep the folder structure organized, and to ONLY include the desired raw drivers.
- Your folder should look similar to this:
- We have a few extra folders here to keep things organized, but you can just put them in the root of “ExportedDrivers” if desired.
Step 2 – Create a package with ImportCustomDrivers.vbs
- Create a new Package (or just add this file to an existing package)
- Download ImportCustomDrivers.txt, and rename to ImportCustomDrivers.vbs.
- Send to DPs.
Step 3 – Add new step to OSD Task Sequence
- This step should run in WinPE, just before all other “Apply Driver Package”or “Auto Apply Drivers” step.
- Your Task Sequence step would look similar to this:
- Depending on your environment, you may want to enable the ‘continue on error’ checkbox on the Options tab. If the script attempts to import a driver that does not apply to the current operating system, it will return a failure exit code.
- If you have ADDITIONAL “Apply Driver Package”, or “Auto Apply Drivers”steps, and you want to skip these steps if we import drivers from the USB, enter a conditional where Task sequence variable “OSDCustomDriversApplied” not equals “True” (this variable is set in the .vbs when it runs).
Now that you have your task sequence configured, insert the USB drive into the test system and launch a test build. At the “Add Custom Drivers…” step. you will see a command prompt that shows the status of the drivers that are being injected.
- In WinPE, two log files will be created in X:\Windows\Temp\SMSTSLog:
- The log files will also be copied to the ConfigMgr log file directory to allow for post-image troubleshooting.
Again, this process is meant for those one-off scenarios. If you plan to fully support a platform, be sure to handle driver installation using ConfigMgr driver management.
'Use this script to import custom drivers for Server 2008 R2, Win7, and newer - full blog post on http://gregramsey.wordpress.com/ 'Created by: Greg Ramsey Log "ImportCustomDrivers - Start" strComputer = "." strDriverFolder = "ExportedDrivers" intReturnCode = 0 intFinalReturnCode = 0 Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") Set objFSO = CreateObject("Scripting.FileSystemObject") Set oShell = WScript.CreateObject("WScript.Shell") Set colDisks = objWMIService.ExecQuery("Select * from Win32_LogicalDisk") 'enum each drive letter, and see if strDriverFolder exists in the root. For Each objDisk In colDisks 'Check each drive letter to see if there is a If objFSO.FolderExists(objDisk.DeviceID & "\" & strDriverFolder) Then 'this will only run in a TS environment, so fail if we can't connect to sms.tsenvironment Log vbTab & "Connecting to SMS.TSEnvironment" Set oTSEnv = CreateObject("Microsoft.SMS.TSEnvironment") If err.number <> 0 Then Log vbTAB & "Unable to connect to Microsoft.SMS.TSEnvironment" Log "ImportCustomDrivers - End" WScript.quit(err.number) Else 'prepare the command line, and launch the DISM command Log vbTAB & objDisk.DeviceID & "\" & strDriverFolder & " Exists, Importing drivers.." strCommand = CStr("Dism /image:" & oTSEnv("OSDTARGETSYSTEMDRIVE") & "\ /logpath:%windir%\temp\smstslog\DismCustomImport.log /Add-Driver /driver:" & objDisk.DeviceID & "\" & strDriverFolder & " /recurse") Log vbTAB & "Preparing to run the following command: " & strCommand intReturnCode = oShell.Run(strCommand, 1, True) Log vbTAB & "Return Code = " & intReturnCode Log vbTAB & "Setting TS Variable OSDCustomDriversApplied = True" oTSEnv("OSDCustomDriversApplied") = "True" End If Else 'no custom drivers exist End If 'slightly cheesy - if more than one drive have the special folder, the DISM command will run more than once ' so we're using this to capture if ANY of the exit code are <> 0, so we can capture that if there are any failures ' you'll have to review the %windir%\temp\smstslog\DISMCustomImport.log for details If intReturnCode <> 0 Then intFinalReturnCode = intReturnCode Next Log "Final Return code = " & intFinalReturnCode Log "ImportCustomDrivers - End" WScript.Quit(intFinalReturnCode) 'a simple logging subroutine Sub Log(message) WScript.Echo message Const ForAppending = 8 Set WshShell = CreateObject("WScript.Shell") strSystemRoot = WshShell.ExpandEnvironmentStrings("%SystemRoot%") Set objFSO = CreateObject("Scripting.FileSystemObject") If Not objFSO.FolderExists(strSystemRoot & "\Temp\SMSTSLog\") Then objFSO.CreateFolder(strSystemRoot & "\Temp\SMSTSLog\") End If 'Create Output Log stroutputlog = strSystemRoot & "\temp\SMSTSLog\OSD_CustomDrivers.log" Set objTextFile = objFSO.OpenTextFile(strOutputLog, ForAppending, True) On Error Resume Next txtstatus.value = Trim(Replace((message & " " & Now()), vbTab, "")) On Error Goto 0 message = Now() & " " & message ' ' Log the given message ' objTextFile.writeline(message) objTextFile.Close End Sub