Hey, Scripting Guy! I am trying to write a script that requests multiple pieces of information from a user; I then want to call a batch file, using each piece of information as a separate command-line argument. Unfortunately, though, I can’t get this to work correctly. Can you help?
Hey, BP. You know, at first we was not going to help, but then we have second thoughts and decide to help if could.
Oh, in case you’re wondering, the Scripting Editor is on vacation this week, which means we can write things any way we dang well please. Grammar? We don’t need no stinkin’ grammar. As the French philosopher Michel de Montaigne so aptly put it, “The greater part of the world's troubles are due to questions of grammar.” As for spelling, well, who even cares about korrect speling anyway? We’ll do the best we can, but we’re with A. A. Milne when it comes to spelling: our spelling is “…Wobbly. It's good spelling but it Wobbles, and the letters get in the wrong places.”
Wee here you, A. A. We hear ewe.
Note. A. A. Milne, of course, is the creator of the immortal Winnie the Pooh, a bear of very little brain. (And no, that doesn’t mean that Winnie the Pooh must be the true identity of the Scripting Guy who writes this column.) Michel de Montaigne was (and still is, we suppose) a 16th-century French writer and philosopher. After Montaigne was born his father decided that the boy must learn Latin as his first language; to make sure that happened, Dad only hired servants who could speak Latin, and everyone in the household was put under strict orders to speak Latin – and Latin only – to young Michel. Of course, this pedagogical approach paid enormous dividends; later in life Montaigne came up with such insightful bits of wisdom as “When I play with my cat, how do I know that she is not passing time with me rather than I with her?“
Or, in Latin, “Ut EGO lascivio per meus cattus , quam operor EGO teneo ut is est non obduco vicis me quinymo quam EGO per suus?”
There’s also one other advantage to the Scripting Editor being on vacation: after all, she not only insists on correct spelling and correct grammar, but she also absolutely refuses to let us answer questions about passing command-line arguments to a batch file. Why? Who knows? Maybe her parents decided that “grouchy” should be the first language she learned.
Note. If so, mission accomplished!
But while the cat’s away, the mice will answer questions about passing command-line arguments to a batch file. Or at least we’ll answer one question about passing command-line arguments to a batch file. And if we use poor grammar when doing so, well, then us you can sue.
Before showing you some code let’s take a minute to explain the scenario, and the problem BP has run into. BP has written a script that solicits two pieces of information from a user: a user name and a computer name. He then wants to take those two pieces of information and use them as command-line arguments for a batch file named Namechange.bat. In order to test the script, he created a simple little batch file that does nothing more than echo back the two arguments he supplied:
echo %1 echo %2 pause
That’s great. However, suppose BP enters kenmyer as the user name and atl-ws-001 as the computer name. Here’s what he gets when he runs the batch file:
C:\scripts>echo kenmyeratl-ws-001 kenmyeratl-ws-001
Uh-oh. As you can see, the batch file doesn’t think we sent it two command-line arguments; instead, it thinks we only provided a single command line argument: kenmyeratl-ws-001. Needless to say, that’s no good, no good at all.
Or, seeing as how the Scripting Editor isn’t around to correct us, that ain’t a-gonna do you no good, no good a’tall.
Or, even better: that does you about as much good as a screen door on a submarine.
Note. Which, by the way, isn’t really all that much good.
So what’s the problem? As it turns out, the problem lies in the way we call the batch file. BP was calling the batch file using a command similar to this:
objShell.Run "C:\Scripts\Namechange.bat " &strUser &strComputer
That’s a valid line of code, but what it does is create a command that, under the covers, looks like this:
As you can see, the two command-line arguments have been scrunched together into a single argument. Why? Because we didn’t specify that a blank space should appear between the two arguments. Granted, in the code itself there is a blank space between &strUser and &strComputer. However, that blank space doesn’t appear when you concatenate the string values. If we wanted to, we could put a ton of blank spaces between the two variable names, like so:
Now, guess how many blank spaces are going to appear between the two command-line arguments. You got it: 0.
Fortunately, this is a very easy problem to fix. All we have to do is “manually” insert a blank space between the two command-line arguments, like we did in this script:
strUser = InputBox("Enter user name:", "RT Remote System Rename") strComputer = InputBox("Enter new computer name:", "RT Remote System Rename") strCommand = "C:\Scripts\Namechange.bat " & strUser & " " & strComputer Set objShell = CreateObject("WScript.Shell") objShell.Run strCommand
Let’s see if we can explain how this works. In the first two lines, we’re simply using BP’s two calls to the InputBox function, one call to retrieve the user name and a second call to retrieve the computer name. That part should be pretty straightforward.
For that matter, this part should be pretty straightforward, too:
strCommand = "C:\Scripts\Namechange.bat " & strUser & " " & strComputer
All we’re doing here is constructing the command that starts the batch file, then storing that command in a variable named strCommand. Notice that, this time around, our command combines four items:
C:\Scripts\Namechange.bat , the path to the batch file. Note that, like BP, we were careful to include a blank space following the path name? Why? Because if we left that blank space out then our command line arguments would run smack dab into the path name, like so: C:\Scripts\Namechange.batkenmyer atl-ws-001. BP was right to include a blank space after the path name; he just didn’t realize that he needed one between the two command-line arguments as well.
strUser, the variable containing the first command-line argument.
" ", a blank space.
strComputer, the variable containing the second command-line argument.
Put them all together and they spell MOTHER.
Oh, wait; sorry. Put them all together and they spell this:
C:\Scripts\Namechange.bat kenmyer atl-ws-001
Which is way more like it.
Incidentally, we didn’t have to store this command in a variable. Like BP, we could have directly called this command from within the script:
objShell.Run "C:\Scripts\Namechange.bat " & strUser & " " & strComputer
So why didn’t we directly call the command from within the script? Mainly for debugging and troubleshooting purposes. As BP discovered, it’s not hard to determine that the script isn’t working correctly; what’s hard is determining why the script isn’t working correctly. We know the batch file didn’t realize we were sending it to command-line arguments, but we have no idea why the batch file didn’t realize that.
So how does storing our command in a variable help us troubleshoot problems with the script? That’s easy. With BP’s original script we never get to see the command that actually calls the batch file. With our script, however, we can easily view the command that actually calls the batch file; all we have to do is echo back the value of strCommand. Suppose we took BP’s original script and stored his original batch file command in a variable. Now suppose we decide to echo back the value of that variable before we actually try calling the batch file. If we do that we’ll see the following:
Right then and there we know we have a problem. More important, we also know exactly what the problem is: no blank space between the command-line arguments. Armed with that information, we have a pretty good chance of being able to fix the script.
Once we’ve created our command we can then call the batch file using these two lines of code:
Set objShell = CreateObject("WScript.Shell") objShell.Run strCommand
As you can see, there’s nothing very fancy going on here: all we’re doing is creating an instance of the Wscript.Shell object, then using the Run method to call the batch file, using the variable strCommand as the sole parameter to the Run method. Upon doing so, we should get back something that looks like this:
C:\scripts>echo kenmyer kenmyer C:\scripts>echo atl-ws-001 atl-ws-001
That’s definitely more like it.
Incidentally, some of you might be wondering what the Script Editor does when she’s on vacation. Well, Monday morning she read her email, then came into work for a meeting. Tuesday morning she read her email, then came into work to have lunch with the legendary Peter Costantini, recently returned from a trip to the planet Saturn. (Or maybe it was Spain. One of the two, anyway.) On Wednesday she came into work for another meeting, then decided to stick around the office for a few hours in order to get some things taken care of.
And you guys thought we were joking when we told you how much fun the Scripting Editor was.
That’s all for now, folks. See you tomorrow, and having a nice daye!