In Reader to Reader, March 2001, InstantDoc ID 19831, Stephen Kiss provided the Backup.vbs script, which automates backups by running the Windows NT Server 4.0 NTBackup utility. However, Backup.vbs doesn't work on Windows 2000 and later. Inspired by Backup.vbs, I created the BackXP.vbs script, which you run from a command line and which automates a daily backup of a Windows XP client to a tape drive by executing the ntbackup.exe and rsm.exe Windows utilities. I also created the DFSRootBackup.vbs script, which uses the Dfscmd utility (dfscmd.exe) to produce a batch script that restores your Dfs roots. These two examples demonstrate how you can use scripting and Windows Script Host (WSH) to enhance your control over built-in and third-party Windows utilities.
To use BackXP.vbs, you need to perform two preliminary tasks. First, you must create a backup selection script (.bks) file, which contains a list of folders and files that you want to back up. The .bks file is simply a text file that stores directory paths to back up, one line at a time. For example, if you want to back up the entire contents of drives C, D, and F, your .bks file should contain the following lines:
If you want to back up only certain directories, the .bks file will look something like this:
Although you can create the .bks file manually, it's easier to do so by using the GUI version of NTBackup to schedule a backup job. There are several ways to run NTBackup, one of which is to select Start, Run. Then, type
in the Run dialog box and click OK.
To create the .bks file, you run NTBackup in Advanced (not wizard) mode, select the Backup tab, and select all the check boxes for the paths that you want to back up. Then, click either Job, Save Selections or Job, Save Selections As to create a .bks file that contains the paths you've chosen to back up.
Your second preliminary task is to use NTBackup to format and label all the backup tapes you'll use. To format the tapes, on NTBackup's Backup tab, click Tools, MediaTools. Label your backup tapes sequentially (e.g., Day One, Day Two, Day Three).
How BackXP.vbs Works
Now that you've taken care of the preliminaries, let's examine BackXP.vbs. The heart of BackXP.vbs is a Select Case statement, which the code at callout A in Listing 1 shows. The Select Case statement identifies the backup tape to use on the current day by checking for seven cases, each of which corresponds to a day of the week. The Select Case statement begins with the passing of two parameters to the DatePart function: the current date on which the script is run, which the script obtains through the Date function, and the w parameter, which tells the DatePart function to return a value from 1 to 7 that corresponds to the day of the week (1 means Sunday, 2 means Monday, and so on). The Select Case statement assigns the predetermined tape names based on the value and day of the week that DatePart returns. As long as you've inserted the correct tape into the tape drive each day before the script runs, BackXP.vbs should execute properly.
The five strParam variables contain some standard NTBackup parameters that you can apply to a backup in your own environment. (NTBackup's Help lists these and other parameters.) The /j parameter uses the Now function to return the job name for the backup log file, including the weekday string and the current date and time. The /t and /n parameters specify the existing tape name and the new tape name, respectively. I use the same values for the tape name to ensure that I overwrite only the same tape name each week; any other tape in the drive will cause the backup job to fail. This is just a small failsafe in case I put the wrong tape in the drive. The /d parameter specifies the job's description.
The strParam5 variable includes six parameters. The /v parameter indicates whether NTBackup should verify the backup. You can specify yes or no; you typically specify yes, assuming you check the backup logs daily for errors. You use the /r parameter to indicate whether only administrators are permitted to access the data on the tape. Like the /v parameter, the /r parameter options are yes and no. The /l parameter is the type of log file. You can specify f (full), s (summary), or n (none). The /m parameter indicates the backup type. You can specify normal (full backup, which is the default), copy (full backup, except the archive bits aren't cleared), differential (backup that copies files created or changed since the last full or incremental backup), incremental (similar to a differential backup, except the archive bits are cleared), or daily (which copies only files that have changed that day and doesn't clear the archive bits). The /rs parameter tells NTBackup whether (specify yes) or not (specify no) to back up the removable storage database. Setting the /hc parameter to on enables hardware compression if it's available. Setting this parameter to off disables it.
Next, BackXP.vbs builds two commands to execute. The strCmd variable contains the command to run the complete NTBackup command with all its parameters. The strRSMCmd variable contains the rsm.exe command that will eject the backup medium after the backup has completed.
The script executes the NTBackup command by using the WshShell object's Run method, as the code at callout B shows. The Run method's SHOW_WINDOW parameter tells the script to display a window that shows the backup is taking place. The Run method's WAIT_ON_RETURN parameter tells the script to pause execution until NTBackup has finished its work. When NTBackup completes successfully, it returns a value of 0; otherwise, it returns a nonzero value. The script stores the returned value in the intResult variable.
When intResult contains a value of 0, the script interacts directly with the tape device and ejects the backup tape. To accomplish this interaction, I use a little-known command-line utility called the Removable Storage Manager (RSM) utility (rsm.exe). Designed for use with tape autoloaders, this utility tracks tape usage, ensuring that the autoloader inserts the correct tape into the streamer before a scheduled backup commences. (For more information about rsm.exe, search on rsm in XP's Help file.) The strRSMCmd variable stores the call to rsm.exe. The call requests an eject of the medium, specifies a physical filename (the /pf parameter) that matches the strWeekday variable, and specifies that the tape eject should start immediately (the /astart parameter).
You'll need to customize BackXP.vbs for your own use. First, you must change the strParam1 through strParam5 lines to match your own backup requirements. You can obtain the complete list of NTBackup parameters by clicking Start, Help and Support and searching for NTBackup. You must also modify the BACKUP_FILE_PATH constant so that it contains the path to your .bks file; this path must have the at (@) symbol as the first character.
Restoring Dfs Roots Through a Script
Dfs, which came of age with Win2K, is a strategic storage management solution that gives administrators a more flexible way to centrally manage their distributed resources. With Dfs, administrators can create simplified views of folders and files--that is, a virtual organization called a namespace--regardless of where those files physically reside in a network. Administrators can use Dfs to automatically replicate entire namespaces across multiple physical locations, thereby letting users access the resources on a network closest to them and providing fault tolerance should a node become unavailable. (For more information about Dfs, see http://www.microsoft.com/windowsserver2003/techinfo/overview/dfs.mspx.)
Windows Server 2003, XP, and Win2K Server include Dfscmd, a root-management tool that lets you manage Dfs from the command line. If Dfscmd isn't installed by default, you can either install it from the Support Tools folder or download it from the Microsoft site. (The Win2K download site is http://www.microsoft.com/windows2000/downloads/servicepacks/SP4/supporttools.asp.) For more information about dfscmd.exe, see http://www.microsoft.com/windowsxp/home/using/productdoc/en/default.asp?url=/windowsxp/home/using/productdoc/en/dfscmd.asp.
The DFSRootBackup.vbs script, which Listing 2 shows, iterates through a series of four servers (Alpha, Beta, Charlie, and Delta) and executes Dfscmd to create a batch script that you can use to restore each server's Dfs root folder. You place the batch script on a separate server; the batch script logs its results in that server's Application event log at key points.
Let's look at DFSRootBackup.vbs in more detail. The first constant I declare--DFS_DEST_PATH--should be customized for your own environment. DFS_DEST_PATH is a Universal Naming Convention (UNC) path to a share that I created on a fifth server called Echo. Alpha, Beta, Charlie, and Delta are the servers that host Dfs root folders. Echo will contain the backups of these folders.
The second and third constants contribute to a command that the script will create, which will look something like this:
"\\Echo\DFSBackup Alpha DFS Batch Script.txt"
(The command wraps to several lines here because of space constraints.) This command uses the /view parameter to retrieve details for the specified Dfs root folder (on server Alpha, in this case) and the /batch parameter to then return a batch script that you can use to restore the root folder. The command places the batch script on server Echo in the designated file. The CMD_PART1, CMD_PART2, and LOGFILE constants represent parts of the dfscmd.exe command that don't contain the specific server name (e.g., Alpha). You can change the name of the DFSRoot folder in CMD_PART2 and the text in LOGFILE to suit your needs. After declaring some familiar constants and variables, I declare the server array. Scripting provides many ways to store (or even dynamically generate) a list of servers. I decided to use VBScript's Array function because it's an easy way to generate an array of server names representing those servers that have a Dfs root.
After the declarations, the script writes an entry in the Application event log on the client running the script, telling the log either that the script has started successfully or had errors. The For...Next statement iterates through the recently created server array. The same actions happen within each iteration. First, the FileSystemObject object's FileExists method checks whether the new log file--which represents the batch script--exists. When the file exists, the FileSystemObject object's DeleteFile method deletes it. Next, the strDFSCmd variable holds the dfscmd.exe command, which is immediately passed to the WshShell object's Run method. Script execution pauses until the command completes. Depending on the value that dfscmd.exe returns (0 means success; 1 means failure), the script writes a success or failure message to the Application event log.
To be absolutely sure that the resulting batch script contains no errors, the code needs to scan the event-log file for the word error. One way to accomplish this would be to use the FileSystemObject object's ReadAll method to read the entire file. However, this method wastes memory resources for large files. Instead, I use a simple line-reading loop, which adds each line in the log file to a long text string. Next, the InStr function determines whether the word error is contained in the file, then writes to the event log a failure or success message, depending on whether the line-reading loop found an error. Then, the next iteration of the loop starts to read the next line of the file and check for the word error. After the last line of the file is read and checked for the word error, the LogEvent method logs a success event in the Application event log to indicate that the script has finished.
BackXP.vbs and DFSRootBackup.vbs demonstrate some simple methods you can use to add flexibility to built-in Windows utilities, and you can easily customize these scripts to fit your backup environment. (For an enhanced version of BackXP.vbs, see the Web-exclusive sidebar "Enhancing BackXP.vbs".) In addition, you can apply these techniques to other Windows utilities. For example, you can apply these techniques to update values in Active Directory (AD), DNS, or other system configuration settings.