How do you quickly deploy 50 Windows 2000 Professional desktops loaded with all the necessary application software? While working as a consultant to a large communications company, I faced this challenge and decided to automate the process. I'd done a lot of reading about Windows Script Host (WSH), and the time seemed right to see whether I could make it work for me.
With disk-imaging software, Microsoft's Sysprep utility, and some basic knowledge of WSH scripting, I was able to take the drudgery out of desktop setup and configuration. The process I came up with has four main steps: Create a standard hard disk image, write a script to perform some required setup tasks, prepare the disk image for cloning, and clone the image onto the target workstations. You too can deploy workstations quickly and easily using the procedure and code described here (of course, you'll need to customize the code for your situation).
The Deployment Environment
In my situation, the company network is a mixture of Novell NetWare 4.x servers running in bindery emulation mode and Novell Directory Services (NDS) providing file-and-print services. The Windows NT 4.0 domain provides access to the application servers. The standard desktop OS is Windows 95, but inhouse application developers and administrators were using NT. Microsoft Systems Management Server (SMS) 2.0 and SMS 1.2 provide hardware and software inventory information, automated software distribution, and Help desk remote control.
Then, our Web application developers decided they needed Win2K Pro, so we needed a plan for deploying it. We decided to use our standard method for building a workstation: cloning a disk image onto each workstation.
Create a Hard Disk Image
To clone a workstation, you configure a computer with the desired OS and application software, then create an image of the disk that you can copy to another computer's hard disk. Disk cloning is a fast and efficient way to set up workstations, letting you build and configure a workstation with all its application software in less than 30 minutes.
Several companies make disk-cloning software. I've most often used Symantec Ghost and PowerQuest's Drive Image Pro, but all the products work similarly. You boot the computer to a DOS prompt, then start the disk-imaging software. You can create an image of an entire disk or a single partition and save it to another partition, drive, or network share. You can later restore the saved image to another disk. One feature to look for in disk-cloning software is media spanning, which lets you break up a disk image into smaller pieces. This feature is important if your image is larger than 640MB and you plan to store it on a CD-ROM.
Disk cloning works best in environments with a standard hardware platform. The video card, network adapter, sound cards, and so on should be the same in all the computers and should occupy the same slots. The hard disks don't all need to be the same size, but the disk image you're loading onto a disk must be no larger than the disk. You might need to maintain several different disk images to keep up with your changing hardware, but the fewer images you have to maintain, the better.
To prepare for disk imaging, load Win2K Pro on a representative workstation. Leave the local Administrator password blank and don't join the domain at this time. Install all the application software that a standard workstation should have, and configure the OS and each application.
Spend some time thinking about the OS and application settings that you would usually apply. Remember that the goal is to perform as little manual configuration as possible on each workstation. For example, if your word processing application has shared template directories, configure the directory location. My company was using an NT 4.0 domain as the back end, so I couldn't take advantage of Win2K Group Policy. However, I was able to configure a local policy to run a logoff script to update antivirus definitions.
Clean up the disk before you create the master image. Empty the Recycle Bin. Remove all the temporary files you and the setup process created. Clear the Start menu's Documents list and browser history. Remove all persistent drive mappings you created while loading applications. Run Chkdsk to ensure the disk has no file-system errors, and clear the Application, Security, and System event logs.
Create a 3.5" network boot disk. If you aren't sure how to perform this task, follow the instructions in Steve Ryles, "18 Steps to a TCP/IP Boot Disk," March 2001. Copy your disk-imaging software to another 3.5" disk. Restart the computer by using the network boot disk, then map a drive to a network share that has enough space to store the disk image. When the computer has finished booting, insert the second 3.5" disk and start the disk-imaging software; save the hard disk image to the network drive you just mapped.
After you've created the disk image, you can use a network boot disk to clone workstations directly from the image on the network share. Alternatively, you can burn the image on a CD-ROM and use the CD-ROM to clone workstations. If you follow the CD-ROM approach, you'll need a boot disk with CD-ROM drivers or you'll need to make the CD-ROM with the image on it bootable. Storing the image on a bootable CD-ROM makes workstation cloning fast and easy. You can find information about creating bootable CD-ROMs in the documentation that came with your CD-ROM burner or on the manufacturer's Web site.
Write a FinalSetup.vbs Script
You can use WSH scripting to manipulate the file system, automate desktop applications, manage a Microsoft SQL Server system, and much more. Learning WSH scripting is easy—all you need is a text editor and a computer with WSH installed. The Microsoft Windows Script Technologies Web site (http://msdn.microsoft.com/scripting) has a great deal of information available for download, and the "Related Resources" box lists articles you might find useful.
I used WSH and VBScript to write the FinalSetup.vbs script, which Listing 1 shows. You'll notice that I like a lot of white space and plenty of comments in a script. Comments make a script easier to read and can help you determine what the script does when you open it up months down the road. In many cases, I even retain, but comment out, any debugging code I added when I wrote and tested the script.
FinalSetup.vbs performs the final steps of the setup process before the installer turns a computer over to the end user. The code confirms that the person running the script is logged on as Administrator and that the computer has joined the domain. The script then adds the WEBDEV global group to the Local Administrators group on the computer to enable the Web developers to install software and configure their computers.
The script's first two statements are very important and should be in every script you write. The OPTION EXPLICIT statement requires you to declare variables before you can use them, thus helping you prevent errors in your scripts. Declaring variables is optional in VBScript. However, if you don't use OPTION EXPLICIT, a typo in a variable name will create a new variable. Such an error might be easy to find in a simple script but not in one that contains hundreds of lines. The ON ERROR RESUME NEXT statement prevents your script from stopping if it encounters an error. The purpose of this statement isn't to ignore errors but to let you deal with them gracefully so that they aren't fatal to the script.
FinalSetup.vbs's next section declares variables. You can place all the variables on the same line, separating them with commas, or you can place them on separate lines, as I've done. A variable name must begin with a letter and can have as many as 255 characters. The name can contain letters, numbers, and underscore (_) characters. Using a lowercase one-letter prefix to indicate the type of data (e.g., object, string, integer) stored in the variable is customary.
The next section of the script declares constants, which are similar to variables except that you can't change their values after you declare them. The script uses three constants: GLOBAL_GROUP, LOCAL_GROUP, and DOMAIN.
To perform real work, a script needs to use objects, which have methods (functions that an object performs) and properties (characteristics). Before a script can use an object, it must instantiate (create) the object. Instantiating an object loads it into memory and registers it. In WSH scripting, you use the Wscript.CreateObject() function to instantiate an object. FinalSetup.vbs uses several objects that are built in to WSH.
The next section of FinalSetup.vbs creates two objects: the Network object (Wscript.Network) and the Shell object (Wscript.Shell). The Network object lets the script connect to network resources. The Shell object lets the script run an executable, manipulate the registry, read environmental variables, create shortcuts, and perform several other functions. In each case, the script stores the created object in a variable (oWshNet and oWshShell, respectively) and uses the variable to access the object's methods and properties.
The local Administrator must be logged on to the computer for the script to be able to complete its tasks. To confirm that the user is the local Administrator, the script gets the value of the Username property of the Network object created earlier and stores the value in the sUser variable. The script retrieves the computer name from the Computername property and stores it in the sCompName variable. Then, the script uses the UCASE() function to convert the value of sUser to uppercase and compares the converted value with ADMINISTRATOR. If sUser's value isn't equal to ADMINISTRATOR, the script displays an error message and exits.
When the user is the Administrator, the script continues to the next step, which ensures that the computer has joined the domain. First, the oWshShell.RegRead method reads the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\Winlogon\DomainCache\GONDOR registry subkey and stores the value in the sInDomain variable. Then, the script performs two checks. First, it checks whether sInDomain is null (i.e., whether the registry subkey is empty). If it is, the script displays an error message and exits. Second, the script checks for the fatal error —2147024894, which occurs if the registry subkey doesn't exist, and exits gracefully if the error has occurred. If the registry subkey weren't present and the script didn't include the ON ERROR RESUME NEXT statement that I mentioned earlier, the user would see the error message that Figure 1 shows.
Next, the script adds the NT 4.0 domain global group to the Administrators local group on the computer. For this task, the script first uses Active Directory Service Interfaces (ADSI) to connect to the SAM database on the local computer. The script creates the oGroup object by using ADSI's GetObject() function to bind to ADSI's WinNT provider. After establishing the connection with the WinNT provider, the script uses the oGroup object's IsMember method to verify that the domain global group (GLOBAL_GROUP) is a member of the Administrator local group. If the global group isn't a member of the local group, the value of the sMember variable is FALSE (0) and the script uses the oGroup.Add method to add the global group to the local group. The script rechecks the value of sMember to ensure that it's TRUE (-1), then uses the oWshShell.Popup method to display a status message and continues running after a 5-second pause.
We use SMS, so the last thing the script does is install the SMS client software on the computer. After displaying an informational message, the script uses the oWshNet.MapNetworkDrive method to map the computer's N drive to the SMS server and the oWshShell.Run method to start smsman.exe. When smsman.exe has finished, the script disconnects the network drive and displays a final message.
Prepare the Disk Image
After you've created the master disk image, you use the Sysprep utility to prepare it for duplication. The Sysprep utility comprises three files: sysprep.exe, setupcl.exe, and sysprep.inf. Sysprep.exe prepares the disk for cloning and runs setupcl.exe, which generates a unique SID on the cloned image. You can use the optional sysprep.inf file to automate Sysprep's Mini-Setup Wizard process. During the first boot after cloning, the Mini-Setup Wizard will prompt you for any information sysprep.inf doesn't provide, such as computer name, time zone, and domain membership.
Sysprep also lets you copy a disk image to a computer that has a compatible hardware abstraction layer (HAL) but different hardware from the system that provided the image. The image must contain any drivers not in the C:\winnt\driver cache\i386\driver.cab file, and sysprep.inf's \[UNATTENDED\] section must specify the location of the additional drivers.
You can find a version of Sysprep on the Win2K Pro CD-ROM under \support\tools\deploy.cab, but a newer version is available at the Microsoft Web site at http://www.microsoft.com/windows2000/techinfo/planning/incremental/sysprep11.asp. Download the white paper "Automating Windows 2000 Deployments with Sysprep," and read it before getting started. Appendix B of this white paper contains the commands you need to create sysprep.inf, and "Microsoft Windows 2000 Guide to Unattended Setup" (unattended.doc), in the \deploy.cab folder on the Win2K Pro CD-ROM, provides information about the syntax of the commands.
Listing 2, page 44, shows the sysprep.inf file I created. Let's look at each section and the actions that it tells the Mini-Setup Wizard to perform.
\[Unattended\]. In the \[Unattended\] section, the OemPreInstall = no line indicates that you'll use a cloned disk rather than an unattended setup. OemSkipEula = yes suppresses the display of the End User License Agreement (EULA). KeepPageFile = 0 causes Win2K to regenerate the computer's pagefile to accommodate any difference in RAM between the master computer and the target computer. ExtendOemPartition = 1 extends the system partition to fill the remaining space on the disk. Another option is to expand the partition by an amount you specify in megabytes (e.g., ExtendOemPartition = 75), leaving the unused disk space available for additional partitions. The Extend OemPartition feature works only on NTFS partitions.
A parameter that I didn't use but that's worth mentioning is OemPnPDriversPath, which lets you add drivers not in the C:\winnt\driver cache\i386\driver.cab file. When the Mini-Setup Wizard detects new hardware on the target computer during installation, the wizard searches for the appropriate drivers in the driver.cab file, then, if necessary, in the location that the OemPnPDriversPath parameter specifies.
\[GuiUnattended\]. In the \[GuiUnattended\] section, OemSkipWelcome = 1 suppresses the display of the Welcome screen. AdminPassword = elyod\[ sets the local Administrator password on the computer to the companywide standard password (elyod\[) used for all NT systems. TimeZone = 035 sets the correct time zone for the computer (035 represents Eastern time). The unattended.doc file contains a table of the time zone codes. OemSkipRegional = 1 ensures that you're prompted for any regional information.
\[GuiRunOnce\]. The \[GuiRunOnce\] section causes the system to run commands after the Mini-Setup Wizard finishes by adding them to the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce subkey. In this case, command01 = c:\winnt\system32\finalsetup.vbs runs the script I created to finish the setup process.
\[UserData\]. In the \[UserData\] section, OrgName = "XYZ Communications" sets the company name and FullName = "XYZ User" sets the username. Enclose the names in quotes if they contain spaces, and use the same username for all computers. If you leave these parameters blank, Mini-Setup Wizard prompts the user for the names. Likewise, if the ComputerName parameter is missing (as it is here) or empty, the Mini-Setup Wizard will prompt the user for the name. If you set the ComputerName value to *, the Mini-Setup Wizard will generate a random computer name.
\[Identification\]. In the \[Identification\] section, JoinDomain = GONDOR automatically adds the computer to the NT domain GONDOR. You must supply a username in DomainAdmin = and a password with sufficient rights in DomainAdminPassword = to add computers to the domain. I created the domain user account desktop and gave it the Add Workstations to Domain right.
The sysprep.inf file contains network names and passwords in plain text, which might seem like a big security problem. However, the Mini-Setup Wizard automatically deletes the folder that sysprep.inf resides in on the target computer.
\[Networking\]. In the \[Networking\] section, setting the InstalldefaultComponents = parameter to no causes the Mini-Setup wizard to leave the network stack alone. The master disk image has all the network settings, but if you find that you have machines with different NICs, you can set parameters in this section.
Now that the FinalSetup.vbs script and the Sysprep utility are ready, you need to add them to the master disk image to prepare it for cloning. To add the files to the disk image, you must first copy them to the computer that you used to make the initial disk image, then create a second disk image. I created a batch file named prepsys.bat, which Listing 3 shows, to copy FinalSetup.vbs to the computer's C:\winnt\system32 directory, copy the Sysprep utility and supporting files to the Sysprep directory on the system drive's root, and run the Sysprep utility. When you run Sysprep with the /forceshutdown switch, the computer should shut down automatically. If it doesn't, turn off the power manually when the hard disk light goes out. Don't restart the computer yet.
To make a second image of the computer's disk, insert a network boot disk as before, boot the computer, and connect to the network share. Run the disk-imaging software and create the second disk image, giving it a new name. You'll use the new image to clone workstations. When you load this image on a computer and boot the computer, the image will perform all the setup steps I've discussed. Save the first image in case you need to make changes.
If you do need to modify your master image, load the first master image onto a computer. Make any necessary changes to the configuration or applications, and clean the disk as I instructed earlier. Make any necessary changes to the FinalSetup.vbs script or sysprep.inf file, and use prepsys.bat to copy the script and the Sysprep files to the computer. Prepsys.bat will also run Sysprep to create a new disk image for cloning.
You can modify a disk that you've prepared with the Sysprep utility, but I don't recommend doing so. When you booted the computer for the first time, the Mini-Setup Wizard would run and perform setup tasks. You would then have to "undo" the Mini-Setup Wizard's work before making the modifications you needed. Making a mistake would be too easy.
Clone the Master Image to a Workstation
To clone the second master disk image to a target workstation, you can use one of three methods: Use a network boot disk to boot the workstation, then load the disk image from the network share; use a bootable CD-ROM that contains the image; or use a disk duplicator to copy the master disk to several hard disks at once. You might find that you need to use one method for some workstations and another method for other workstations.
I think the most efficient approach is to use a bootable CD-ROM that contains the disk image. The CD-ROM lets you copy the image to a computer without network connectivity (which the network-share approach requires) and without removing the computer's hard disk (which the disk duplicator requires). The CD-ROM (and disk-duplicator) approach also doesn't consume network bandwidth.
After you've loaded the disk image on the target workstation, restart it. When the computer runs for the first time, Sysprep starts the Mini-Setup Wizard, which prompts the user for any information not in the sysprep.inf file. In my company's case, the computer name was the only information the user had to enter. The operator used the company's standard naming convention to give the computer a unique name based on the end user's name, department, and physical location. The Mini-Setup Wizard also adds an entry to the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce registry subkey. Win2K will run the FinalSetup.vbs script when someone logs on to the computer the first time.
Planning ahead can give network administrators and support staff a painless way to upgrade or reinstall a client's computer in place in minutes. Disk-imaging software, WSH scripting, and Microsoft's Sysprep utility are tools anyone deploying desktops should learn to use. In the time it would take you to install and configure a dozen desktops the old-fashioned way, you could master these new tools.
| MICROSOFT WEB SITES|
Microsoft Windows Script Technologies Web Site
Sysprep Utility Download and Documentation
You can obtain the following articles from Windows 2000 Magazine's Web site at http://www.win2000mag.com.
"Disk-Imaging Solutions," June 15, 2001, InstantDoc ID 20876
Scripting Solutions, "Windows Scripting Host 2.0," December 1999, InstantDoc ID 7530
Scripting Solutions, "Scripting 101, Part 4," September 1999, InstantDoc ID 7112
Scripting Solutions, "Scripting 101, Part 3," August 1999, InstantDoc ID 5683
Scripting Solutions, "Scripting 101, Part 2," July 1999, InstantDoc ID 5505
Scripting Solutions, "Scripting 101," June 1999, InstantDoc ID 5410