I'm using the Windows Script Host (WSH) WshShell object's Run method to run a batch file, and I've stumbled across a problem with the Run method. Listing 3 contains a simplified version of my script, and Listing 4 contains a test batch file. The problem occurs with the argument R&D (which is the name of an organizational unit—OU) that I'm passing to the batch file. For some reason that I don't understand, the Run method doesn't like the ampersand (&) in the OU's name. When I run my script, I receive the error message 'D' is not recognized as an internal or external command, operable program or batch file. Is this a bug, or am I doing something wrong?
The behavior you're seeing isn't a bug. The WshShell object's Run method retrieves the command and any arguments you provide as parameters (e.g., R&D) and hands them to the OS to run. The Run method doesn't perform any preprocessing of the command or the arguments. You can verify that WSH isn't the problem by taking WSH out of the picture. For example, if you use the command
to run your batch file, you'll obtain the same error message. The ampersand is causing the error because the ampersand is one of the command processor's reserved characters. The ampersand lets you construct, on one command line, compound-command statements that can run multiple commands. For example, the following compound-command statement uses the ampersand to run ipconfig.exe twice:
The first invocation of ipconfig.exe displays basic IP configuration information, and the second invocation displays the contents of the DNS resolver cache.
When working at the command line or with batch files, you must take one of two actions when you use strings that contain an ampersand. Either you must escape the ampersand by using the caret (^) symbol, or you must enclose the string inside quotation marks.
Enclosing the string inside quotation marks adds the burden of removing the quotation marks inside the batch file, so let's look at how to use the escape character—the caret symbol—to escape the ampersand. Admittedly, escaping characters can get a little confusing when a batch file is involved, so let's start with a simple command, such as the Echo command.
Suppose you want to use the command processor's built-in Echo command to send, or echo, the string R&D to the console:
This command results in the error that you've seen because the command processor interprets the command as echo R and run D. Because D isn't recognized as a valid command, an error occurs. If you escape the ampersand in the command
C:\Scripts> echo R^&D
the command processor interprets the ampersand as part of the argument instead of interpreting it as the compound-command symbol. The result is that the command processor echoes the string R&D to the console.
Batch files complicate escaping command-line arguments because the argument is interpreted multiple times: first when the argument is read into %1 and again when the argument is used inside the batch file. To fully understand what I mean, let's revisit the example
C:\Scripts> Listing4.bat R&D
You already know that this command produces an error. So, how do you fix it? Adding an escape character to the command
doesn't do the trick because, unlike the string R&D in the Echo command, the batch-file argument R&D is interpreted first by the batch file and again when the argument is used by a command inside the batch file. Consequently, you need to add an extra escape character when you work with batch files that take command-line arguments containing special symbols. In addition, because the escape character is also a special symbol, you must escape the escape character. The following example demonstrates the correct way to pass a batch file an argument that contains one of the command processor's reserved characters:
If you run Listing4.bat as shown, the batch file does what you expect, as Figure 1 shows.
So, how do you fix your script in Listing 3? Simply insert three carets immediately before the ampersand in the OU name, as Listing 5 shows.