Hardware specific application targeting with MDT 2010

This content is 14 years old. I don't routinely update old blog posts as they are only intended to represent a view at a particular point in time. Please be warned that the information here may be out of date.

Guest Post
[Editor’s note: this post was originally published on Garry Martin’s blog on 28 October 2009. As Garry’s closing down his own site but the content is still valid, he asked me if I’d like to post it here and I gratefully accepted!]

I’m running a Proof of Concept (PoC) at work at the moment which is making use of Microsoft Deployment Toolkit (MDT) 2010. Whilst most of the drivers we need can be managed by using the Out-of-Box Drivers Import function, some are delivered by the OEM as .EXE or .MSI packages. Whilst we could use multiple Task Sequences to manage these, or even select the applications individually at build time, our preference was to use some sort of hardware specific targeting.


First of all, we needed to uniquely identify the hardware, and for this purpose we used the Plug and Play (PnP) Device ID, or hardware ID as it is sometimes called.

To determine the hardware IDs for a device by using Device Manager:

  1. Install the device on a test computer
  2. Open DeviceManager
  3. Find your device in the list
  4. Right-click the entry for your device, and then click Properties
  5. In the Device Properties dialog box, click the Details tab
  6. In the Property list, click Hardware Ids
  7. Under Value, make a note of the characters displayed. They are arranged with the most specific at the top to the most general at the bottom. You can select one or more items in the list, and then press CTRL+C to copy them to the clipboard.

In our case, the Sierra Wireless MC8755 Device gave us USB\VID_1199&PID_6802&REV_0001 as the most specific value and USB\VID_1199&PID_6802 as the least specific, so we made a note of these before continuing.

Next, we downloaded the Sierra Wireless MC87xx 3G Watcher .MSI package from our notebook OEM support site. Sierra Wireless have instructions for performing a silent install of the 3G Watcher package, so we used those to understand the installation command we would need to use.

So, we had a unique ID for targeting, the installation package, and the installation command line we would need to use. Now we needed to configure MDT to deploy it. First, we create a New Application.

  1. In the MDT 2010 Deployment Workbench console tree, right-click Applications, and click New Application
  2. On the Application Type page, click Next to install an application and copy its source files to the deployment share
  3. On the Details page, type the application’s name in the Application Name box, and click Next
  4. On the Source page, type the path or browse to the folder containing the application’s source files, and click Next
  5. On the Destination page, click Next to use the default name for the application in the deployment share
  6. On the Command Details page, type the command you want to use to install the application, and click Next. We used the following
    msiexec.exe /i 3GWatcher.msi /qn
  7. On the Summary page, review the application’s details, and click Next
  8. On the Confirmation page, click Finish to close the New Application Wizard.

Next we modify the Task Sequence and create our query.

  1. In the MDT 2010 Deployment Workbench console tree, click Task Sequences
  2. In the details pane, right-click the name of the Task Sequence you want to add the Application to, and then click Properties
  3. In the Task Sequence Properties dialog box, click the Task Sequence tab
  4. Expand State Restore and click on Install Applications
  5. Click the Add button, and select General, then Install Application
  6. On the Properties tab for Install Application, type the application’s name in the Name box, and click the Options tab
  7. On the Options tab, click the Add button and select If statement
  8. On the Source page, type the path or browse to the folder containing the application’s source files, and click Next
  9. In the If Statement Properties dialog box, ensure All Conditions is selected and click OK
  10. On the Options tab, click the Add button and select Query WMI

This is where we’ll now use a WMI query that will provide our Hardware Specific Application Targeting. You’ll need to modify this for your particular hardware, but we previously discovered that our least specific Device ID value was USB\VID_1199&PID_6802 so we will use this to help form our query.

  1. In the Task Sequence WMI Condition dialog box, ensure the WMI namespace is root\cimv2 and type the following in the WQI Query text box, clicking OK when finished:
    SELECT * FROM Win32_PNPEntity WHERE DeviceID LIKE '%VID_1199&PID_6802%'
  2. Click OK to exit the Task Sequences dialog box

And that’s it. When you deploy a computer using the modified Task Sequence, the WMI query will run and, if matched, install the application. If a match can’t be found, the application won’t be installed. Hardware Specific Application Targeting in a nutshell.

Native VHD boot Windows 7 or Server 2008 R2 from an external USB drive

This content is 15 years old. I don't routinely update old blog posts as they are only intended to represent a view at a particular point in time. Please be warned that the information here may be out of date.

Guest Post
Are you excited about Native VHD Boot for Windows 7 (Enterprise or Ultimate) and Windows Server 2008 R2 but wish you could use an external USB drive to store the .VHD files? Well unfortunately it isn’t officially supported but, if that doesn’t worry you too much, you might find this post interesting…


In order to get Native VHD Boot working from an external USB Disk, there are a few things we need to understand about device drivers and their load orders.

Setup and the PnP manager configure devices starting with the system root device, followed by the child devices of the root device, the children of those devices, and so on. To influence the driver load order outside of this sequence, we need to change the .INF files for the USB related drivers, specifying relevant values in the service-install-section, specifically the StartType and the LoadOrderGroup entries.

A PnP driver should have a start type of SERVICE_DEMAND_START (0x3), specifying that the PnP manager can load the driver whenever it finds a device that the driver services. USB drivers normally behave in this manner and have this start type.

However, if a driver is required to boot the machine (such as when, oh I don’t know, maybe attempting something like native VHD boot from an external USB drive), the drivers for the device should have a start type of SERVICE_BOOT_START (0x0).

On system boot, the operating system loader loads drivers of type SERVICE_BOOT_START before it transfers control to the kernel. These drivers are in memory when the kernel gets control. Boot-start drivers can use the .INF LoadOrderGroup entries to order their loading. You can see the List order at HKLM/SYSTEM/CurrentControlSet/Control/ServiceGroupOrder.

For Native VHD Boot from an external USB drive to work, we need to modify the behaviour of six device drivers:

  • usbccgp – Microsoft USB Generic Parent Driver
  • usbehci – Microsoft USB 2.0 Enhanced Host Controller Miniport Driver
  • usbohci – Microsoft USB Open Host Controller Miniport Driver
  • usbuhci – Microsoft Universal Host Controller Miniport Driver
  • usbhub – Microsoft USB Standard Hub Driver
  • usbstor – USB Mass Storage Driver

The USB drivers have a LoadOrderGroup entry of Base, which is considerably down the list, and critically much later than we need to use them as a boot device. We therefore need to modify the LoadOrderGroup to something more appropriate that will be processed earlier in the boot cycle. There is some debate about the best entries to use for this purpose, and whilst it seems the below is technically most appropriate, I began this journey with all entries set to use Boot Bus Extender and have continued to use that without issue. However, you may want to try the settings below as an alternative:

  • usbccgp – Boot Bus Extender
  • usbehci – Boot Bus Extender
  • usbohci – Boot Bus Extender
  • usbuhci – Boot Bus Extender
  • usbhub – System Bus Extender
  • usbstor – SCSI Miniport

So, to enable Native VHD Boot from an external USB drive, we need to modify the StartType and LoadOrderGroup of each of those drivers, and critically, ensure that they don’t get reset to their defaults.


You’ll need a computer running Windows 7 or Windows Server 2008 R2 and a suitable external USB drive to store your .VHD files and to create the necessary bootloader. You’ll also need the following tools:


Disclaimer: This is close to a step-by-step guide, but it assumes a certain level of technical knowledge and understanding. Hopefully I’ve made it as easy to follow and as painless as possible but tread carefully. To quote Scott Hanselman:

“This is some advanced stuff and you may lose a finger. No warranty express or implied.”

To begin with, we need to create our .VHD file. Mike Kolitz has created a fantastic script called WIM2VHD that takes much of the hard work out of this task for us. The example below uses a Windows Server 2008 R2 WIM file as source, and creates a 49GB Enterprise edition dynamically expanding .VHD file from it.

From an elevated command prompt, run the following command:


Now that we have created the .VHD file, we need to make some changes to the operating system contained within it. From the same elevated command prompt used for the previous command, we’ll use diskpart.exe to mount the .VHD. Note the use of LIST VOLUME so that we can see the correct volume number, select it, and assign a drive letter to it – you’ll need to change the number in SELECT VOLUME to match your environment:


At this stage, I use the offline servicing tool, dism.exe, to change the default language, keyboard layout and timezone to something more appropriate for the United Kingdom. You can obviously make other changes too if necessary:

DISM /IMAGE:R: /Set-SysLocale:en-GB
DISM /IMAGE:R: /Set-UserLocale:en-GB
DISM /IMAGE:R: /Set-InputLocale:409:00000409
DISM /IMAGE:R: /Set-TimeZone:”GMT Standard Time”

Next, we need to make changes to the registry for each of the six USB device drivers. We’ll use the built in reg.exe command to do this. By default, when an operating system is launched from a dynamically expanding .VHD file using native VHD boot, it expands to its maximum size, reverting to its dynamic size when it is shutdown. I also modify the VirtualDiskExpandOnMount registry value to prevent this:

REG ADD HKLM\TEMP\ControlSet001\services\usbccgp /v Group /t REG_SZ /d “Boot Bus Extender” /f
REG ADD HKLM\TEMP\ControlSet001\services\usbccgp /v Start /t REG_DWORD /d 0 /f
REG ADD HKLM\TEMP\ControlSet001\services\usbehci /v Group /t REG_SZ /d “Boot Bus Extender” /f
REG ADD HKLM\TEMP\ControlSet001\services\usbehci /v Start /t REG_DWORD /d 0 /f
REG ADD HKLM\TEMP\ControlSet001\services\usbhub /v Group /t REG_SZ /d “Boot Bus Extender” /f
REG ADD HKLM\TEMP\ControlSet001\services\usbhub /v Start /t REG_DWORD /d 0 /f
REG ADD HKLM\TEMP\ControlSet001\services\usbohci /v Group /t REG_SZ /d “Boot Bus Extender” /f
REG ADD HKLM\TEMP\ControlSet001\services\usbohci /v Start /t REG_DWORD /d 0 /f
REG ADD HKLM\TEMP\ControlSet001\services\USBSTOR /v Group /t REG_SZ /d “Boot Bus Extender” /f
REG ADD HKLM\TEMP\ControlSet001\services\USBSTOR /v Start /t REG_DWORD /d 0 /f
REG ADD HKLM\TEMP\ControlSet001\services\usbuhci /v Group /t REG_SZ /d “Boot Bus Extender” /f
REG ADD HKLM\TEMP\ControlSet001\services\usbuhci /v Start /t REG_DWORD /d 0 /f
REG ADD HKLM\TEMP\ControlSet001\services\FsDepends\Parameters /v VirtualDiskExpandOnMount /t REG_DWORD /d 4 /f

The next step is to modify the .INF files so that the operating system does not reset these values to their defaults at any point. As some of the files require SYSTEM permissions to modify them, we use the excellent SysInternals psexec.exe command to launch a command prompt in the SYSTEM security context.

PSEXEC –i –d –s C:\Windows\System32\cmd.exe

From the resultant command window, we use Horst Schaeffer’s INI File Tool to modify any .INF files that might reset the device driver values to their defaults:

INIFILE R:\Windows\inf\usb.inf [StandardHub.AddService] StartType = 0 ; SERVICE_BOOT_START
INIFILE R:\Windows\inf\usb.inf [StandardHub.AddService] LoadOrderGroup = Boot Bus Extender
INIFILE R:\Windows\inf\usb.inf [CommonClassParent.AddService] StartType = 0 ; SERVICE_BOOT_START
INIFILE R:\Windows\inf\usb.inf [CommonClassParent.AddService] LoadOrderGroup = Boot Bus Extender
INIFILE R:\Windows\inf\usbport.inf [EHCI.AddService] StartType = 0 ; SERVICE_BOOT_START
INIFILE R:\Windows\inf\usbport.inf [EHCI.AddService] LoadOrderGroup = Boot Bus Extender
INIFILE R:\Windows\inf\usbport.inf [OHCI.AddService] StartType = 0 ; SERVICE_BOOT_START
INIFILE R:\Windows\inf\usbport.inf [OHCI.AddService] LoadOrderGroup = Boot Bus Extender
INIFILE R:\Windows\inf\usbport.inf [UHCI.AddService] StartType = 0 ; SERVICE_BOOT_START
INIFILE R:\Windows\inf\usbport.inf [UHCI.AddService] LoadOrderGroup = Boot Bus Extender
INIFILE R:\Windows\inf\usbport.inf [ROOTHUB.AddService] StartType = 0 ; SERVICE_BOOT_START
INIFILE R:\Windows\inf\usbport.inf [ROOTHUB.AddService] LoadOrderGroup = Boot Bus Extender
INIFILE R:\Windows\inf\usbstor.inf [USBSTOR.AddService] StartType = 0 ; SERVICE_BOOT_START
INIFILE R:\Windows\inf\usbstor.inf [USBSTOR.AddService] LoadOrderGroup = Boot Bus Extender
INIFILE R:\Windows\inf\brmfcsto.inf [USBSTOR.AddService] StartType = 0 ; SERVICE_BOOT_START
INIFILE R:\Windows\inf\brmfcsto.inf [USBSTOR.AddService] LoadOrderGroup = Boot Bus Extender

Now we delete the precompiled INF files, and copy our modified INF files to appropriate locations. Note that the file locations differ for x64 and x86 builds.

For x64 builds only:
DEL /Q R:\Windows\inf\usb.pnf
DEL /Q R:\Windows\System32\DriverStore\FileRepository\usb.inf_amd64_neutral_e2b28ecac19a29af\usb.pnf
DEL /Q R:\Windows\winsxs\amd64_usb.inf_31bf3856ad364e35_6.1.7600.16385_none_26ed589d28235a16\usb.pnf
DEL /Q R:\Windows\inf\usbport.pnf
DEL /Q R:\Windows\System32\DriverStore\FileRepository\usbport.inf_amd64_neutral_5a41ca742f7973cc\usbport.pnf
DEL /Q R:\Windows\winsxs\amd64_usbport.inf_31bf3856ad364e35_6.1.7600.16385_none_19b7511a1d3ea7fd\usbport.pnf
DEL /Q R:\Windows\inf\usbstor.pnf
DEL /Q R:\Windows\System32\DriverStore\FileRepository\usbstor.inf_amd64_neutral_c301b770e0bfb179\usbstor.pnf
DEL /Q R:\Windows\winsxs\amd64_usbstor.inf_31bf3856ad364e35_6.1.7600.16385_none_a47b405db18421ea\usbstor.pnf
DEL /Q R:\Windows\inf\brmfcsto.pnf
DEL /Q R:\Windows\System32\DriverStore\FileRepository\brmfcsto.inf_amd64_neutral_2d7208355536945e\brmfcsto.pnf
DEL /Q R:\Windows\winsxs\amd64_brmfcsto.inf_31bf3856ad364e35_6.1.7600.16385_none_7fe64f7a6167bcf6\brmfcsto.pnf
COPY /Y R:\Windows\inf\usb.inf R:\Windows\System32\DriverStore\FileRepository\usb.inf_amd64_neutral_e2b28ecac19a29af
COPY /Y R:\Windows\inf\usb.inf R:\Windows\winsxs\amd64_usb.inf_31bf3856ad364e35_6.1.7600.16385_none_26ed589d28235a16
COPY /Y R:\Windows\inf\usbport.inf R:\Windows\System32\DriverStore\FileRepository\usbport.inf_amd64_neutral_5a41ca742f7973cc
COPY /Y R:\Windows\inf\usbport.inf R:\Windows\winsxs\amd64_usbport.inf_31bf3856ad364e35_6.1.7600.16385_none_19b7511a1d3ea7fd
COPY /Y R:\Windows\inf\usbstor.inf R:\Windows\System32\DriverStore\FileRepository\usbstor.inf_amd64_neutral_c301b770e0bfb179
COPY /Y R:\Windows\inf\usbstor.inf R:\Windows\winsxs\amd64_usbstor.inf_31bf3856ad364e35_6.1.7600.16385_none_a47b405db18421ea
COPY /Y R:\Windows\inf\brmfcsto.inf R:\Windows\System32\DriverStore\FileRepository\brmfcsto.inf_amd64_neutral_2d7208355536945e
COPY /Y R:\Windows\inf\brmfcsto.inf R:\Windows\winsxs\amd64_brmfcsto.inf_31bf3856ad364e35_6.1.7600.16385_none_7fe64f7a6167bcf6

For x86 builds only:
DEL /Q R:\Windows\inf\usb.pnf
DEL /Q R:\Windows\System32\DriverStore\FileRepository\usb.inf_x86_neutral_e24d8d3fec6e4567\usb.pnf
DEL /Q R:\Windows\winsxs\x86_usb.inf_31bf3856ad364e35_6.1.7600.16385_none_cacebd196fc5e8e0\usb.pnf
DEL /Q R:\Windows\inf\usbport.pnf
DEL /Q R:\Windows\System32\DriverStore\FileRepository\usbport.inf_x86_neutral_ba59fa32fc6a596d\usbport.pnf
DEL /Q R:\Windows\winsxs\x86_usbport.inf_31bf3856ad364e35_6.1.7600.16385_none_bd98b59664e136c7\usbport.pnf
DEL /Q R:\Windows\inf\usbstor.pnf
DEL /Q R:\Windows\System32\DriverStore\FileRepository\usbstor.inf_x86_neutral_83027f5d5b2468d3\usbstor.pnf
DEL /Q R:\Windows\winsxs\x86_usbstor.inf_31bf3856ad364e35_6.1.7600.16385_none_485ca4d9f926b0b4\usbstor.pnf
DEL /Q R:\Windows\inf\brmfcsto.pnf
DEL /Q R:\Windows\System32\DriverStore\FileRepository\brmfcsto.inf_x86_neutral_39ae61431a44cded\brmfcsto.pnf
DEL /Q R:\Windows\winsxs\x86_brmfcsto.inf_31bf3856ad364e35_6.1.7600.16385_none_23c7b3f6a90a4bc0\brmfcsto.pnf
COPY /Y R:\Windows\inf\usb.inf R:\Windows\System32\DriverStore\FileRepository\usb.inf_x86_neutral_e24d8d3fec6e4567
COPY /Y R:\Windows\inf\usb.inf R:\Windows\winsxs\x86_usb.inf_31bf3856ad364e35_6.1.7600.16385_none_cacebd196fc5e8e0
COPY /Y R:\Windows\inf\usbport.inf R:\Windows\System32\DriverStore\FileRepository\usbport.inf_x86_neutral_ba59fa32fc6a596d
COPY /Y R:\Windows\inf\usbport.inf R:\Windows\winsxs\x86_usbport.inf_31bf3856ad364e35_6.1.7600.16385_none_bd98b59664e136c7
COPY /Y R:\Windows\inf\usbstor.inf R:\Windows\System32\DriverStore\FileRepository\usbstor.inf_x86_neutral_83027f5d5b2468d3
COPY /Y R:\Windows\inf\usbstor.inf R:\Windows\winsxs\x86_usbstor.inf_31bf3856ad364e35_6.1.7600.16385_none_485ca4d9f926b0b4
COPY /Y R:\Windows\inf\brmfcsto.inf R:\Windows\System32\DriverStore\FileRepository\brmfcsto.inf_x86_neutral_39ae61431a44cded
COPY /Y R:\Windows\inf\brmfcsto.inf R:\Windows\winsxs\x86_brmfcsto.inf_31bf3856ad364e35_6.1.7600.16385_none_23c7b3f6a90a4bc0

The next part is optional. It creates a differencing .VHD from the original file. The allows you to leave the base .VHD file intact and make all subsequent changes to the differencing .VHD instead. It’s a great way of building a base operating system image and then branching it for development work or testing. Once again, make sure you note the correct volume number when doing this. So, from the original elevated command prompt:


Now all that is left to do is to create a bootloader on the external USB disk and create an entry for our Native VHD Boot. When you BCDEDIT /COPY {default} below, note the resultant GUID that you are given and use that instead of the {5aaa2c7a-a627-11de-83c7-001372bf1815} listed in the example. So, continuing from the same command window:

BCDEDIT /STORE M:\BOOT\BCD /COPY {default} /d “Windows Server 2008 R2 Enterprise”
BCDEDIT /STORE M:\BOOT\BCD /SET {5aaa2c7a-a627-11de-83c7-001372bf1815} DEVICE VHD=[LOCATE]\BootVHDs\W2K8R2ENT_DIFF.vhd
BCDEDIT /STORE M:\BOOT\BCD /SET {5aaa2c7a-a627-11de-83c7-001372bf1815} OSDEVICE VHD=[LOCATE]\BootVHDs\W2K8R2ENT_DIFF.vhd
BCDEDIT /STORE M:\BOOT\BCD /SET {5aaa2c7a-a627-11de-83c7-001372bf1815} DETECTHAL ON

And that’s it. Reboot your computer, select your external USB disk as your boot device, and you should see the entry you created above. Windows will start, perform the final stages of setup (rebooting a couple of times in the process) and you will be done.

I have personally used this method to store a large number of .VHD files (fixed, dynamic and differencing) and to use them to boot Windows 7 Enterprise and Ultimate in both x64 and x86 platform versions, and the various Windows Server 2008 R2 editions, and found it to be an extremely flexible option.

I’ve even had some success swapping the external USB disk between machines. It doesn’t always work (and to be honest, I haven’t had the time to look any deeper into why) but I’ve used the same native VHD boot instance on a Fujitsu Siemens Celsius H240, Lifebook T4210 and Lifebook S7220, swapping it backwards and forwards between machines and letting Windows manage the driver changes each time without issue.

I’ve also had success with native VHD boot using .VHD files created from Windows Backup and have recently started looking at using the files created from the SysInternals Disk2vhd tool too. Pop back sometime soon and you may even find another guest post documenting those particular adventures…

[MW: Sounds great Garry! Looking forward to it]

Native boot from VHD on a Windows XP computer

This content is 15 years old. I don't routinely update old blog posts as they are only intended to represent a view at a particular point in time. Please be warned that the information here may be out of date.

Guest PostLike almost every other corporate in the world, where Mark and I work there is a standard build deployed to everyone. The default in our particular organisation is a 32-bit Windows XP OS regardless of the capabilities of the laptop or desktop it is deployed to. Over the years, this has caused a number of problems that have required an increasing number of “exemptions” from standard policy to allow people to run a different Windows version or platform.

Whilst this hasn’t been too much of a problem for the majority of the Architects that Mark and I work with – after all, we’re fairly self-sufficient when it comes to supporting our environments and are infinitely capable of collectively dreaming up ever more creative workarounds for the things that don’t work – it isn’t a solution that’s manageable at scale.

Then, along came Windows 7 and Windows Server 2008 R2 and with them came the introduction of a great new feature – Native Boot from VHD. With a little configuration, this has enabled us to leave the existing Windows XP corporate build in place, and to deploy a 32-bit or 64-bit Windows 7 (Enterprise or Ultimate) or 64-bit Windows Server 2008 R2 build side-by-side, crucially without having to make any changes to the Windows XP build or the existing disk partitioning scheme.

To achieve this, we created a new Windows 7 or Windows Server 2008 R2 bootloader, and “chained” the original Windows XP bootloader from it. At boot, this allows us to select a Native Boot from VHD into, for example, a 64-bit Windows Server 2008 R2 Enterprise build, or to select the chained bootloader which allows us to boot into the corporate Windows XP build.

Of course, you’ll need to create your VHD-contained Windows 7 or Windows Server 2008 R2 OS build and put it to your local disk, and this post doesn’t go into that detail, but once you have done that, the steps below will allow you to create a new bootloader and chain your existing Windows XP corporate build from it.

To begin, boot your computer using your Windows 7 or Windows Server 2008 R2 installation media.

When you reach the Install Windows screen, select your preferences in the Language to installTime and currency format, and Keyboard or input method boxes, and then click Next.

Do not click Install now. Instead, click Repair your computer.

The search for supported operating systems will fail, and the System Recovery Options dialog box appears with the Restore your computer using a system image that you created earlier option selected. Click Next.

The Re-image your computer tool will fail to find a system image and will display a dialog informing you of this. Click Cancel on the dialog, and then Cancel again on the main tool window.

The System Recovery Options menu appears. Click Command Prompt.

To write the new Windows 7 or Windows Server 2008 R2 bootloader:


To create a BCD store from the Windows VHD:


Set up the VHD native boot:


Set up the legacy boot:

BCDEDIT /CREATE {ntldr} /d "Chain Legacy Bootloader"
BCDEDIT /SET {ntldr} PATH \ntldr

To put things back to normal, should you ever need to: