Service pack deployment has been the bane of many systems administrators since the early days of Windows NT 3.5. Deploying service packs in Windows 2000 is no exception, especially for those administrators in enterprises with numerous machines. Administrators often solve the dilemma of having to install multiple service packs or other software packages by spending lots of time and money evaluating and purchasing third-party products. However, some administrators might not have the time to evaluate and compare the effectiveness of third-party products or have the financial resources to purchase a suite of utilities.

Although Win2K's Active Directory (AD) provides the Group Policy feature, which administrators can use to deploy service packs and other software packages, some enterprises, such as my company, choose not to implement AD. So, when I had to deploy Service Pack 2 (SP2) on many Win2K machines, I checked whether Microsoft had any service pack deployment tools. According to our technical account manager, no such tools were available, and the third-party products that I evaluated were either too costly or too complex for my simple needs. Frustrated, I gave up my search and endeavored to create a script that reliably and consistently deploys SP2 on remote Win2K machines.

The result is ServicePack2Deploy.bat. This script initiates a silent, remote install of SP2 from an administrator's workstation. The script works on Win2K Server, Win2K Advanced Server, and Win2K Professional machines running SP1. To use ServicePack2Deploy.bat in your environment, you need to prepare for its deployment, understand how the script works, customize the script, and know how to launch it.

Preparing for Deployment
Installing software remotely from the command line might be new territory for some administrators. You'll need access to a command line on the remote machine. You can use Telnet, Secure Shell (SSH), the Microsoft Windows 2000 Server Resource Kit's Remote Command Service, or some other method to access the command line. I needed a simple utility that I could execute from my workstation and that wouldn't require a lot of front-end work (e.g., installing agents or software on the remote machines). Sysinternals' PsExec filled my needs nicely. You can obtain this freeware from the Sysinternals Web site ( To use ServicePack2Deploy.bat, you need PsExec 1.21 or later.

Besides PsExec, ServicePack2Deploy.bat uses three other utilities: SP2's update.exe and the resource kit's netsvc.exe and sc.exe. The script uses update.exe to install SP2. You can download the SP2 files, which include update.exe, from the Microsoft Windows 2000 Downloads Web site (

To install a service pack on a Win2K machine, you must be running the Print Spooler service on the target remote machine. According to the Microsoft article "Update.exe Cannot Start If the Spooler Service Is Disabled"(, this behavior is by design. The netsvc .exe and sc.exe utilities help ensure that the Print Spooler service is running, as I explain later.

I recommend that you keep all the SP2 files and utilities on a network share that's visible from the remote machines on which you want to install SP2 and from the workstation on which you plan to run ServicePack2 Deploy.bat. When you keep the SP2 files and utilities in a central location, every administrator has access to the same set of files and utilities, which helps ensure the script's repeatable and reproducible outcome. Although you can store and run the utilities locally, you could encounter problems if different machines have different versions of the utilities. I keep the SP2 files and utilities on a file server. PsExec, netsvc.exe, and sc.exe are in a directory called utils.

After obtaining SP2 and the utilities and placing them on a network share, you need to create the necessary user credentials to access those files. My company has an isolated production domain that contains a mix of Win2K and NT 4.0 machines. This setup is popular because it lets administrators use an administrative domain user account to easily manage their servers. However, when I initially tried to run ServicePack2Deploy.bat on a remote server in that environment, I ran into a snag. By design, the remote server was unable to use my credentials to retrieve the SP2 files and utilities on the file server. You'll likely run into similar problems in your environment. To work around this problem, you need to create a local user account on the file server and give the user account Read & Execute permission to access the file server from the network. Don't create a domain user account, because you need to hard-code the username and password in the script. Using a local account that has Read & Execute permission to only one file server minimizes security risks. (If you're the cautious type, you might want to modify the script to call an encrypted text file that contains the user account information.)

Understanding How the Script Works
ServicePack2Deploy.bat might not be the most elegant solution, but it works well. Here's how the script works:

  1. The script verifies that the target remote machine is running an NT-based OS. This script doesn't differentiate between Win2K and NT 4.0 or earlier. However, the script is only for Win2K machines. If you run this script against machines running NT 4.0 or earlier, you'll get undesirable results. If you try to use this script with a machine that's running Windows Me, Windows 9x, or another non-NT OS, the script exits.

  2. The script determines the date and time, which it uses for logging purposes.

  3. The script sets the variables specific to your environment. If you have to include the same environment-specific information often in a script, putting that information in variables is more efficient than hard-cording it because you have to specify the information only once.

  4. The script determines whether the Print Spooler service is running on the target remote machine. As Listing 1 shows, the script uses netsvc.exe within a For command to make this determination. Running netsvc.exe with the /query switch prompts the utility to check the status of the specified service (in this case, spooler, which represents the Print Spooler service) on the specified machine (in this case, \\%1, the variable that represents the target remote machine). If you're unfamiliar with argument-holding variables such as %1, see Dick Lewis, "Shell Scripting 101, Lesson 3," http://www.winscriptingsolutions .com, InstantDoc ID 20142. The For command parses the utility's results for two key words: running and stopped. If the results contain the word running, the script proceeds to install SP2. If the results contain the word stopped, the script prompts you to start the Print Spooler service, then exits.
  5. To start the service remotely, open a command shell window and run the command

    netsvc.exe spooler \\Machine /start

    where Machine is the name of the target remote machine. The /start switch tells netsvc.exe to start the Print Spooler service. If you receive an error message, the Print Spooler service is probably disabled on that machine. To enable the service remotely, you use sc.exe. In the current command shell window, type the following command all on one line, with one space between config and spooler:

    sc.exe \\Machine config
       spooler start= demand

    Then, run netsvc.exe with the /start switch again:

    netsvc.exe spooler \\Machine /start

    Figure 1 shows sample output from successfully running these two commands. After the Print Spooler service is running, you can again launch the script for the remote machine, and the script will perform Steps 1 through 4 again. This time, the Print Spooler service will be running, so the script proceeds to Step 5.

  6. The script dynamically creates the file SP2Inst.cmd to be run on the target remote machine. SP2Inst.cmd deletes any existing remote connections on the target machine, logs on to the file server with the local user account credentials you created, then runs update.exe, which installs SP2 on the target machine.

  7. Listing 2 shows how ServicePack2 Deploy.bat creates SP2Inst.cmd. Service Pack2Deploy.bat uses the Echo command with the > and >> redirection symbols to write the necessary code in SP2Inst.cmd. (If you're unfamiliar with redirection symbols, see Dick Lewis, "Shell Scripting 101, Lesson 4," http://, InstantDoc ID 20530.) Callout A in Listing 2 highlights the code that installs SP2. The code uses update.exe with the ­q and ­f switches. As Figure 2 shows, the ­q switch runs update .exe in quiet mode and the ­f switch forces other applications to close when the utility shuts down the machine for a reboot. Listing 3 shows an example of what the resulting SP2Inst.cmd file looks like.

  8. The script creates an error log on the administrator's local workstation in the C:\temp directory. If C:\temp doesn't exist, the script creates it.

  9. PsExec copies SP2Inst.cmd to the target server and executes it.

Customizing the Script
I've tested ServicePack2Deploy.bat on Win2K Server, Win2K AS, and Win2K Pro machines running SP1. You can find ServicePack2Deploy.bat in the Code Library on the Windows Scripting Solutions Web site ( To use this script, you must have some form of basic network connectivity to the servers for which you're responsible. If your environment contains a firewall between the file server and the remote server, the script might fail to execute correctly. To verify your ability to establish a Universal Naming Convention (UNC) connection from the target server to the file server, you can map a drive from the target server to the file server with the local user account you created earlier. Most standard networking errors appear in the log, which helps with troubleshooting. A good source for looking up error messages is the Win2K Search Support Web site (

Before you can run ServicePack2 Deploy.bat, you need to modify several lines of code. In the :START section, you need to modify the code that Listing 4, page 4, shows. Follow these steps:

  1. Customize the date and time format, if desired. The script uses the DTStamp variable to record the date and time when logging its results. Currently, the script logs the date and time following the format YearMonthDay-HourMinute. You can modify the format by changing the order of the %Year%, %Month%, %Day%, %Hour%, and %Min% variables.

  2. Customize the names of the file server and share. In the code that sets the SPServer variable, specify the names of the file server and share that contain the SP2 files. Don't include the beginning double backslashes (\\); the script will put them in for you.

  3. Customize the directory that contains update.exe. In the code that sets the SPPath variable, specify the directory. For example, if update.exe is in \\fileserver\sharename\w2ksp2\i386\update, set SPPath to w2ksp2\i386\ update. If you've already decompressed SP2, copy it to a subdirectory inside the share and specify that subdirectory.

  4. Customize the working directory, if desired. Currently, the script works and creates the log in C:\temp. You can keep this directory or change it.

  5. Customize the log's filename and location, if desired. Currently, the script creates a log whose filename consists of the date and time (%DT Stamp%), the name of the target remote machine (%1), and the service pack number (sp2). Underscores (_) separate each element. For example, if you run the script on February 23, 2002, at 5:14 p.m. to install SP2 on server3, the script produces the log named 20020223-514p_server3_sp2.log. You can keep this naming convention or change it. You can also keep or change the location of the log. Currently, the script creates the log in C:\temp.

  6. Customize the .cmd file's name, if desired. The script names this file SP2Inst.cmd. You can keep or change this filename.

  7. Customize the file-server name, username, and password. When you were preparing for the deployment of ServicePack2Deploy.bat, you created a local user account on the file server. In the code that sets the User variable, specify the name of the file server and user by following the format fileserver\user. In the code that sets the Pass variable, specify the password. Incorrect user account information results in Error 53.

  8. Customize the path to PsExec. If you followed the recommended practice of placing the PsExec utility on a file server, you need to customize the code that sets the PsExecPath variable. In this code, specify the path to PsExec by changing the directory name at the end of the path (i.e., change utils to the name of your directory).

If you placed PsExec on your local machine, you need to comment out the code that sets the PsExecPath variable. In addition, you need to customize some code in the :NEXT section. Listing 5 shows this code and provides instructions on how to customize it.

Launching the Script
Before you run any script that adds new software to your production servers, you need to thoroughly test the software and the script. After you test ServicePack2Deploy.bat and SP2 in your environment, you're ready to run the script. Open a command shell window, drag the script onto the window, and press the space bar. After the name of the script, insert the name of the target remote machine on which you want to install SP2. For example, as Figure 3 shows, I've entered server3. Finally, press Enter. If you inadvertently press Enter before inserting a machine name, you'll receive the script's syntax. Typing a question mark (?), the /? switch, or the word help after the script's name also provides the script's syntax.

The SP2 install process typically takes about 15 minutes, but that time might vary depending on the speed of your hardware. I designed the script to run in silent mode, so don't close the command shell window if you don't see any immediate feedback. After the script finishes and the remote machine reboots, the command shell window closes automatically. Update.exe has an option that lets you uninstall the service pack should you encounter problems with the SP2 installation.

Save Time and Money
With ServicePack2Deploy.bat, you don't need to spend lots of time and money to install SP2 in a large enterprise that has many Win2K machines. Because the script uses utilities that are free or in the resource kit, you don't need to buy costly programs. Because the script is easy to customize and use, you don't need to spend lots of time deploying SP2 in your environment.