• Michael Niehaus' Windows and Office deployment ramblings

    Using the Hyper-V integration components with MDT 2008 Update 1 Lite Touch

    • 10 Comments

    There have been some blog postings talking about how to add the Hyper-V integration components into Windows PE.  The first from Mike Sterling, available at http://blogs.msdn.com/mikester/archive/2008/05/30/using-the-hyper-v-integration-components-in-winpe.aspx, talks about the manual way of going about this.  Then the Deployment Guys, specifically David Hornbaker, talked about how to do this with MDT 2008 in his posting at http://blogs.technet.com/deploymentguys/archive/2008/06/12/adding-hyper-v-integration-components-to-winpe-using-mdt-2008.aspx.  But with MDT 2008 Update 1, we can improve this process and fix some of the challenges that David alludes to in his post.  (I'll point these out below.)

    Step #1: Obtaining the drivers

    First you need the Hyper-V integration components from the "VMGUEST.ISO".  The easiest way to do this is from inside a virtual machine: mount the ISO and extract the needed Windows6.0-KB951634-x86.msu file into a new, empty directory.  (See the other blog entries for details.)  Then you need to first extract the x86 drivers:

    MD MSU
    expand  Windows6.0-KB951634-x86.msu -F:*.CAB MSU

    MD Files
    expand  MSU\Windows6.0-KB951634-x86.cab -F:* Files

    (I skipped David's steps that rearranged the files and cleaned up the temporary working directories.  You can choose to do those if you like.)  Here's what it would look like (except for the output of the final command):

    x86

    Repeat the steps for the x64 drivers too, using a different new, empty directory because some of the file and directory names will be the same:

    MD MSU
    expand  Windows6.0-KB951634-x64.msu -F:*.CAB MSU

    MD Files
    expand  MSU\Windows6.0-KB951634-x64.cab -F:* Files

    Not surprisingly it will look it looks just like the x86 output, just with different directory and file names:

    x64

    The final EXPAND command for both x86 and x64 should show 305 files extracted (at least if you are using the Hyper-V RTM integration components; the number may change in the future):

    305Files 

    One important note:  If you try this on Windows Server 2003 or Windows XP, it may not work properly because these operating systems contain earlier versions of EXPAND.EXE and related DLLs.  You won't see any errors or any other indication that the process didn't work; the resulting file count will be much smaller.  Ideally, use Windows Vista or Windows Server 2008 to do the extraction.  (If you are desperate, you could copy the EXPAND.EXE, DPX.DLL, and MSDELTA.DLL files from a Windows Server 2008 OS or image.  Place these files into the empty directories you create above, then make sure you run them by specifying ".\EXPAND.EXE" so that Windows doesn't find them in the system path first.)

    Step #2: Adding the drivers to Workbench

    This sounds like it should be really easy, and it almost is.  First, import the x86 integration component drivers , pointing to the directory "files" directory you created above (in my case, "C:\x86\Files").  Create a new driver group called "Windows PE Drivers" and be sure to import the drivers into that group:

    Import x86

    Now look at the results of that import:

    Imported x86

    Notice that some of the drivers say that they are for both x86 and x64 platforms.  Well, that's not actually true, as these are only x86 drivers.  So we'll take advantage of a new MDT 2008 Update 1 feature to de-select the x64 platform for each of these drivers.  Right click on each of the drivers and choose "Properties," then uncheck the "x64" checkbox:

    Uncheck x64

    Now we need to repeat this same process for x64 drivers, this time selecting the "c:\x64\Files" directory and the "Windows PE Drivers" group created previous.  But there's one other important item:  You need to check the "Import drivers even if they are duplicates of an existing driver" box:

    Import x64

    If you didn't do this, Deployment Workbench will think the drivers are already present and won't import them again.  It checks for duplicates based on the class, manufacturer, and version.  In this case, all of those values are the same so we wouldn't import the drivers again.  By checking the box, they'll all get imported anyway.

    You'll notice now that there are again some that say they are for x86 and x64.  Uncheck the "x86" checkbox for these newly-imported drivers since they are all x64 drivers.

    You should now have this full list of drivers:

    Full list

    Notice the paths for each of the drivers: The ones with the "_(1)" suffix wouldn't have been imported if you didn't check the "import duplicates" box.  (This also points out another change in MDT 2008 Update 1: We no longer create driver directories containing spaces in them.  This is related to a problem with the processing of [SysprepMassStorage] sections by sysprep.exe on Windows XP or Server 2003.  More on that some other time.)

    Step #3: Creating new Windows PE images

    With all the needed drivers in place, we just need to tell Deployment Workbench to use them.  Open the properties of the lab deployment point and specify the "Windows PE Drivers" group you created previously.  (Be sure to check the "x64" box on the General tab if you want x64 images.)  Also specify to "Include all drivers from the selected driver group":

    Deploy properties 

    This "include all drivers" checkbox is another new feature in MDT 2008 Update 1.  Without this checkbox, we could only inject mass storage, network, video, and system-class drivers.  With this, we'll inject all the drivers in the specified group.  Why does this matter?  Well, in this case we want to be sure to inject the HIDClass drivers you can see in the above list.  HID stands for "human interface device."  This is the driver that enables mouse integration so that you no longer need to press Control-Shift-Left Arrow all the time you are working in Windows PE.

    Also make sure that you have added all the existing drivers, at least for networking and mass storage, into the same "Windows PE Drivers" group, otherwise your Windows PE boot images will work on Hyper-V but not on any machine requiring other out-of-box drivers.

    Now, you can "Update" the deployment point to generate the new images containing the drivers that were imported in the previous step and selected in this one.  Want to see the proof that they were all injected?  Check the %TEMP%\DeployUpdates_x86.log (or %TEMP%\DeployUpdates_x64.log for the x64 boot image) to see each of them being imported.  (Search for "/inf=" to find the right lines.)

    In David's blog he mentioned that you would need to create the Windows PE images in separate steps.  He was talking about using two different driver groups, one for x86 containing the x86 drivers and one for x64 containing the x64 drivers.  This was necessary for two reasons:

    1. There's no way to specify different driver groups for x86 and x64.
    2. There was no way to alter drivers that didn't specify the right platforms.

    The first reason is really needed because of the second.  But now since MDT 2008 Update 1 allows you to override the platform on each driver, you can again get back to a single driver group - both problems solved.

    Step #4: Exclude the Hyper-V drivers from from the full OS

    Now that there are Hyper-V drivers included in Deployment Workbench, they will also be injected into the full OS.  That's less than desirable because we really want the Hyper-V drivers to be installed in the full OS using the integration components.  So if you want to prevent this, you can create a new driver group containing all the non-Hyper-V drivers.  (Yes, if you have lots of drivers this is a fairly painful process as you need to select the new group by opening the properties of each driver individually.)

    Once you've created this group, e.g. "Full OS Drivers", you need to tell the MDT scripts to only use this group.  There's no user interface in the task sequence editor to specify this, but you can add it to CustomSettings.ini (on the Rules tab of the deployment point):

    Rules

    If you skipped this step, it probably wouldn't hurt anything, but you do want to make sure the integration components are installed afterwards.

    Step #5: Install the Hyper-V integration components

    Now we need to install the integration components themselves.  (Yes, this isn't related to Windows PE, but hey, go back and read the title: it's not all about Windows PE).  The easiest way to do this is to set them up as an application.  In Deployment Workbench, create a new application with source files (so we don't need to worry about mounting the VMGUEST.ISO), pointing to the "e:\support\x86" directory (where E: is my DVD drive in the VM) that contains all the needed files.  For the command line, specify "setup.exe /quiet /norestart".  After the application has been added, modify the properties to specify "Reboot the computer after installing this application".  (If you want, you can also modify the platform restrictions so this application is only seen on supported OSes.)

    Repeat the same process for the x64 integration components, pointing to the "e:\support\amd64" directory.

    With these applications created, you can now select them in the Lite Touch deployment wizard.  If you want to automate this by adding the application into the task sequence, you can certainly do that instead (hiding the applications from the wizard at the same time).

    Finally!

    With these pieces in place, it should be that much easier to work with MDT 2008 Update 1 and Hyper-V.  When I started writing this up (a long time ago, before MDT 2008 Update 1 was even released) I didn't think it would take so long.  And I'm sure I didn't need to be quite so verbose...

  • Michael Niehaus' Windows and Office deployment ramblings

    Piles and piles of Dell drivers

    • 9 Comments

    For those of you who attended my driver management sessions at MMS 2009 and TechEd 2009 US, you know that Dell is planning to provide CAB files for many of their machines, starting with the corporate laptop models.  These are “raw” drivers, provided in a CAB file that saves you the hassle of trying to figure out how to download and extract the contents of dozens of different packages for each model.  Now, one CAB file contains all the files you need, just extract the contents of the CAB and import them into your driver repository of choice (MDT 2008, MDT 2010, ConfigMgr, WDS R2, etc.).

    See http://www.delltechcenter.com/page/Dell+Business+Client+Operating+System+Deployment+-+The+.CAB+Files for the list of models that now have CAB files posted (there are quite a few).

    Once MDT 2010 Beta 2 comes out, you won’t even need to extract the contents of the CAB files.  Deployment Workbench will automatically extract the CAB file contents into a temporary folder and then import each driver that it finds.

  • Michael Niehaus' Windows and Office deployment ramblings

    Upgrading to Microsoft Deployment Toolkit (MDT) 2008 - Lite Touch

    • 9 Comments

    If you are upgrading from BDD 2007 (any version) to MDT 2008, the instructions are covered in the "Getting Started Guide" included with MDT 2008.  So I won't repeat that discussion here.  I want to focus on the new scenario, upgrading from the original Microsoft Deployment to the new Microsoft Deployment Toolkit 2008.  Here are the basic steps:

    1. Make sure you have a backup of your environment.  While I don't expect anything to go wrong, it's always a good practice to have a backup :-)
    2. Install the new MSI.  This will automatically upgrade the existing installation files, e.g. C:\Program Files\Microsoft Deployment Toolkit.
    3. Run the new Deployment Workbench.
    4. Click on the "Distribution Share" node and run the "Create Distribution Share" wizard to upgrade the scripts and tools in the distribution share directory.  You can choose to backup the existing scripts as part of this.(After doing this, you may need to press F5 to refresh the nodes under the distribution share node.)
    5. Update (not files only, as you need to get the new scripts into the Windows PE images) each deployment point.

    MDT 2008 does not require Windows AIK 1.1 if you are using only Windows Vista RTM, Windows XP, or Windows Server 2003; Windows AIK 1.0 is fine for these.  But if you are using Windows Vista SP1 or Windows Server 2008, you need to upgrade to Windows AIK 1.1.  (If you don't, as soon as you add a Windows Vista SP1 or Windows Server 2008 image, you'll start seeing warning dialogs.  They won't go away until you do upgrade.)  The steps needed to upgrade to Windows AIK 1.1 are:

    1. Uninstall Windows AIK 1.0.
    2. Reboot.
    3. Install Windows AIK 1.1.
    4. Run Deployment Workbench.
    5. Update (not files only) each deployment point in order to get the updated Windows PE 2.1 images.  (Windows AIK 1.1 includes Windows PE 2.1; Windows AIK 1.0 included Windows PE 2.0.)

    That should do it.  Now you're ready to start with Windows Vista SP1 and Windows Server 2008 :-)

  • Michael Niehaus' Windows and Office deployment ramblings

    MDT 2010 Update 1: Fix to re-enable System Restore in ConfigMgr task sequence

    • 9 Comments

    Some people noticed that during an OS deployment task sequence, performed either by MDT 2008 Lite Touch or by ConfigMgr, could capture sensitive information (from unattend.xml, variables.dat, etc.) as part of the automatic System Restore snapshot process that happens whenever a new driver, application, security update, etc. is installed.

    To address that issue, we added some logic in MDT 2010 to disable System Restore by configuring the default unattend.xml template:

    <component name="Microsoft-Windows-SystemRestore-Main" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <DisableSR>1</DisableSR>
    </component>

    We then added logic to re-enable that at the end of the deployment process – but only for Lite Touch.  (You can see that logic in LTICleanup.wsf.)  We discovered later that this was left out of the ConfigMgr scripts.  So as a result, machines deployed using ConfigMgr and an MDT 2010 task sequence template ended up with System Restore disabled.

    In MDT 2010 Update 1, we added logic to address this.  Now, System Restore will be re-enabled at the end of the deployment even with ConfigMgr.  (Because we don’t have the equivalent of LTICleanup.wsf in a ConfigMgr task sequence, the logic was added to ZTICopyLogs.wsf, the last script to run during an OSD task sequence.)

    (10527)

  • Michael Niehaus' Windows and Office deployment ramblings

    Creating a fully-patched image using MDT 2010 Lite Touch

    • 9 Comments

    I’ve always been a fan of the thinnest image possible.  Taking that to an extreme, that means using the original image straight off the Microsoft media.  But over time if you did this you’d find that the time required to apply patches to that image becomes unmanageable.  (Case in point:  I started up a new laptop for the first time with an OEM-installed image that had hooks to require all patches be applied before first logon.  It took three hours for that to happen.)

    I’ve also been a fan of doing “just in time” patching, which is something that MDT can do too:  Instead of patching the image in advance, you can inject updates offline after the image has been applied to the disk but before it boots for the first time.  That does often improve the time required, but it doesn’t eliminate it – it adds time when initially injecting the updates offline, and then more time on first boot as the “online actions” for those “offline patches” are completed (you’ll see the messages on the screen during the first boot showing a percentage complete while this is happening).

    So reading between the lines, that means I would suggest always creating your own master image containing at least all the current service packs and patches.  (Don’t try to install the OS service pack yourself – just download “slipstreamed” media from the Microsoft licensing website, as that’s the ultimate time-saving technique.)  So how should you do this?  Well, there are a few ways:

    • Mount the existing WIM image and just inject the updates offline with DISM.  This is certainly doable, but there are three challenges:
      • The online actions for these updates will still take some time
      • It introduces a “human touch” into the process, unless you go through the effort of automating this to make it a repeatable process.
      • It only works for operating system updates.
    • Build a new image and install all the updates into that image before sysprepping and capturing the image using a completely automated process.  This is my preferred approach, because it’s a consistent process for any other type of update being made to the image.

    Not surprisingly, MDT 2010 Lite Touch provides a way to implement my preferred method above – and actually multiple methods that can be used.  Let’s go through those methods.

    Install all updates from Microsoft Update directly

    This is the easy way, as long as you have good internet bandwidth (all updates are downloaded from the internet) and a direct path to these downloads (as we don’t really support proxy servers in the MDT task sequence), and always want to install all critical updates.  (We skip language packs, drivers, and service packs by default, and you can exclude additional updates, but the exclusion process requires a little work.)

    To use this method, all you need to do is search your task sequence for the following steps:

    • Windows Update (Pre-Application Installation)
    • Windows Update (Post-Application Installation)

    Enable both of them, and then build a new image – that’s all there is to it.  (Why are there two steps you ask?  Well, the first might be required in order for the subsequent application installs to complete; the second might be required to patch the applications, e.g. Office, after it’s installed.  If the second step doesn’t need to install any additional patches, it won’t take very long.)

    Install all updates approved on your WSUS server

    To give you better control over patched put into your image, you may only want to install approved updates.  If you are using Windows Server Update Services (WSUS), then you already have such an approval mechanism in place, all you need to do is tell the task sequence to talk to WSUS instead of going to the internet.  This is pretty simple too:

    • Enable the same “Windows Update” task sequence steps listed in the previous section (two of them).
    • Add an entry into the [Default] section of CustomSettings.ini that says:
      WsusServer=http://SERVERNAME:PORT
      where “SERVERNAME” is the fully-qualified name of your WSUS server and “PORT” is the port number that WSUS was configured to use (only needed if that is something other than port 80).

    Make sure that you have configured WSUS to install updates on unknown computers, because when building a reference computer it is indeed unknown to WSUS at the point the task sequence is executing.

    Download all updates and import into your deployment share

    This one is probably the most work, primarily because you need to manually download all the updates that you want to install, and it only works for OS updates (as they are the only ones that can be injected offline). The steps required:

    • From the monthly security bulletin, or using a site such as http://catalog.update.microsoft.com, download all the updates which are typically packaged as MSU files.  (If they come down as executables, you’ll need to extract the MSU files from the executable.)
    • Import the MSU files into Deployment Workbench from the “OS Packages” node.  (This will extract a CAB file that is contained in the MSU file, since that’s the piece that gets installed offline.)

    When the task sequence runs, the “Apply Patches” will identify all the updates for the OS and platform being deployed, download them to the client, and update the unattend.xml to inject them.  (SETUP.EXE will later call DISM.EXE to do the actual injection after the image has been extracted and applied to the hard drive.)  If you want to apply a particular set of patches, you can configure a selection profile with one or more folders containing those updates, then configure the “Apply Patches” step to use that selection profile.

    How often should I do this, and what should I do in between?

    Well, that’s a completely different discussion.  Some people do a new image monthly (and probably don’t do much testing on that image each time they recreate it).  Some do it every few months.  Some do it once a year.  You just need to balance the efforts required to build it (easy), test it (not quite so easy), and distribute it (can be really painful) against the added time of applying some updates later.

    You can actually use any (or all) of the above methods in that “later” deployment task sequence too:

    • Enable the “Windows Update” steps in the deployment task sequence to download and install any updates released since the last image was created (from Microsoft Update or from WSUS if you set the WsusServer variable).
    • Download and import any new MSU files into Workbench (but keep these separate from all the ones in the image as MDT won’t know which are installed and which aren’t so it will download all of them and let DISM figure it out).

    For more information

    Some additional links that might be useful:

    Windows Update in MDT 2010 « Xtreme Deployment

    Approving Windows Updates in an MDT 2010 Standalone Environment

  • Michael Niehaus' Windows and Office deployment ramblings

    USMT 4.0 Support for Office 2010

    • 9 Comments

    A new hotfix for USMT 4.0 was released today to support migrating Office 2010 settings.  (It includes other fixes too.)  You may want to download this and integrate it into your deployment processes.  The full instructions for doing this (including what needs to be done with MDT and ConfigMgr) are included in the KB:

    http://support.microsoft.com/kb/2023591

    There is one complication that you should be aware of if you are using ConfigMgr and moving from Windows XP or deploying Windows XP.  USMT 4.0 uses a set of manifest files to determine what needs to be migrated from Windows XP.  These manifest files are stored in the “DLManifests” folder, which is part of your USMT package in ConfigMgr.  There is an issue though where Scanstate.exe can’t find this DLManifests folder when run from ConfigMgr.  In MDT 2010 Update 1, we included a workaround for this with some logic in ZTIUserState.wsf, copying the folder where Scanstate can find it:

    ' Workaround for USMT bug in Windows 7 AIK
    If oEnvironment.Item("DeploymentMethod") = "SCCM" and oEnvironment.Item("OSVersion") = "XP" and oFSO.GetFileVersion(sFoundScanState) = "6.1.7600.16385" then
        oUtility.RunWithHeartbeat "cmd.exe /c xcopy /iesryhd """ & sUSMTPath &"\DlManifests"" """ & oEnv("SystemRoot") & "\system32\DlManifests" &""" 1>> " & oLogging.LogPath &"\zticopyUSMT.txt 2>>&1 "
    End if

    Notice that this checks specifically for build 6.1.7600.16385 of Scanstate.exe, the version released in the Windows 7 version of Windows AIK, as we expected this problem to be fixed in the next version of USMT.  Well, it wasn’t.  But once you install the KB 2023591 hotfix, the version changes to 6.1.7601.21645 and our fix stops working.

    You can work around this by fixing the fix in ZTIUserState.wsf to read like this:

    If oEnvironment.Item("DeploymentMethod") = "SCCM" and oEnvironment.Item("OSVersion") = "XP" and (oFSO.GetFileVersion(sFoundScanState) = "6.1.7600.16385" or oFSO.GetFileVersion(sFoundScanState) = "6.1.7601.21645")  then

    If you aren’t using ConfigMgr or don’t have Windows XP around any more, you won’t need to worry about this.

  • Michael Niehaus' Windows and Office deployment ramblings

    Make sure a ConfigMgr task sequence has all the packages it needs

    • 9 Comments

    If you’ve done ConfigMgr OS deployments, you’ve probably seen an error dialog like this before:

    image

    Pretty simple, right?  Distribute this package to a local DP and then try again.  But there are often dozens (or in extreme cases, hundreds) of packages referenced by the package, so you might have to go through this cycle a few times before you get them all.  Fortunately, there are some ConfigMgr WMI classes that can help figure out which packages are missing.  With a little bit of PowerShell logic, we can automate the whole process, through these basic steps:

    1. Get a list of all the task sequences.
    2. Get a list of all the packages referenced by those task sequences.
    3. Compare the complete list of distribution points against the list for each referenced package.
    4. Add a new distribution point to each package that is missing (keeping in mind that only boot images need to be distributed to SMSPXEImages$ distribution point shares).

    This process will take care of boot images, OS images, OS install packages, driver packages, software update packages, or any other type of packages that are referenced (because behind the scenes, packages are packages to ConfigMgr – only the UI differentiates).

    The scripts needed to this are attached to this blog.  You’ll need to save the SCCM.psm1 file in an appropriate PowerShell module folder (see the comments in the script for more details) so that the CheckTaskSequences.ps1 script can find it (and of course you’ll have to enable PowerShell script execution using something like “Set-ExecutionPolicy RemoteSigned”).  Then, just run CheckTaskSequences.ps1 each time you create a new task sequence.  It will very quickly identify the packages that need to be distributed and take care of those for you.

    Note:  Version 1.1 of the script is now attached (using version 1.5 of SCCM.psm1) to address a couple of bugs found in the current version.  See the comments in CheckTaskSequences.ps1 for more information.

  • Michael Niehaus' Windows and Office deployment ramblings

    Querying the MDT database using a custom model

    • 8 Comments

    This seems to be a frequent question that comes up:

    “I am working with PCs from <vendor> that have model strings that frequently change, although the first part is always consistent.  How can I use these models with the MDT database without creating a new entry for each unique string?”

    This seems to come up most often with computers from Lenovo, where the first four characters indicate the model and the last three indicate a specific configuration of that model.  It’s also seen with various HP computers, although their pattern tends to be a little more difficult.

    The “gather” process that MDT uses doesn’t provide a way to do wildcard or “like” queries, but it does provide extensibility to let you define your own property to use instead of “Model” when querying the database.  Let me give a “real world” example for the Lenovo case.  I can use a CustomSettings.ini like this:

    [Settings]
    Priority=CalculateCustom, MMSettings
    Properties=CustomModel

    [CalculateCustom]
    CustomModel=#Left("%Model%", 4)#

    [MMSettings]
    SQLServer=MNiehaus-T61p-7
    Instance=SQLExpress
    Database=MDTDatabase
    Netlib=DBNMPNTW
    SQLShare=DeploymentShare$
    Table=MakeModelSettings
    Parameters=Make, CustomModel
    CustomModel=Model

    This defines a new property called “CustomModel”.  It includes a rule that has a very simple manipulation: it sets the value to the first four characters of the existing “Model” value, which in the case of my T61p laptop results in a value of “6458”.

    I then modified the database query to tell it to use “CustomModel” as a parameter instead of “Model”.  If that’s all I did, the query would fail because it would create a SQL statement that specified “WHERE CustomModel = ‘6458’” but that’s not valid since there isn’t a CustomModel column in the database.  That’s where the next line comes in:

    CustomModel=Model

    This says that the property “CustomModel” as we know it locally is called “Model” in the database.  As a result, the correct query is generated:

    About to issue SQL statement: SELECT * FROM MakeModelSettings WHERE MAKE = 'LENOVO' AND Model = '6458'
    Successfully queried the database.

    That’s all it takes.  Now, there would typically be more than just the [MMSettings] section that needs the “CustomModel” updates – you would also want to change [MMPackages], [MMApps], [MMAdmins], and [MMRoles] the same way.

    If you need to do a calculation that is more complex than the simple substring that I implemented above, you may need to use a user exit to do the calculation.  The end of the exit just needs to set the same “CustomModel” property.  The rest of the logic would be the same.  So you could use something like this for the exit:

    Function UserExit(sType, sWhen, sDetail, bSkip)

        If sType = "SECTION" and sWhen = "BEFORE" then

            oLogging.CreateEntry "Calculating custom model string.", LogTypeInfo

            If UCase(oEnvironment.Item("Make")) = "LENOVO" then
                oEnvironment.Item("CustomModel") = Left(oEnvironment.Item("Model"), 4)
            ElseIf Instr(oEnvironment.Item("Model"), "(") > 2 then
                oEnvironment.Item("CustomModel") = Trim(Left(oEnvironment.Item("Model"), Instr(oEnvironment.Item("Model"), "(") - 2))
            Else
                oEnvironment.Item("CustomModel") = oEnvironment.Item("Model")
            End if

        End if

        UserExit = Success

    End Function

    Save that as “CustomModelExit.vbs” in the same “Scripts” directory with ZTIGather.wsf, then edit the CustomSettings.ini to specify to run it:

    [Settings]
    Priority=CalculateCustom, MMSettings
    Properties=CustomModel

    [CalculateCustom]
    UserExit=CustomModelExit.vbs

    [MMSettings]
    SQLServer=MNiehaus-T61p-7
    Instance=SQLExpress
    Database=MDTDatabase
    Netlib=DBNMPNTW
    SQLShare=DeploymentShare$
    Table=MakeModelSettings
    Parameters=Make, CustomModel
    CustomModel=Model

    The only change from the previous CustomSettings.ini sample is the [CalculateCustom] section.  Now it specifies the run the user exit script.  So what exactly does this script do?  Well, if it’s a Lenovo machine, it takes the first four characters.  If the models string contains a starting parenthesis, “(“, it will chop everything from that point off of the model (e.g. “My Model (Test)” will become “My Model”).  In any other case, the script will assign the current model value to the CustomModel property.  (That simplifies things somewhat.)

    You might need to tweak the script some based on your specific requirements, but the basic setup should work for whatever manipulation you would like to do.

  • Michael Niehaus' Windows and Office deployment ramblings

    MDT 2010 Wizard Example: Role Selection

    • 8 Comments

    We have seen lots of requests over the past couple of years for a wizard pane that allows you to select from a list of roles that should be applied to a machine, where those roles are defined in the MDT database.  There are a few examples of this available on the web, implemented in different ways.  I’ll throw another one into the mix, this one using an ADO.NET Data Services web service to get the needed data.  (If you didn’t read my previous posting about this setup, click here.)

    <?xml version="1.0" encoding="utf-8"?>
    
    <Wizard>
    
      <Global>
    
        <CustomStatement><![CDATA[
    
    ' ***************************************************************************
    
    ' File:	Roles.xml
    
    ' Author:	Michael Niehaus
    
    ' Version:	1.0
    
    ' Purpose:	Display a list of roles from the MDT database, retrieved
    
    '	using an ADO.NET Data Services.web service.  One
    
    '	or more roles can be selected.  After they have been
    
    '	chosen, CustomSettings.ini needs to be re-processed
    
    '	to pick up the new settings.  Ideally this would be done
    
    '	after the wizard is complete (just in case someone 
    
    '	navigated back to the screen after initially making
    
    '	changes), but that requires changing LiteTouch.wsf.
    
    '
    
    ' NOTE:	Be sure to modify the web service URL below
    
    '
    
    ' ***************************************************************************
    
    Function InitializeRoleList
    
    	Dim sScript
    
    	Dim oDataService
    
    	Dim oRole
    
    	Dim sRoles
    
    	' Make sure that ZTIDataAccess.vbs is available since it isn't loaded by Wizard.hta
    
    	sScript = oFSO.OpenTextFile(oUtility.ScriptDir & "\ZTIDataAccess.vbs", 1, false).ReadAll
    
    	On Error Resume Next
    
    	ExecuteGlobal sScript
    
    	On Error Goto 0
    
    	' Call the web service
    
    	Set oDataService = New WebService
    
    	oDataService.WebService = "http://localhost:62932/MDTDatabase.svc/RoleIdentity"
    
    	oDataService.Method = "REST"
    
    	Set oResult = oDataService.Query
    
    	' Process the roles to populate the list of checkboxes
    
    	sRoles = ""
    
    	For each oRole in oResult.SelectNodes("//d:Role")
    
    		sRoles = sRoles & "<input type=checkbox name=Roles id=Roles enabled value='" & oRole.Text & "'>" & oRole.Text & "</input><br>"
    
    	Next
    
    	' If no roles were found, set the div to indicate that
    
    	If sRoles = "" then
    
    		sRoles = "<label class=errmsg style='display: inline;' >No roles could be found."
    
    	End if
    
    	' Update the pane
    
    	RoleList.InnerHTML = sRoles
    
    End Function
    
    Function ValidateRoleList
    
    	' Flush the value to variables.dat, before we continue.
    
    	SaveAllDataElements
    
    	SaveProperties
    
    	' Process full rules (needed to pick up the role settings, apps, etc.)
    
    	sCmd = "wscript.exe """ & oUtility.ScriptDir & "\ZTIGather.wsf"""
    
    	oItem = oShell.Run(sCmd, , true)
    
    	ValidateRoleList = True
    
    End Function
    
    ]]></CustomStatement>
    
      </Global>
    
      <Pane id="Roles">
    
        <Body><![CDATA[<H1>Select the roles to be assigned to this computer.</H1>
    
    <br>
    
    <div class=TreeList id=RoleList style="height: expression( GetDynamicListBoxSize(this) );">
    
    <label class=errmsg style="display: inline;" >Loading roles...
    
    <!-- List goes here -->
    
    </div>
    
    ]]></Body>
    
        <Validation><![CDATA[ValidateRoleList]]></Validation>
    
        <Initialization><![CDATA[setTimeout GetRef("InitializeRoleList"), 0]]></Initialization>
    
      </Pane>
    
    </Wizard>

    While this is set up as a stand-alone wizard, you can insert this into an existing deployment wizard using the MDT Wizard Editor by following these steps:

    1. Launch the MDT Wizard Editor.
    2. Open the DeployWiz_Definition_ENU.xml file.
    3. Click on the “Global” pane.  Click “Add” on the “Settings” pane and choose to add a new “CustomStatement”.
    4. Select the new “CustomStatement” at the end of the “Settings” list.
    5. Select the VBScript code above (from the first comment line to the last End Function line) and copy it to the clipboard.
    6. Paste the copied VBScript code into the text box in the MDT Wizard Editor.  Edit the web service URL to specify your ADO.NET Data Services web service URL.
    7. Select a wizard pane (the new pane will be inserted after this one, so select appropriately).
    8. Select all the text above from “<Pane” through “</Pane>” and copy it to the clipboard.
    9. Right-click on the selected pane name in the MDT Wizard Editor and choose “Paste”.

    What, your MDT Wizard Editor doesn’t have a “Paste” option?  Well, you need to download a new version from http://mdtwizardeditor.codeplex.com/, as I just added the paste capability tonight (along with other general usability improvements – I forced myself to actually use the program to create the rules wizard pane above and fixed all the behaviors I didn’t like while I was at it).

    A few notes to mention:

    • Because the wizard runs after CustomSettings.ini has been processed, the role settings, applications, etc. wouldn’t be processed as the “Gather” process isn’t run again.  To work around this, I added logic above to run ZTIGather.wsf again.  This could add a delay when clicking “Next”, so you might choose to do this later (possibly by modifying LiteTouch.wsf).  The other problem with running ZTIGather.wsf from this wizard pane:  If you navigate back to this wizard pane and uncheck an item, it’s too late – the settings for that role have already been added into the task sequence environment.
    • The MDT 2010 wizard hypertext application (Wizard.hta) doesn’t load the ZTIDataAccess.vbs script needed to make web service calls from a wizard pane.  To work around this, I added logic above to dynamically load the file.  The other alternative would be to edit Wizard.hta to tell it to include the file.
    • The role list is populated asynchronously so that the wizard doesn’t appear to be hung.  This is done by the “setTimeout” initialization statement above.  Note that the “Next” (or “Finish”) button will be enabled even while this is happening, so if you don’t want to wait you can probably go ahead and click the button to move on to the next pane.
    • If you don’t have the ADO.NET Data Services web service set up and working, don’t expect this wizard pane to somehow magically fix it :-)
  • Michael Niehaus' Windows and Office deployment ramblings

    MDT 2012 Beta 1: Cross-Platform Deployment

    • 8 Comments

    Those of you who deploy both x86 and x64 versions of Windows 7 using MDT 2010 Lite Touch probably know that you have to use two different boot images to do it:  When booted from a Lite Touch x86 boot image, you only see task sequences associated with x86 operating systems; when booted from a Lite Touch x64 boot image, you only see task sequences associated with x64 operating systems.

    With MDT 2012 Beta 1, that’s been changed.  Now, if you boot from a Lite Touch x86 boot image you will see all task sequences, whether x86 or x64. 

    But there is one “gotcha”:  If you choose a task sequence that deploys an x64 OS, MDT will need to find a copy of the corresponding x86 setup files and it will then use those to install the x64 OS.  So you need to make sure that you have x86 setup files in the deployment share (with one of the operating systems), even if you aren’t deploying that operating system.  It needs to match the version (e.g. 6.1.7601.17514) of the x64 OS that you are deploying.  (This is the really the same as if you were deploying a custom image.  Now, we just make sure we pick a copy of setup files that match the Windows PE platform being used, ignoring those that don’t, even if they are provided with the OS being deployed.)

    The other combination, booting from an x64 boot image and deploying an x86 OS, isn’t supported by Windows Setup, so we still hide x86 task sequences when you have booted into an x64 boot image.

Page 3 of 27 (265 items) 12345»