In the past, I've discussed how to assign network resources based on user and machine identities. However, assigning resources based on user and machine account properties requires that you have an account to inspect. Therefore, I want to show you how to create a script that checks a domain to see whether a user account with a certain name exists and, if it doesn't, how to create an account with that name. Listing 1, page 88, shows this script called CheckNCreateUser.vbs, which takes advantage of Windows Script Host (WSH) and Active Directory Service Interfaces (ADSI). Before you can create a script like CheckNCreateUser.vbs, though, you need to know about procedures.
Understanding Procedures
Procedures are collections of statements that run only when a script calls them. When you call a procedure in a script, the procedure is executed immediately, regardless of where its code appears in the script. Procedures let you easily reuse code in scripts.
VBScript has two types of procedures: Sub procedures (aka subroutines), which you create with the Sub statement, and Function procedures (aka user-defined functionsUDFs), which you create with the Function statement. Subroutines are effectively miniscripts used to execute the same code more than once within a complete script. They don't require arguments and don't necessarily have return values.
UDFs are similar to VBScript's built-in functions in that both types of functions package frequently used sets of instructions that operate on arguments. However, built-in functions aren't Function procedures because Microsoft developers created the built-in functions. Like the name suggests, UDFs are created by VBScript users. Another difference between UDFs and built-in functions is that built-in functions work in any VBScript file, whereas, without special code, UDFs work only in the script in which you've created them. (WSH 5.6 supports a way to reuse code outside a script, but in this article, I look just at UDFs within the body of a script.)
The flow of control in VBScript code is pretty easy to follow: The VBScript runtime engine starts at the top of a script, reads every instruction, then ends when it runs out of instructions or encounters WSH's WScript.Quit method. As a result, if you create a script with errors in line 8 and line 26, the VBScript runtime engine complains only about the error in line 8. It never sees the error in line 26, and it won't until you fix the problem on line 8 and it's able to get to line 26.
You can use conditional statements to slightly change the flow. Conditional statements make the execution of code dependent on the outcome of circumstances for which you're testing (e.g., the existence of a user account before attempting to add the account). However, even with conditional statements, the VBScript runtime engine proceeds methodically through the script from top to bottom. Thus, where you put that Select Case statement or Do...Loop statement mattersunless you put that statement in a procedure.
When you run a script written in VBScript, the VBScript runtime engine examines the script to see whether the code includes any procedures. The runtime engine processes the code in a procedure only if you explicitly invoke that procedure with a Call statement. The Call statement typically includes the Call keyword, followed by the name of the procedure being invoked and any arguments that the procedure needs. (The Call keyword and the arguments are optional.) When the VBScript runtime engine comes across a Call statement, the engine bookmarks that place in the code. The engine then searches the code for a Sub statement or Function statement that includes the same name mentioned in the Call statement. When the runtime engine finds this Sub or Function statement, the engine runs the code that immediately follows, taking into account any conditional statements, until it comes to the End Sub or End Function clause, which marks the end of the procedure. At that point, the runtime engine goes back to its bookmarked location and continues with its methodical path through the script until it comes to another Call statement, runs out of code, or encounters the WScript.Quit method.
If the VBScript runtime engine comes across a Sub statement or Function statement for a procedure that hasn't been called yet, the runtime engine ignores the statement. Therefore, you can define a procedure either before or after you call it. In other words, the location of the procedure's code doesn't matternor does the order in which you include multiple procedures. However, a good scriptwriting practice is to put all procedures at the beginning of a script so that you know which procedures the script will call.
You can use procedures for more than just controlling a script's flow. You can also use procedures to perform repetitive actions and store data. For example, having a script perform an action more than once isn't uncommon. One way to have a script repeat an action is to copy the code that carries out the action and paste it wherever necessary.