I have had recently had a couple of enquires from people having issues with setting multiple keyboard locales.
When setting the “KeyboardLocale” value using a Lite Touch new computer deployment any settings specified in the CustomSettings.ini are being ignored.
To solve this problem, update the KeyboardLocale line in the ZTIGather.xml file to set allow overwrites to true.
<property id="KeyboardLocale" type="string" overwrite="true" description="Locale used for Keyboard, can be either 0409:00000409 or en-US format (default is OS Default)" />
You then need to make sure that you skip the locale selection screen, otherwise it will override any values specified in the customsettings.ini. Here is an example of the rules you will need to skip this screen:
SkipLocaleSelection = YES
UserLocale = en-NZ
SystemLocale = en-NZ
UIlanguage = en-US
KeyboardLocale = 0413:00020409;0413:00000409;0409:00020409;0409:00000409;1409:00001409
When making this change you need to be aware of its effects. This will cause the last value gathered during rule processing to be the one used. So for example if you specify a KeyboardLacale in the database and it is also specified in the Default section then the last section processed will win(normally the first section will win), which usually means the values in the default section will win.
For more information on rule processing see this blog.
I see the same issues coming up over and over again with BDD 2007. So, I decided it was time for my own Top Ten List!
Number 1. - Partitioning within the Unattend.xml
BDD likes (no needs) to look after partitioning itself! Do not do this via Unattend.xml. The most common symptom of this is the Task Sequence not restarting after the operating system has been installed.
Number 2. - XP disk partitioning
Affectionately know as the UBERBUG, this little baby causes some machines to blue screen when an XP image is applied to a machine that has been partitioned with Windows PE 2.0. For more information see my previous blog.
Number 3. - Trying to deploy images with WDS
This is a common misunderstanding about the relationship between BDD and WDS. Let me assure the relationship is not a close one, BDD is just using WDS! Simply put uses WDS as a mechanism to boot the Lite Touch WIM which connects to the BDD deployment point. Once this has happened it has nothing more to WDS, nothing! So my advice here is DO NOT try to load an image captured with BDD into WDS.
Number 4. - Failure to join the domain
Oh the joys of documentation, one little error and everyone has strife. The BDD configuration reference states that "MachineObjectOU=NewYork" , it's wrong! Instead it should say something like this "MachineObjectOU=OU=NewYork,DC=DammTypos,DC=com". So if for some reason your machine fails to join the domain then make sure you have specified the correct OU in the correct manner.
Number 5. - Drivers
Where do I start with this one? This could be a number of blogs on its own, maybe I could use this as a teaser to make you keep coming back and finding more useful information on my blog(did I say that out loud?). I will write a blog(s) on drivers soon.
Number 6. - Creating custom WIM image without using /flags
So you already have a Vista machine built up and you have decided that you want to manually image it . So you capture an image and try to import it into BDD but it won't work. Well the real lesson is you should have used BDD to create and capture the image then you wouldn't of had this problem in the first place. But if you really have no choice then remember to specify the correct flags for the Version of Vista you a capturing. Here is and example command line:
imagex /flags “Enterprise” /capture c: d:\image.wim "Custom Image"
And if you want to add a flag to an image you have already capture try this command line:
imagex /flags [flags value] /info mywim.wim [image index] [new name] [new description]
Number 7. - SQL connectivity
Having trouble connecting to your SQL database well take heed of these four simple rules, and your life will be simpler :
1. Make sure your BDD account has access to the database
2. Ensure that the "surface area" of SQL is opened up enough to allow connections
3. Use named pipes - it makes life easier as you cannot use integrated security with TCP/IP sockets
4. If you have an instance then be sure to specify it when connecting to the DB
Number 8. - Memory requirements for Vista PE
Do random things happen when you try to build some machines? Do you have 256Mb of memory? Well the problem you have is that Windows PE 2.0 can boot with only 256MB of memory but it cannot run. This means that when it tries to do stuff it freezes randomly, NICE! So when building machines make sure you have at least 512Mb of memory and everything will be rosy.
Number 9. - Not removing the MININT folder
Are you testing your build and nothing you do seems to have any effect. Usually this is caused by the fact that BDD is storing information from a previous build in the MININT folder. So commit this to command to memory, your gonna need it:
rd c:\minint /q/s
And while your at it you may as well remember this one:
rd c:\_SMSTaskSequence /q /s
Number 10. - Adding Windows PE to console
Are you trying to add your customized version of Windows PE to the console, yeah the one that you spent hours getting just right! Well its not going to work, the Windows PE source files need to be taken straight off the volume source CD. BDD will then combine this with the OS source files and create a version customized just for BDD.
There may be other common issues I have missed but I thought it is worth while getting these out there. Anyway one day I will create a Top Ten Returns list and I will need something to put in it!
Many people have been having "Fun and Games" when using Windows Preinstallation Environment (Windows PE) 2.0 to create partitions on a hard disk.
They use Windows PE to create a partition which XP is then installed onto, this then results in a "Blue Screen" at first reboot. This issue only occurs with some BIOS's but can be extremely frustrating.
There is now a patch available for this issue:
Windows 2003: http://support.microsoft.com/kb/931761/en-usWindows XP: http://support.microsoft.com/kb/931760/en-us
This patch needs to slimstreamed into your XP source files, and your done!
There is also a workaround for this issue which is detailed in the KB article or if you are using BDD 2007 then take a look at Johan Arwidmark's blog.
Patching XP images is common topic of discussion with many of my customers. When deploying XP should they continuously update their “master” image every time a new patch is released or should they deploy the image without every patch and wait for the machines to be updated automatically via SMS or WSUS?
One of my favourite features of Vista is the ability to patch images offline. This will hopefully mean that the “patching discussion” will be short from now on!!
BDD 2007 leverages this functionality and will patch a Vista client directly after an image is deployed in the Windows PE phase of the deployment. This means that you have a fully patched client when Vista launches for the first time.
Unfortunately for this process to work you will need to update the script that performs the patching process “ztipatches.wsf”. This is due to an a feature that was intended to prevent the addition of the same language pack multiple times.
To fix the problem simply find the following block of code and comment out the line “fLangCanContinue = FALSE”.
fLangCanContinue = TRUE
If not oExistingLang is nothing then
If oExistingLang.Length > 0 then
fLangCanContinue = FALSE
It is also important to know that patches must be converted into a CAB file format before they can be imported into BDD. To do this you simply use the expand command as shown below and then import the expanded CAB file.
Expand patch.msu -F:*.CAB c:\temp
Hopefully with these two tips you will be well on the way to a secure fully patched Vista environment.
UPDATE - 16th June 2007: This fixes detailed in this blog have now been fixed by BDD patch 1. You will find further details here.
NOTE: This process is for Vista only, NOT XP.... sorry.
BDD provides a scripting framework, by leveraging this framework you can write a custom script that can utilize the functionality that BDD provides. This functionality includes a logging, accessing and changing environment variables and a number of utility functions.
Before describing how to create a script it is best to review how the scripts included with BDD are constructed.
The standard BDD script is a WSF file, this allows references to be made to functions that are contained in other scripts. BDD scripts leverage this functionality by referencing a script called “ZTIUtility.vbs”.
ZTIUtility.vbs is used to initialize the BDD environment and setup classes, these can then be used by scripts that reference it.
The script defines a number of standard objects:
Note: You do not need to declare these objects in your script.
Four classes are defined which perform a number of standard tasks:
These classes can be referenced in your scripts, here are some examples for each of the classes:
This class is referenced in scripts through the object “oEnvironment”.
For example you change the computer name to “Blah” using the following command:
oEnvironment.Item("ComputerName") = “Blah”
Or if you needed to determine if this is an x86 or x64 then you could query the architecture using the following command:
This class is referenced in scripts through the object “oLogging”.
When creating a informational log entry use the following command:
oLogging.CreateEntry "Informational message", LogTypeInfo
When creating a error log entry use the following command:
oLogging.CreateEntry "An error occured“,LogTypeError
The class is referenced in scripts through the object “oUtility”.
To determine the name of the the current script, use the following command:
To find the location of a file and BDD use the following command will look in a number of locations for it.
iRetVal = oUtility.FindFile("CustomSettings.ini", sIniFile)
The class is referenced in scripts through the object “oDatabase”. There is generally no need to use the database class directly. Database lookups can be performed using rule processing. See my rule processing blog for more information.
This is a high level view of the tasks that ZTIUtility.vbs can perform. It is worthwhile taking a good look through the script yourself as there are many hidden gems.
Now that we have reviewed the framework lets look at how to write a custom script. I have created a script template below which is based on the structure used within the standard BDD scripts. The template is simply a wrapper that references the ZTIUtility.vbs script and launches the function "ZTIProcess". To create your own script you simply place your code within the ZTIProcess function.
Here is a quick overview of the steps required to add your script to a BDD build:
It is also important to remember the following key rules when creating your script:
Hopefully these tips will get you started, writing your own scripts that leverage the true flexibility of BDD.
Use the following template to create your own custom scripts.
<job id="Z-Sample"><script language="VBScript" src="ZTIUtility.vbs" mce_src="ZTIUtility.vbs"/><script language="VBScript">
' //***************************************************************************' // ***** Script Header *****' //' // Solution: Solution Accelerator for Business Desktop Deployment' // File: Z-Sample.wsf' //' // Purpose: Template' //' // Usage: cscript Z-Sample.wsf [/debug:true]' //' // Customer Build Version: 1.0.0' // Customer Script Version: 1.0.0' // Customer History:' //' // ***** End Header *****' //***************************************************************************
'//----------------------------------------------------------------------------'//'// Global constant and variable declarations'//'//----------------------------------------------------------------------------
'//----------------------------------------------------------------------------'// End declarations'//----------------------------------------------------------------------------
'//----------------------------------------------------------------------------'// Main routine'//----------------------------------------------------------------------------
On Error Resume NextiRetVal = ZTIProcessProcessResults iRetValOn Error Goto 0
'//---------------------------------------------------------------------------'//'// Function: ZTIProcess()'//'// Input: None'// '// Return: Success - 0'// Failure - non-zero'//'// Purpose: Perform main ZTI processing'// '//---------------------------------------------------------------------------Function ZTIProcess()
iRetVal = Success
ZTIProcess = iRetval
'!!!!!!!!!!! INSERT YOUR CODE HERE !!!!!!!!!!!!
When creating your own script to use with BDD it is a good idea to leverage the framework that BDD provides. See my previous blog about how to leverage these functions.
To make this process a little easier on myself I have created the following list which defines the functions that BDD provides, hopefully you will find this as useful as I have.
The first list defines the useful functions that are available via the oUtility object created by ZTIUtility.vbs:
LocalRootPath() – Returns the path of the root folder
LogPath() – Returns the path to the logs folder
ScriptName() – Returns the name of the current script
BootDevice() – Returns the system boot device
StatePath() – Returns the path of the state store, eg C:\MININT\StateStore
ScriptDir() – Returns the directory of the current script
ReadIni(file, section, item) – Reads the specified item from an ini file
WriteIni( file, section, item, myvalue ) – Writes the specified item to an ini file
Sections(file) – Reads the sections in an ini file and stores them in an object
SectionContents(file, section) – Reads the contents of the specified section and stores them in an object
RunWithHeartbeat(sCmd) – Runs command will providing heartbeat information to logs
ComputerName() – Determines the computer name to use for the build process
FindFile(sFilename, sFoundPath) – Returns the location of a file by looking in a number of standard locations
FindMappedDrive(sServerUNC) – Checks to see if a drive is mapped to the specified UNC path and returns the driver letter
ValidateConnection(sServerUNC) – Checks you are connected to the server if not then it will try to connect
MapNetworkDrive(sShare, sDomID, sDomPwd) - Maps a drive letter to the sShare UNC path, returns the drive letter, example: "C:", otherwise returns an error string
VerifyPathExists(strPath) – Verifies if the specified path exists, returns TRUE if path exists
There is also another script that can be referenced for disk utilities, this is called ZTIDiskUtility.vbs. These functions are not class based but can be referenced directly.
GetDiskSize(iDrive) – Returns the size of the specified disk
GetPartitionSize(sDriveLetter) – Returns the size of the specified partition
GetDiskPartitionCount(iDrive) – Returns the number of partitions on a disk, will also log the size of the partitions
GetDiskFreeSpace(iDrive) – Returns the free space available on the specified disk
GetNotActiveDrive() – Returns the active drive
GetBootDrive() – Returns the boot partition
MatchPartitionConfiguration(iDriveIndex, iPartitionIndex, sDriveLetter, iMinSizeMB) - Determine drive status as compared to the custom partition config, return codes are - 0 = Partition exists and meets criteria, 1 = Partition exists and does not meet the criteria, -1= Partition does not exist.
When discussing the use of BDD 2007 with partners I like to introduce the concept of "hydration".
Desktop deployment projects tend to be very similar between customers. The desktop master images tend to contain the same roughly the same set of applications, such as Office, Acrobat Reader and perhaps some plug-ins. On top of these applications partners tend to perform the same set of "tweaks" across all customers. Once the standard stuff has been completed they then tend to add a few customer specific applications and tweaks.
In general the number of tasks to create a master image usually numbers at least 30. Setting up BDD to perform all these tasks can be quite time consuming and prone to errors due to typos or perhaps adding things in the wrong order.
To help alleviate these issues I suggest implementing a hydration process. Here are the steps to create this process:
Setup the De-Hydrated environment.
1. Setup BDD in a lab environment, configure BDD with all the standard settings you would normally use at a client site.
2. Once you are happy with your configuration simply remove product keys and any customer specific media (e.g. OS source files).
3. Make a copy of the BDD Distribution folder.
You now have a de-hydrated BDD installation.
When you arrive at a new customers site you can simply copy the de-hydrated distribution folder over the customers distribution folder, and perform a few tweaks and you have a fully configured BDD, FAST. Here are the steps to rehydrate your BDD installation.
1. Install BDD 2007 and the Window Automated Installation Kit (WAIK)
2. Create a lab distribution point.
3. Copy the files from your dehydrated distribution point over your newly created distribution point.
You then need to “re-hydrate” BDD with the customer specific settings, these include:
4. Update the bootstrap.ini and Customsettings.ini with the correct server values for the customer
5. Update the OS source files with the customers source files (Vista, office etc)
6. Update product keys with the customers keys
7. Add any customer specific applications into your build
Now you have a fully customized BDD installation. This process should save heaps of time setting up BDD at each customer, not to mention avoiding some of the tedious tasks around setting up builds. It also has the advantage of creating consistency across customer sites which makes everyone’s life much easier.
For all of you who want to further understand the inner workings of BDD 2007, the source code is now available!
You will find it here:http://www.microsoft.com/downloads/details.aspx?FamilyID=6a67f884-d629-4962-bd0a-c51bad560354&displaylang=en
This means that you can make modifications, enhancements or perhaps even fix bugs!!If you feel the urge to make changes to the source code for your own use be aware that you may need to reengineer these changes when upgrading to the next version of BDD.
Anyway I know some folks have been waiting for this for a while, so go and have a play with it at least.
The code has been released under the Microsoft Permissive Use license.
The User State Migration Tool has updated to address two issues:
1. You can now install USMT on computers that are running non-English versions of Windows Vista
2. Some settings for local accounts were not being migrated, this has been addressed
If you are using USMT with BDD you will need to use the CAB file workaround described in the BDD 2007 release notes. This essentially means that you will need to manually download he USMT files, build a CAB file using the process described in the release notes, then use that CAB file with BDD.
The new version is 3.0.1 and you can download it here: