Learn about Windows PowerShell
Hey, Scripting Guy! A while back you showed how we could use the InputBox function to prompt a user to enter a value we could then use in our script. What I’d like to know is, is there any way I can take that value and use it in another script?-- JW
Hey, JW. We’re guessing here, but apparently you’d like to have a script that, among other things, prompted the user for some data. You’d then like to be able to start a second script, and enable that second script to access data the user entered in the first script. And, of course, you’d also like to know if such a thing is even possible.
And the answer is (the suspense is killing you, isn’t it?): sort of. Suppose you start Script A, and you enter a value. Can you now independently start Script B, and somehow have Script B peer into Script A and retrieve that value? No; that seems more akin to magic than to scripting. However, you can do this: start Script A and have the user enter the data. Then use Script A to start Script B; when you do that, you can pass the data along to Script B. That way, Script B will have full access to any information the user entered.
To better explain this, let’s take a look at a very simple example. We need two scripts: Script A and Script B. When we start Script A, the script will prompt the user to enter a number. Script A will then launch Script B; at the time it launches Script B, it will also pass along the number the user entered. Script B will then take that number, determine the square root, and report the answer.
Note. In a case like this, wouldn’t it be easier to just have one script that both accepted the user input and calculated the square root? Yes. Remember, though, this is just a demonstration script designed to show you a way to pass data from one script to another; it’s not intended to be an actual script you’d make use of in real life.
Here’s Script A. Notice that it starts by creating an instance of the WSH Shell object; this object is used later on to launch Script B (which we’ve named output.vbs; we’ll name Script A input.vbs). We then use the InputBox function to ask the user to enter a number:
Set objShell = CreateObject("Wscript.Shell")
intValue = InputBox("Please enter a number:")
strCommandLine = "output.vbs " & intValue
Notice what we do after the user enters a number (we’ll pretend that the user entered the number 2). We have this line of code:
strCommandLine = "output.vbs " & intValue
This code constructs a command for starting Script B. Suppose you wanted to start Script B and pass it the number 2 as a command-line argument. To do that, you would type this from the command prompt:
What we’re doing here is building a string that contains these two items: the name of the script we’re starting (output.vbs) and the command-line argument we’re passing (2). Of course, we don’t know that the argument is actually 2; we’re just passing along whatever value the user entered. That’s why we use the variable intValue instead. Notice, too, that output.vbs (plus a blank space) is included inside double-quote marks, and intValue is outside those double-quote marks. Why isn’t intValue inside the double-quotes? That’s easy; because then we would have constructed this command, which wouldn’t pass the number 2 (or any other number the user entered), but would instead pass the string value intValue:
Not what we want.
After constructing the command line, we then use the Run method to launch Script B, passing the value entered by the user as a command-line argument.
So then what does Script B look like? Well, it looks an awful lot like this:
intValue = Wscript.Arguments.Item(0)
intSquareRoot = Sqr(intValue)
Msgbox "The square root of " & intValue & _
" is " & intSquareRoot & "."
As you can see, we assign the first (and in this case, the only) command-line argument to the variable intValue. We then use the Sqr function to determine the square root of that value. Finally, we display the answer. In this case we used VBScript’s Msgbox function (as opposed to Wscript.Echo) to ensure that the answer appears in a message box. Had we used Wscript.Echo and Cscript was your default script host, a command window would open for a split second, the answer would appear on screen, and then the window would disappear before you had a chance to actually see the answer. Again, not what we wanted. The Msgbox function always displays data in a message box, regardless of the script host, so we went with Msgbox.
Again, a very simple example, but it could easily be expanded to send 2, 3, 4 or any number of command-line arguments from Script A to Script B. This definitely works, although you could theoretically run into the limitations on the length of a command string if you tried to pass too much data. In that case, your best bet would be to have Script A save data to a text file, and then have Script B read the data from that same file.
You also have to be careful about scripts that send command-line arguments that include spaces. For example, suppose you wanted to send the name Ken Myer to Script B. This command won’t work; it send two arguments (Ken and Myer) rather than the single argument Ken Myer:
output.vbs Ken Myer
Because of the space between Ken and Myer (and the space is the way WSH determines where one argument ends and the next begins), you need to put Ken Myer in double quote marks, like this:
output.vbs "Ken Myer"
In turn, that means the command-string you construct must includes double-quote marks as well. Here’s one way to do that; for more information, see this archived Hey, Scripting Guy!column:
strCommandLine = "output.vbs " & chr(34) & strValue & chr(34)
In this example, each instance of chr(34) inserts a double-quote mark. We thus end up with output.vbs plus " plus Ken Myer plus ", or:
<p>i cant get the argument to pass to the next script. can you tell me where i am going wrong?</p>
<p>Const conPath = "C:\Program Files\Login\login-log.vbs "</p>
<p>Const conUser = "test\tester"</p>
<p>Const conPwd = "test~" 'The tild(~) simulates an enter key press.</p>
<p>dim userloggedon, strCommandLine</p>
<p>set fso = CreateObject("Scripting.FileSystemObject")</p>
<p>set WshShell = CreateObject("WScript.Shell")</p>
<p>userloggedon = WshShell.Environment("process").Item("USERNAME")</p>
<p>strCommandLine = ("runas /noprofile /user:" & conUser & " " & chr(34) & _</p>
<p>"wscript \" & chr(34) & conPath & chr(34))</p>
<p>objShell.Run(strCommandLine) & chr(34) userloggedon & chr(34)</p>