Scripting Windows management is one of those good ideas that you might not have gotten around to trying yet. Perhaps you're not sure what you could accomplish with a script that you can't accomplish from the graphical interface. Perhaps you're worried about the learning curve—you don't know whether the time scripting saves you would make up for the time you spend learning to use it.
Or maybe you're a little lost in the crowd of scripting TLAs and vocabulary—WSH, WMI, ADSI, objects, methods, procedures, functions. If you've stuck scripting in the mental Developer Stuff box to be safely ignored, you're not alone.
However, ignoring scripting might be a mistake. In fairly short order, you can learn to script well enough to save yourself time and effort. And the more you script, the more time and effort you'll save.
In this column, I explain when you should use scripting, introduce some basic scripting concepts, and provide some helpful tips (see the sidebar "Quick Scripting Tips," page 74). In subsequent columns, I'll provide VBScript code that performs a common task and walk you through the code. I've chosen VBScript because Windows includes support for it. Windows also comes with JScript, but using one language for all the code samples will let you build on what you've learned in previous months.
The tasks I've already identified for forthcoming scripts are mostly from reader queries. I encourage you to send me your questions, with a couple of caveats: This column can't provide scripts for every occasion, and I can't provide extensive debugging support through email. However, some very smart people hang out at http://www.winscriptingsolutions.com; I recommend that you use this site's forum for getting and sharing debugging tips.
Scripting a task takes longer than doing the task once manually, even if you're a VBScript pro and know how to tackle the problem. If you're not a pro, writing and debugging the script will take much longer than using the GUI. So why script?
The key application for administrative scripting is automating repetitive tasks. If you have a task that you need to perform more than once or need to perform regularly, scripting that task is a good idea. Scripting such tasks lets you perform them quickly and consistently. Scripting also lets you create tools that the GUI doesn't provide.
If the GUI is time-consuming, then what about using the command-line tools that come with the OS and resource kits? Use them when you can, but Windows 2000 doesn't have command-line equivalents for every task you might want to accomplish, and some tools might not suit your situation. Batch files don't always work well in situations in which the input must change. Besides, scripting and the command-line tools aren't mutually exclusive options. You can write scripts that exploit the command-line tools while minimizing their disadvantages.
To get started, I want to define some scripting terms. You'll follow future columns much more easily if you know what a scripting host is, how the scripting host that you use can affect your script design, whether a procedure can contain an expression, and so on.
A scripting host is the operating environment for a script. Windows doesn't understand VBScript: Type a line of VBScript code at a command prompt, and you'll get an error message. When Windows encounters a file with a recognized scripting extension, the OS passes the script to the scripting host for interpretation. The scripting host interprets the script, then passes the script's message (e.g., a request for registry data) to Windows for execution.
Windows supports two scripting hosts: Microsoft Internet Explorer (IE) and Windows Script Host (WSH). The scripting host you use affects the options available to you in building your scripts. If you use WSH as the scripting host (as we'll do most often), you can use the objects WSH supports but not the ones that IE supports, and vice versa. A scripting host doesn't understand all scripts; it understands only the ones written in languages—script engines—that the host supports. Both WSH and IE natively support VBScript and JScript.
Elements of a Script
Each line in a script is a statement that tells the computer what to do next. Executable statements usually have a simple verb-object form, expressing the action and what to perform the action against. A script might also outline the conditions under which the verb-object combination applies. The scripting host interprets lines of code from left to right and top to bottom, so you can, for example, gather information in line 10 of the script, then manipulate that information in line 30. The exceptions to this rule are procedures. Procedures—functions and subroutines—are collections of statements that run only when the script calls them. When called, a procedure is executed immediately, regardless of where the procedure's code appears in the script.
The executable pieces of a script are called statements. The nonexecutable portions of a script, preceded by Rem or an apostrophe ('), are called comments and look like
Rem This is a comment
' This is a comment
Comments can appear on a separate line or as part of a line containing executable code. Comments document the script so that someone unfamiliar with the script or even with the scripting lexicon can easily tell what the script is intended to do. You can also add Rem or an apostrophe to the beginning of an executable line to disable that line for debugging purposes.
VBScript recognizes four types of data: numbers, strings, dates and times, and Boolean statements. Numbers are numbers such as 2 or 9458. Strings are any combination of characters enclosed within quotation marks, such as "fish" and "This is a string %@#^>". Date and time information must be within octothorps (i.e., pound sign—#—characters) and follow VBScript's idea of what dates and times should look like; both #16 January 1968# and #1/01/02 11:45 PM# are valid VBScript date or time values. Boolean statements are either TRUE or FALSE, as in x<x+1 = TRUE. (They don't have to be capitalized, but I find it easier to see them if they are.) You'll often use Boolean statements when testing the validity of statements.
VBScript sees all four of these data types as subsets of a larger data type, type variant, which can contain any kind of data. Thus, you don't have to tell VBScript what type of data you're feeding it, but you also can't perform some tasks possible with languages such as Visual Basic (VB), which treat these four data types differently. (Don't worry too much about any such limitations—you might never run into them.) Groups of like data treated together are called arrays.
To simplify data manipulation, VBScript supports two other data types that have no starting value (i.e., they are null) but are assigned one in the course of a script: variables and constants. Variables can (and frequently do) change value in the course of the script while retaining the same name. Constants have one value for the duration of the script and can't be changed.
You can make data available to scripts in several ways. One way is to hard-code the data in the script. For example, coding ""\\bigserver\sharedfolder"" is a valid way of including path information in a script. Another way is to have the person running the script explicitly provide the data or provide input that tells the script to use certain data. The script can also create its own data (e.g., by calculating the date 2 weeks from today's date), then work with it.
One way to manipulate data is with operators, symbols typically used to represent mathematical functions. Some operators take precedence over others, so although VBScript typically reads lines in a script from left to right, operator precedence affects the order in which the operators are interpreted. An expression is a calculation that might include any combination of numbers, variables, strings, or constants to get some result. Expressions can include operators. For example, the expression dInputDate + 2 = dNewDate increments the variable dInputDate by 2, then assigns the new value to the variable dNewDate.
Functions and Subroutines
VBScript provides built-in functions, which let you perform certain operations without having to spell them out in expressions. With these built-in functions, you can manipulate numbers, strings, dates and times, and arrays. VBScript also has conversion functions that let you convert one type of data to another. For example, VBScript typically assumes that a number such as 45 should be the number data type, but you might want to change it to the string data type.
VBScript lets you create user-defined functions (UDFs) to perform an action that you specify in the code. For example, in
Function TestFunct TestFunct = Sqr(9) + 2 End Function
the TestFunct UDF uses the built-in Sqr function to find the square root of 9, then adds 2 to the result. You could also create a UDF that acts on arguments you feed it, just as the built-in Sqr() function accepts numbers as arguments and derives their square roots.
The TestFunct UDF produces a result that you can return to the main body of the script. A subroutine performs a predefined action that doesn't return a result to the script. The scriptwriter might put the action in a subroutine because it needs to happen many times in the course of the script and he or she doesn't want to have to retype it each time. The subroutine
Sub AskUserName WScript.Echo _ "Please type a username." WScript.Quit End Sub
exploits a couple of capabilities of the WScript object to make it print a string to the screen, then exit the subroutine. Functions and subroutines can use the values of variables declared within the main body of the script or can use variables private to themselves.
Objects in Scripting
Objects represent physical or logical parts of the computing environment, such as disk drives or user account names. You can do simple scripting without resorting to objects, but most administrative scripts use them. If you're using WSH, VBScript can use objects native to WSH, such as those representing files and folders or parts of the registry; VBScript also supports Windows Management Instrumentation (WMI) and Active Directory Service Interfaces (ADSI) objects. WMI objects represent physical and logical parts of the computing system, such as IP addresses, file systems, and network cards. ADSI objects represent resources stored in a directory service such as Active Directory (AD) or other supported directories, such as the Windows NT 4.0 SAM. Static groups of objects of the same ilk are known as classes, and user-defined groups of objects are called libraries.
Objects have properties and methods. Properties describe an object (e.g., IP Address could be a property of the Network Card object, with 22.214.171.124 being the value of that property). Methods are actions you can take against an object (e.g., Copy could be a method of the File object). Not all objects have methods. Properties and methods are both written the same way: object first, a period, then the method or property name (e.g., ObjectName.PropertyName). Objects can contain other objects. For example, the WScript object in WSH contains a subordinate WshArguments object, which is a collection of any input that the person running the script has provided. To refer in a script to the first piece of input in WshArguments, you would type WScript.Arguments(0). As you'll see when we discuss WSH objects, the formal name of the subordinate objects doesn't match the name used to invoke them in a script.
If you're new to scripting, I've probably hit you with enough information for now. In my next column, I'll begin to show you how to apply this information to building administrative scripts.