Editor's note: This is the 11th column in a continuing interactive series on scripting that appears monthly on SearchWinSystems.com. You can send any scripting questions to the author, Christa Anderson, at firstname.lastname@example.org.
Providing guidance from the command prompt
A key part of any script that needs user input is to give the user help. There is no standard template that allows a user to predict with any degree of reliability how information should be presented. Even Microsoft's command-line utilities (as anyone who's used them knows) accept input in a dizzying array of forms that requires careful reading of the help files. Since no one can definitely know what, for example, "/a" means, you need to tell them, using either the command prompt or by providing guidance while you're asking for input.
There is one (fairly) standard input for command-line tools: the method of asking for help. Since so many command-line tools offer help when you type the name of the executable followed by /?, why not follow their lead and do the same? When the user types the script name followed by /?, they'll see help such as the following:
This script tells you the total and available space of the selected drive. Please type the identifier of the drive to inventory, like this: C:.
To make this work, you'll need to edit the script slightly, since it now expects that all input is a drive letter and colon. If you've read my previous columns, then you'll know about Select Case, a conditional statement that allows you to fork the outcome of a script according to the value of a variable—in this case, according to the value of the user input. Because all the input we're expecting is a single word (that is, not separated by a space), it will be taken as a single argument, which we're now going to assign to the variable sInput.
Notice that this example also makes use of subroutines (functions and procedures) to package complex sets of instructions. Subroutines make your scripts easier to edit, a heck of a lot easier to read, and, if you're consistent in your naming conventions, very portable from one script to the next.
Select Case sInput Case Empty Wscript.Echo "Please Case /? Call Help Case Else Call GetDriveInfo Sub Help This script tells you the total and available space of the selected drive. Please type the identifier of the drive to inventory, like this: C:. End Sub
GetDriveInfo is the script we made last month (with the user input variable amended); I'm sticking the whole thing in a subroutine.
Inventorying remote drives
One extension to this script could be running it to perform regular inventory on a known set of drives. In this case, the script would not run locally on a drive specified by the user, but remotely on a pre-determined set of drives. To accomplish this, we'll write a simple subroutine called "Remote," which will be called only if the user runs our script using the word "remote" as an argument.
"Remote" performs a couple of different routines. First, it prompts the user for the name of the remote computer to inventory. This input is gathered from a dialog box.
Once the subroutine has that information, it plugs it into the WshController object's CreateScript method. CreateScript's arguments are the path to the script to execute and the name of the server the script should execute on. If the script is stored on a network share, then you can launch the script from one computer to run on another, using a script stored on yet a third machine. Because we can't ask for user input from a script running on a remote computer, the script stored in this network location will need to have hard-coded drives instead of sInput, as our locally running script does not allow the user to specify which drive to inventory.
Sub Remote sRemote = InputBox("Supply the remote computer name.") Wscript.Echo sRemote Set oController = WScript.CreateObject("WSHController") Set RemoteScript = oController.CreateScript("c:scriptsstatic.vbs", sRemote) RemoteScript.Execute Do While RemoteScript.Status <> 2 WScript.Sleep 100 Loop End Sub
Putting it all together
Last month's column discussed the subroutines that allow you to inventory drives and write the data to a file, and we've already talked about the contents of our Help and Remote subroutines. The last piece to review is our Select Case conditional statements.
sInput = UCase(Wscript.Arguments(0)) Select Case sInput Case "/?" Call Help Case "HELP" Call Help Case "REMOTE" Call Remote Case Else Call WriteFile End Select
Most of this will look very familiar to you. The only piece that may be new is in the first line: the UCase function. This built-in function converts the data in its arguments to upper case. (LCase does the same thing in reverse.) By converting the user input to the script, I don't have to provide separate cases for every possible capitalization of "hElP." Non-alphabetic characters are not affected by UCase, so it's safe to use here.
This month, we've taken a script that performed a useful function and you now know how to make it more flexible by adding help and letting the user run inventory on a remote computer. You've also learned some things about functions—one subroutine in SuperDriveInfo.VBS calls a function external to it, meaning that you can nest procedures for greater flexibility. Any time that you've got a complex decision path in a script, I strongly recommend using procedures to make it easier to navigate. Here's the full script to look at:
Option Explicit 'Define the variables to be used in this script Dim oFSO, oFiletxt, sFilename, sPath, odrive, odrivepath, sInput, sRemote, oController 'Define the drive letter according to user input sInput = UCase(Wscript.Arguments(0)) Select Case sInput Case "/?" Call Help Case "HELP" Call Help Case "REMOTE" Call Remote Case Else Call WriteFile End Select 'This function gets the drive identified by the user Function GetDrive(sInput) Set odrive = oFSO.GetDrive(oFSO.GetDriveName(sInput)) End Function 'This subroutine writes drive info to a file Sub WriteFile 'Create the file system object and the file to store inventory in Set oFSO = CreateObject("Scripting.FileSystemObject") Set oFiletxt = oFSO.CreateTextFile("c:\driveinventory.txt", True) sPath = oFSO.GetAbsolutePathName("c:\driveinventory.txt") sFilename = oFSO.GetFileName(sPath) 'Call the function connecting to the drive Call GetDrive(sInput) 'Write the information in the file oFiletxt.WriteLine("Current Drive Inventory for "&odrive.VolumeName) oFiletxt.WriteLine("Total Drive Volume (in gigabytes):"&odrive.TotalSize/1073741824) oFiletxt.WriteLine("Available Space (in gigabytes):"&odrive.AvailableSpace/1073741824) oFiletxt.WriteLine("Drive Serial Number:"&odrive.SerialNumber) oFiletxt.Close If oFSO.FileExists(sPath) Then Wscript.Echo "The drive inventory is stored in",sFilename&"." End Sub 'This subroutine provides help information Sub Help Wscript.Echo "This script tells you the total and available space of the selected drive on this computer." Wscript.Echo "Please type the identifier of the drive to inventory, like this: C:." Wscript.Echo "To run the script on another computer with access to the volume where the script is stored, please type 'remote'." End Sub 'This subroutine executes the script on the remote specified computer Sub Remote sRemote = InputBox("Supply the remote computer name.") Wscript.Echo sRemote Set oController = WScript.CreateObject("WSHController") Set RemoteScript = oController.CreateScript("c:\scripts\static.vbs", sRemote) RemoteScript.Execute Do While RemoteScript.Status <> 2 WScript.Sleep 100 Loop End Sub
Read all of Christa's scripting columns:
April 2005: Beginner's guide to scripting
May 2005: It's time to increase your scripting expertise
June 2005: Connect users to network resources
July 2005: More on connecting to network resources
August 2005: Find objects with Windows Scripting Host
September 2005: Windows Script Host arguments
October 2005: Scripting School: Turning the environment with WshShell
November 2005: Scripting School: Connect scripts to remote computers
December 2005: Scripting School: Writing output to a text file
January 2006: Scripting School: Taking inventory of drives
|ABOUT THE AUTHOR:|
When Christa Anderson began working with Windows Server operating systems in 1992, she became increasingly interested in finding more efficient and flexible ways of performing routine tasks. Christa has written extensively about administrative scripting and taught technical sessions on the subject at conferences such as Comdex and CeBIT, helping people who had never done any scripting to write their own scripts in half a day. In addition to her interest in scripting Windows management, Christa is an authority on server-based computing and the program manager for Terminal Services licensing in Longhorn. If you have a scripting question for Christa, please e-mail her at editor@SearchWincomputing.com.