Hey, Scripting Guy! How can I force users to type command-line arguments in a specific order?
Hey, JA. You know, the Scripting Guy who writes this column has a 16-year-old son. He coaches Colt League baseball. He works every day with all the other Scripting Guys. With that background, it probably come as no surprise to hear that he doesn’t believe it’s possible to get anyone to do anything, let alone get them to type command-line arguments in a specific order. So, sorry, but as far as we know there’s no way to force users to type command-line arguments in a specific order (e.g., myscript.vbs atl-fs-01 alerter, where atl-fs-01 is the name of a computer and alerter is the name of a service). It just can’t be done.
But wait, don’t go: the Scripting Guys never let anyone leave empty-handed. Let’s think about what it is you really want to do here. We’re guessing you don’t really care whether the computer name is entered before the service name; you’re just looking for a way to know which command-line argument is which. And that makes sense; after all, these two commands are going to produce very different results:
myscript.vbs atl-ws-01 alerter myscript.vbs alerter atl-ws-01
You’d like to force users to type the computer name first, because then you can be assured that the first argument will always be the computer name and the second argument will always be the service name. We’re assuming that the order doesn’t really matter to you: you just want to be able to identify which argument represents the computer name and which argument represents the service name.
If it’s true that you don’t really care about order you just care about being able to identify which argument is which, well, then here’s your answer:
If Wscript.Arguments.Named("s") = "" Or Wscript.Arguments.Named("c") = "" Then Wscript.Echo "You must specify both the service and the computer using syntax like this:" Wscript.Echo Wscript.Echo "myscript.vbs /s:alerter /c:atl-ws-01" Wscript.Quit End If Wscript.Echo "Service: " & Wscript.Arguments.Named("s") Wscript.Echo "Computer: " & Wscript.Arguments.Named("c")
What we’re doing in this script is taking advantage of “named arguments” in Windows Script Host. We can’t force users to type command-line arguments in a particular order; however, we can require users to specify arguments by name. In this script, we require people to include an argument named s and an argument named c. In other words, you need to start the script using one of the following statements:
myscript.vbs /s:alerter /c:atl-ws-01 myscript.vbs /c:atl-ws-01 /s:alerter
If either (or both) of the two arguments are missing, the script will display some usage instructions and then quit. For example, suppose you try starting the script like this, with nary a /s or a /c in sight:
myscript.vbs alerter atl-ws-01
Here’s what you’ll get back:
You must specify both the service and the computer using syntax like this: myscript.vbs /s:alerter /c:atl-ws-01
Is this foolproof? No; obviously a user could type /s (for service) and then type the computer name, like so:
We can’t guard against that. But, at the very least, there will be no doubt as to which argument is supposed to represent the service name. And that’s all we were hoping to do.
So how does the script work? Well, the key is the very first line of code:
If Wscript.Arguments.Named("s") = "" Or Wscript.Arguments.Named("c") = "" Then
As you can see, we’re checking two things here: whether or not the named argument s is an empty string or whether or not the named argument c is an empty string. Suppose that argument s is equal to an empty string. That means one of two things: either you didn’t include that particular argument when starting the script, or you didn’t supply that argument with a value (for example, you started the script using the command myscript.vbs /s: /c:atl-fs-01). If no argument (or no value) can be found for either the named argument s or the named argument c then this block of code executes:
Wscript.Echo "You must specify both the service and the computer using syntax like this:" Wscript.Echo Wscript.Echo "myscript.vbs /s:alerter /c:atl-ws-01" Wscript.Quit
This code simply echoes back usage instructions and then uses the Quit method to terminate the script. In other words, if you don’t supply the proper arguments the script won’t run. Period.
But suppose you do supply values for both arguments. In that case the script uses these two lines of code to echo back the values for the two arguments:
Wscript.Echo "Service: " & Wscript.Arguments.Named("s") Wscript.Echo "Computer: " & Wscript.Arguments.Named("c")
Of course, you’d probably do something a bit more interesting with those values – like, say, connect to computer c and then stop service s. But that’s up to you. The important thing is that we can require people to enter specific arguments, and we can identify which argument is which. And all with a minimal amount of code.
A couple quick notes here. To begin with, argument names are purely arbitrary: we went with s and c because they’re easy to type and easy to remember. However, we could have given these arguments any name we wanted; we would just need to modify the code accordingly. For example, if we wanted to use service and computer then the first line of our script needs to look like this:
If Wscript.Arguments.Named("service") = "" Or Wscript.Arguments.Named("computer") = "" Then
Second, keep in mind that the name of the argument is a tad bit different from the syntax used when specifying that argument. Our arguments are named s and c. However, when we actually use those arguments we need to use this syntax: /argument_name:argument_value. Don’t type something like this; it won’t work:
myscript.vbs s alerter c atl-ws-01
Type this instead:
myscript.vbs /s:alerter /c:atl-ws-01
One more thing: if an argument value includes a blank space make sure you enclose that value in double quote marks. For example, suppose you want to stop the service Automatic Updates. In that case, you need to type the following command:
arguments.vbs /s:"Automatic Updates" /c:atl-fs-01
And, of course, order doesn’t matter: if you’d rather type the computer name and then the service name, well, hey, why not?
Incidentally, if you’re new to the whole idea of command-line arguments you might want to take a look at the Tales from the Script column Scripts Like a Good Argument. And, no, we can’t force you to read that column. After all, we still can’t get our rightfielder to throw the ball to the cutoff man, let alone make someone read an article about scripting and command-line arguments. But we’re working on it.
Note. Which one are we working on? Forcing people to read our articles. We’ve given up on our rightfielder.