In a previous post I detailed the process for using a cut down version of the task sequence to test application installation, unfortunately this process has not worked for a number of people so I thought I should add the following tip.
If you leave any folders behind then make sure that you remove any conditions. A example of this is the folder for the state restore phase, when using the custom task sequence BDD will see that it is not in the state restore phase and skip the folder. This means that non of the tasks in that folder will be run. The screen shot below shows the condition that should be removed.
Another good tip is to leave the "Gather local only" task in your task sequence as this will then ensure that the BDD environment variables are collected. These are then able to be used by other scripts.
UPDATE - 01/09/08
MDT 2008 now includes built in support for custom task sequences and you do not need to use this process.
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.
BDD 2007 has a great technique of determining which drivers should be applied to the clients being deployed. It maintains a central driver library and then deploys the drivers based on the plug and play ID’s of the client.
So for example if we where deploying an HP DC7700 it would see that it has a Intel Pro 1000 network card and apply the appropriate driver to the client. This process works well until you realize that once we add the drivers to the driver library for the DC7700 we can affect the drivers that are applied to other hardware models.
This may not be a problem but a lot of sites must validate the drivers that are deployed to an image and they do not want unintended drivers to be deployed to their client devices.
To get around this issue BDD uses Driver Groups. Drivers can be added to a Driver Group and then you can specify the driver groups each model will receive. Through this process you can ensure that each hardware model will only receive the drivers that you specify.
This is good but unfortunately managing driver groups can be a time consuming and prone to errors. To add a driver to a group you need to open the drivers properties select the groups tab and then select the driver group that you wish to add this computer too. This process must be repeated for each driver you wish to add to the group.
The second issue that I have is determining what drivers are members of each group. You must look at each driver individually, a task that no one is keen to perform.
To get around these issues I have created a couple of PowerShell scripts, the first will import a set of drivers and add them to a specified group, and the second produces a CSV file listing each driver and the group it belongs to. These are relatively simple scripts but they should show the some of the ability's of PowerShell when managing BDD 2007. For further information on using PowerShell with BDD please refer to Michael Niehaus' blog.
IMPORTANT NOTE - When running PowerShell scripts please ensure that the BDD Workbench is closed.
Import Drivers and add to Driver Group
This script will import all the drivers in a specific folder and then add those drivers to a group. This script first imports all the drivers in the specified folder then it iterates through all the drivers in the driver library and adds any drivers that are a member of of only one group ("All Drivers") too the specified Driver Group. I have made the assumption that all drivers will be a member of the "All Drivers" group and one other group, using this assumption we are able to identify the newly added drivers and add them to the desired group.
Note - If the driver group name or source folder contains spaces then these should be enclosed in single quotes, for example:
powershell .\Import-Drivers.ps1 'C:\Drivers\IBM T60' 'IBM T60'
# //***************************************************************************# // ***** Script Header *****# //# // File: Import-Drivers.ps1# //# // Purpose: Imports Drivers and assigns them to a group# //# // Usage: powershell .\Import-Drivers.ps1 [Drivers Location] [Driver Group]# // Drivers Location – The folder containing the drivers to be imported# // Driver Group - BDD Driver group name. Driver group to which the drivers will be added. - This is case sensitive.# //# // Notes:# //***************************************************************************Param( [string]$DriverLocation, [String]$Group)
[System.Reflection.Assembly]::LoadFile("C:\program files\BDD 2007\bin\Microsoft.BDD.ConfigManager.dll")$manager = [Microsoft.BDD.ConfigManager.Manager]write-host "Driver Location: " $DriverLocationwrite-host "Driver Group: " $Group$dgmgr = $manager::DriverGroupManager$dmgr = $manager::DriverManager
# Refresh the Driver Groups to ensure we can see any new groups$dgmgr.Refresh()
# See if the group exists $dgadd = $dgmgr.Find($Group)if ($dgadd -eq $null){ write-host "Driver Group does not exist, please specify "} else{ $dmgr.Import($DriverLocation) $dmgr.Refresh() foreach ($driver in $dmgr) { # Count the number of gr0ups that this driver is a member of $intcount = 0 foreach ($DriverGroup in $dgmgr) { # Make sure the driver is in the group if ($driverGroup.IsMember($driver["guid"])) { $intcount++ } } if ($intcount -eq 1) { # Make sure the driver is in the group if (-not $dgadd.IsMember($driver["guid"])) { write-host "Adding driver " $driver["name"] " to group " $Group $dgadd.AddMember($driver["guid"]) $dgadd.Update() } } }}
Reporting on Driver Groups
This script simply lists each group and the drivers that are a member of the group in a CSV format. It is very simple but does the job!
# //***************************************************************************# // ***** Script Header ***** # // # // File: DGMembershipReport-csv.ps1 # // # // Purpose: Creates an CSV report on driver group membership # // # // Usage: powershell .\DGMembershipReport-csv.ps1 # // # // Notes: # //***************************************************************************
[System.Reflection.Assembly]::LoadFile("C:\program files\BDD 2007\bin\Microsoft.BDD.ConfigManager.dll") $manager = [Microsoft.BDD.ConfigManager.Manager] $CSVFilePath = ".\DriverGroups.CSV" $strDate = get-date -uformat "%Y/%m/%d" $strOutputString | out-file -filepath $CSVFilePath -encoding ascii
# Create and write CSV to file $strOutputString = "Driver Group Membership Report" $strOutputString | out-file -filepath $CSVFilePath -encoding ascii -append $strOutputString = "Date: " + $strdate $strOutputString | out-file -filepath $CSVFilePath -encoding ascii -append
foreach ($DriverGroup in $manager::DriverGroupManager) { foreach ($driver in $manager::DriverManager) { if ($driverGroup.IsMember($driver["guid"])) { $strOutputString = $driverGroup["Name"] + "," + $driver["Name"] $strOutputString | out-file -filepath $CSVFilePath -encoding ascii -append } } }
Windows Recovery Environment (Windows RE) is a recovery platform based on Windows Preinstallation Environment (Windows PE). Windows RE provides two main functionalities, Automatic diagnosis and repair of boot problems using a tool called Startup Repair and a centralized platform for advanced recovery tools.based on this functionality I think it makes a lot of sense to integrate WinRE into all of your Vista deployments. From the number of questions I have received on the topic it seems like I am not the only one!
So how do we integrate WinRE into the Vista deployment process using BDD 2007?
The first thing I do is I create my WinRE source. There is a good article on the WinRE team blog that explains how to create a WinRE source using the WAIK. Unfortunately adding the Mass storage and network drivers for all the models you want to support can be quite laborious. The obvious question here is “why can’t we just use the BDD driver library?” to do this for us, after all it is used to create the Lite touch WIM. Well thanks to Dave Hornbaker a fellow Microsoft Services consultant you can.
Dave has developed a PowerShell script that automatically creates a WinRE WIM and then injects the drivers that you have already imported into BDD, NICE!
The script must be run on a machine with both BDD and the WAIK installed. The script is attached to this blog and is usage is detailed below:
Powershell .\CreateWinRE.ps1 [Arch] [Group] [–ISO] [–MassStorageDrivers] [–Net] [–system] [–Display] Arch - “x86” or “x64” (“x64” has not been tested) Default is “x86” Group - BDD Driver group name. Driver group to be injected into the image. Default is “All Drivers” -ISO - Create an ISO image Default is to just create a WIM -MassStorageDrivers - Inject Mass Storage Drivers (default) -Net - Inject network drivers (default) -System - Inject system drivers -Display - Inject display drivers
Now we have this fantastic script, run it to create the WinRE WIM the and inject the drivers as required:
Powershell .\CreateWinRE.ps1 –MassStorageDrivers –Net
Now that we have out WIM we can integrate into the BDD deployment process:
Copy the following files to the specified locations:
Now create an application with the following settings:
Next add the application to task scheduler, it is important to note that you should add this to your deployment build not your master image as WinRE will be disabled by sysprep :
NOTE: <Build ID> is the name of the build to edit i.e. DEPLOY-VISTA
The sample script I have provided simply copies the WinRE.wim file to the C drive and enables WinRE. You may want to look at other options such as locating it on a partition with Bitlocker or creating a seperate partition just for WinRE. For more information about the possible configuration options please refer to the WinRE team blog.
When using BDD to deploy and OS one of the first things it does is detect information about the hardware via WMI. As part of this detection process it determines the Chassis Type of the machine. By using this information we can configure the rules to perform different tasks based on the hardware type. For example we could base the computer name of the machine on the hardware type. So for example if the client type is a laptop then the computer could be the letter "L" followed by the computers serial number (also collected via WMI).
The chassis type is identified by the numeric value returned to BDD via a WMI query. These numbers are then matched to specific hardware types , these values and their corresponding hardware types are listed below:
Laptop: 8, 9, 10, 11, 12, 14, 18, 21 Desktop: 3, 4, 5, 6, 7, 15, 16 Server: 23
Laptop: 8, 9, 10, 11, 12, 14, 18, 21
Desktop: 3, 4, 5, 6, 7, 15, 16
Server: 23
This information is returned in the form of a boolean value, so if the chassis type is a laptop then the %IsLaptop% variable will be true.
So with this in mind the following example shows how to name a machine based on the hardware type identified by BDD. I have also included an empty section that could be used if you machine was not a laptop ([Laptop-False]).
[Settings] Priority= ByDesktopType, ByLaptopType,ByServerType, Default [ByDesktopType] Subsection=Desktop-%IsDesktop% [ByLaptopType] Subsection=Laptop-%IsLaptop% [ByServerType] Subsection=Server-%IsServer% [Desktop-True] ComputerName=D-%SerialNumber% [Laptop-True] ComputerName=L-%SerialNumber% [Server-True] ComputerName=S-%SerialNumber% [Laptop-False] [Default]
[Settings]
Priority= ByDesktopType, ByLaptopType,ByServerType, Default
[ByDesktopType]
Subsection=Desktop-%IsDesktop%
[ByLaptopType]
Subsection=Laptop-%IsLaptop%
[ByServerType]
Subsection=Server-%IsServer%
[Desktop-True]
ComputerName=D-%SerialNumber%
[Laptop-True]
ComputerName=L-%SerialNumber%
[Server-True]
ComputerName=S-%SerialNumber%
[Laptop-False]
[Default]
For further information on understanding rule processing please refer to this blog.
When testing BDD in a Lab environment or even some customer sites I find that when I update an OSD package it takes a long time for the package to be distributed to the distribution points. This delay is usually due to the time it takes to compress the WIM image (or the network speed). Compressing the WIM strikes me as pointless as the WIM format is already compressed.
Did you know that you can exclude certain file extension types from being compressed by SMS?
You simply need to update the following registry key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SMS\Compression\DontCompressExts
By default it contains the following extensions:
".cab;.zip;.arj;.rar;.jpg;.jpeg;.wma;.wmv;.mpg;.mpeg;.mov"
So just add the WIM extension:
“cab;.zip;.arj;.rar;.jpg;.jpeg;.wma;.wmv;.mpg;.mpeg;.mov;.wim"
I have found this can make a big difference in lab environments and in those customer sites with overworked SMS servers.
This an extremely simple tip (my favourite type) but hopefully it will save you lots of time.