The Deployment Guys

Helping to deploy your world automagically...

Using Device Aliases for Hardware Specific Application Installation

Using Device Aliases for Hardware Specific Application Installation

  • Comments 4
  • Likes
15 Feb 2010 Update – To use techniques found in this post with MDT 2010 you will need to use one of the workarounds described in this post:  http://blogs.technet.com/deploymentguys/archive/2010/02/15/using-convertbooleantostring-with-ztigather-wsf-in-mdt-2010.aspx.

In my last post I described how to use and extend model aliases.  In this installment I show how you can do the same thing with individual devices or groups of devices.

Defining setting, applications, etc. by model works in many instances.  However, there are time when a device may or may not be installed in any particular model (e.g. broadband wireless adapter) and you may need to install an application only if the device is installed.  I had just such a need at my current customer and this led me to develop a concept of Device Aliases.  I define a Device Alias as a friendly name given to a device or groups of devices for which you want to configure the same settings, applications, etc.

I used a simple version of the concept of a Device Alias in my post on Windows XP Tablet PC Edition 2005 Single-Image Deployment.  The IsTablet property is actually a device alias for the defined set of digitizer devices.  IsTablet is set to True when one of the digitizer devices if present.

[Settings]
Priority=IsTabletCheck, Default
Properties=MyCustomProperty, TabletPnpIds, IsTablet

[IsTabletCheck]
TabletPnpIds=ACPI\WACF004,ACPI\WACF008,ACPI\MAI3310,ACPI\FUJ02E5
UserExit=ZTI-DetectHardwareExit.vbs
IsTablet=#DetectDevices("%TabletPnpIds%")#

You could use this method as is to create additional device aliases.  However, once you have more that a few of these, the Properties line in CustomSettings.ini would become loaded with Device Alias variables.  So I took a different approach for defining multiple Device Aliases.  Before I explain, I want to note that for my new design to work you will need to fix a bug that I found in one of the MDT scripts.  I explain how to fix the script at the end of this post.

I decided to design the new implementation with its own INI file called DeviceAlias.ini.  Below is a sample INI file that I created for testing this on my laptop (Lenovo T61p).

[HIDClass]
WacomDigitizer=ACPI\WACF004,ACPI\WACF008

[Display]
NVIDIAQuadroFX570M=PCI\VEN_10DE&DEV_040C,PCI\VEN_10DE&CC_030000

[Net]
Intel82566MMGigabit=PCI\VEN_8086&DEV_1049,PCI\VEN_8086&CC_020000

[NoPrefix]
IsTablet=ACPI\WACF004,ACPI\WACF008,ACPI\MAI3310,ACPI\FUJ02E5

[NoPrefix-Mouse]
ThinkPadUltraNav=ACPI\IBM0057

This INI file is organized in to sections.  The sections contain the <Device Alias entry>=<Plug and Play ID list> entries.  These section names are used in a prefix that is added to the device alias.  When the prefix is added the Device Alias is of the form Device_<section name>_<device alias entry>.  In this example, a machine with an NVIDIA Quadro FX570M display adapter would have a the Device Alias of Device_Display_NVIDIAQuadroFX570M set to True.  I add the prefix to make it easier to find and sort Device Alias entries in the Make and Model entries in the MDT Database.  As in the example above, I like to use the device class as the prefix.  However, the section names can be anything you want.  For Device Alias variables that you don’t want to have a prefix (IsTablet is a good example), just begin the section name with NoPrefix.

I have updated ZTI-DetectHardwareExit.vbs with two new functions to process the Device Alias INI file.  The first, SetDeviceAliases, reads each section in the INI file and evaluates each entry to determine if any of the Plug and Play IDs in the list for the entry is installed.  It then sets the Device Alias for that entry to True or False based on that determination.  Finally, for any Device Alias that is True (the device is present), the Device Alias is added to a list item called DeviceAlias.  This list item is used in the database queries.  Below is an example of the CustomSettings.ini entries to use SetDeviceAliases.

[Settings]
Priority=SetDeviceAlias
Properties=MyCustomProperty, SetDeviceAliases

[SetDeviceAlias]
UserExit=ZTI-DetectHardwareExit.vbs
SetDeviceAliases=#SetDeviceAliases("DeviceAlias.ini")#

Even a Device Alias is insufficient to identify which hardware specific applications should be installed during a deployment.  At minimum, you usually also need to know the operating system version and architecture for which the applications are targeted.  For example, for an NVIDIA Quadro FX570M display adapter you would typically have one or more hardware specific applications for Windows XP x86, one for Windows Vista x86, one for Windows Vista x64, etc.  To that end I created a new composite property called DeviceOSArchAlias. which combines the Device Alias, OSVersion, and Architecture properties.  (I refer to this property by a newly minted acronym called DOAA.  Sounds like something Homer Simpson would say. J )  I create this by using another new function, SetDeviceOSArchAliases, using CustomSettings.ini entries like the ones below:

[Settings]
Priority=SetDeviceAlias
Properties=MyCustomProperty, SetDeviceAliases, SetDeviceOSArchAliases

[SetDeviceAlias]
UserExit=ZTI-DetectHardwareExit.vbs
SetDeviceAliases=#SetDeviceAliases("DeviceAlias.ini")#
SetDeviceOSArchAliases=#SetDeviceOSArchAliases("DeviceAlias.ini")#

SetDeviceOSArchAliases also adds the DOAA entries that are True to a list item called DeviceOSArchAlias to be used in the database queries.  So for the DeviceAlias.ini shown above, SetDeviceOSArchAliases run on a Windows Vista x64 machine that an NVIDIA Quadro FX570M display adapter, an Intel 82566MM Gigabit ethernet adapter, and a ThinkPad UltraNav pointing device will create the following properties and list items:

Device Alias Properties
Device_HIDClass_WacomDigitizer = False
Device_Display_NVIDIAQuadroFX570M = True
Device_Net_Intel82566MMGigabit = True
IsTablet = False
ThinkPadUltraNav = True

DeviceAlias List Item
DeviceAlias001 = Device_Display_NVIDIAQuadroFX570M
DeviceAlias002 = Device_Net_Intel82566MMGigabit
DeviceAlias003 = ThinkPadUltraNav

DOAA Properties
DOAA_Display_NVIDIAQuadroFX570M_Vista_X64 = True
DOAA_Net_Intel82566MMGigabit_Vista_X64 = True
ThinkPadUltraNav_Vista_X64 = True

DeviceOSArchAlias List Item
DeviceOSArchAlias001 = DOAA_Display_NVIDIAQuadroFX570M_Vista_X64
DeviceOSArchAlias002 = DOAA_Net_Intel82566MMGigabit_Vista_X64
DeviceOSArchAlias003 = ThinkPadUltraNav_Vista_X64

To define settings, applications, roles, etc. in the MDT Database based on either the DeviceAlias or DeviceOSArchAlias, enter the DeviceAlias or DeviceOSArchAlias as the Model in the Make and Model entries in the Database.  You can put anything you want in the the Make field in the database entries.  I enter the alias type (DeviceAlias or DeviceOSArchAlias) so that I can sort the entries by type.  Here is a screen shot with a DeviceAlias or DeviceOSArchAlias entry for a device in the Panasonic Toughbook model CF-U1 that I have been working with recently.

Model-DeviceAlias

You would then use CustomSettings.ini entries like the ones below.  (The DatabaseVariables section below is there because I like to use variables for the common database parameters in the other sections so that the actual values only have to be changed in the DatabaseVariables section.  Note that some lines may wrap on the screen depending on your display resolution.)

[Settings]
Priority=SetDeviceAlias, DatabaseVariables, DASettings, DAPackages, DAApps, DAAdmins, DARoles, DOAASettings, DOAAPackages, DOAAApps, DOAAAdmins, DOAARoles
Properties=MyCustomProperty, MASQLServer, MADatabase, MANetlib, MASQLShare, SetDeviceAliases, SetDeviceOSArchAliases

[SetDeviceAlias]
UserExit=ZTI-DetectHardwareExit.vbs
SetDeviceAliases=#SetDeviceAliases("DeviceAlias.ini")#
SetDeviceOSArchAliases=#SetDeviceOSArchAliases("DeviceAlias.ini")#

[DatabaseVariables]
MASQLServer=SQLS001
MADatabase=MDT
MANetlib=DBNMPNTW
MASQLShare=Logs$

[DASettings]
SQLServer=%MASQLServer%
Database=%MADatabase%
Netlib=%MANetlib%
SQLShare=%MASQLShare%
Table=MakeModelSettings
Parameters=DeviceAlias
DeviceAlias=Model

[DAPackages]
SQLServer=%MASQLServer%
Database=%MADatabase%
Netlib=%MANetlib%
SQLShare=%MASQLShare%
Table=MakeModelPackages
Parameters=DeviceAlias
DeviceAlias=Model
Order=Sequence

[DAApps]
SQLServer=%MASQLServer%
Database=%MADatabase%
Netlib=%MANetlib%
SQLShare=%MASQLShare%
Table=MakeModelApplications
Parameters=DeviceAlias
DeviceAlias=Model
Order=Sequence

[DAAdmins]
SQLServer=%MASQLServer%
Database=%MADatabase%
Netlib=%MANetlib%
SQLShare=%MASQLShare%
Table=MakeModelAdministrators
Parameters=DeviceAlias
DeviceAlias=Model

[DARoles]
SQLServer=%MASQLServer%
Database=%MADatabase%
Netlib=%MANetlib%
SQLShare=%MASQLShare%
Table=MakeModelRoles
Parameters=DeviceAlias
DeviceAlias=Model

[DOAASettings]
SQLServer=%MASQLServer%
Database=%MADatabase%
Netlib=%MANetlib%
SQLShare=%MASQLShare%
Table=MakeModelSettings
Parameters=DeviceOSArchAlias
DeviceOSArchAlias=Model

[DOAAPackages]
SQLServer=%MASQLServer%
Database=%MADatabase%
Netlib=%MANetlib%
SQLShare=%MASQLShare%
Table=MakeModelPackages
Parameters=DeviceOSArchAlias
DeviceOSArchAlias=Model
Order=Sequence

[DOAAApps]
SQLServer=%MASQLServer%
Database=%MADatabase%
Netlib=%MANetlib%
SQLShare=%MASQLShare%
Table=MakeModelApplications
Parameters=DeviceOSArchAlias
DeviceOSArchAlias=Model
Order=Sequence

[DOAAAdmins]
SQLServer=%MASQLServer%
Database=%MADatabase%
Netlib=%MANetlib%
SQLShare=%MASQLShare%
Table=MakeModelAdministrators
Parameters=DeviceOSArchAlias
DeviceOSArchAlias=Model

[DOAARoles]
SQLServer=%MASQLServer%
Database=%MADatabase%
Netlib=%MANetlib%
SQLShare=%MASQLShare%
Table=MakeModelRoles
Parameters=DeviceOSArchAlias
DeviceOSArchAlias=Model

In a computer replacement and/or OS change (different source and destination OS) scenario you will likely only want to set the DeviceOSArchAlias and do the DOAA database queries using a Gather step in the State Restore phase.  This is because you will almost always want the hardware specific settings, application installations, etc. based on the target model and operating system.

Fixing the Database Class Bug

As I explained earlier, there is a bug in the MDT Database class that needs to be fixed before the database queries above will work.  If a parameter in the database section is a list item like DeviceOSArchAlias, then the Database class Query function does not use the translated column name (Model in this case) and the query fails.

The problem appears in line 2691 in the MDT 2008 Update 1 version of ZTIUtility.vbs or line 549 in the MDT 2010 RTW version of ZTIDataAccess.vbs .  This line is:

tmpClause = sElement & " IN ("

The query works if the line is changed to:

tmpClause = sColumn & " IN ("

If you need to make this change, be sure to edit not only the copies in your current deployment shares but also edit the copy in %ProgramFiles%\Microsoft Deployment Toolkit\Templates\Distribution\Scripts so that new deployment shares will get the fix as well.

Disclaimer: The information on this site is provided "AS IS" with no warranties, confers no rights, and is not supported by the authors or Microsoft Corporation. Use of included script samples are subject to the terms specified in the Terms of Use.

This post was contributed by Michael Murgolo, a Senior Consultant with Microsoft Services - U.S. East Region.

Attachment: ZTI-DetectHardwareExit.zip
  • Thanks for the post and code.  I wanted to let you know that the ZTI-DetectHardwareExit.vbs was not returning the proper value from the DetectDevices function when I implemented it per your instructions.  I was able to get it working properly by changing line # 285  located toward the bottom of the DetectDevices function:

    DetectDevices = ConvertBooleanToString(bDevicePresent)

    Was changed to:

    DetectDevices = CStr(bDevicePresent)

    Prior to making this change the function returned a null value.

    Now the code is working as expected and I'm using it along with the model alias routines previously mentioned to dramatically reduce (80% reduction) the number of make and model records I need for our environment.  In addition, we are going to see how this will work for automating the installation of locally attached printer software and other locally attached devices that would otherwise require a tech. to perform a manual installation after the automated deployment completed.  Very handy for in-place upgrade scenarios.

  • Thanks Trevor,

    That's interesting.  The ConvertBooleanToString function is part of ZTIGather.wsf and works fine for me.  Your change will return a localized string for True and False when the language is not US English.  If you are only deploying US English Windows, this will not be a problem.

    I'm glad that you've found this useful.  Be sure to post a comment on how it works for the locally attached devices.

    Michael Murgolo

  • I ran into a similar issue to Trevor's while setting up automation for Win7. The logs indicated it found the device, but the variable was still set to the value from CustomSettings.ini. Copying the ConvertBooleanToString function into ZTI-DetectHardwareExit.vbs yielded the expected True/False response. This is using SCCM R2SP2/MDT 2010. An XP setup using an older ZTI-DetectHardwareExit.vbs (from the XP Tablet post) is still working - but it uses the MDT 2008 files. It looks like the ZTI-DetectHardwareExit.vbs script is no longer inheriting the ConvertBooleanToString function in MDT 2010.

  • Thanks Mike.

    You hit the issue right on the head.  I've addressed this in a new post: http://blogs.technet.com/deploymentguys/archive/2010/02/15/using-convertbooleantostring-with-ztigather-wsf-in-mdt-2010.aspx

    Michael Murgolo

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment