If you administer or manage Windows NT networks, you'll want to know about Microsoft's Windows Scripting Host. WSH is Microsoft's new kid on the scripting block that offers more powerful capabilities than WSH's command-language, batch-file predecessor. In this article, I'll describe the architecture and components of WSH, explain how it works, and demonstrate its power with an example script.
WSH is more than just a language: WSH is a lightweight component object model (COM) scripting environment. The language is just one component of the script execution environment. Additional components include the objects you want your scripts to interact with or automate.
WSH provides improved systems administration capabilities through the use of the WSH Object Model. This runtime library includes objects, methods, and properties that you can use to map network drives or printers, retrieve and modify environment variables, create shortcuts, and read from and write to the Registry. You can use these functions to create logon scripts, configure users' desktops, create custom installation or configuration scripts, or perform other simple tasks. (For more information about using WSH, see Keith Pleas, "Windows Scripting Host in Action," February 1998.)
Although the built-in capabilities of WSH are useful, WSH's real power comes from its ability to use COM to call objects that expose automation interfaces. Microsoft calls this capability ActiveX Scripting. I'll show you an example script that exploits the power of WSH to access the services of Excel and the Active Directory Server Interfaces (ADSI). But first, let's look at how the WSH pieces fit together.
How WSH Works
Figure 1, page 204, is an architectural view of WSH. The WSH execution environment includes wscript.exe, a windows-based host; cscript.exe, a console-based host; and wshom.ocx, the WSH Object Model runtime library. WSH also includes two scripting engines: Microsoft JScript 3.0 (jscript.dll) and Microsoft VBScript 3.0 (vbscript.dll). Any optional Object Linking and Embedding (OLE) automation servers and your script source code (AddUsers.js and AddUsers.vbs in Figure 1) complete the picture. WSH uses the Registry to map scripts to the appropriate scripting engine.
Wscript.exe and cscript.exe provide the interface between a script source and a registered script engine (i.e., interpreter). The wscript.exe and cscript.exe hosts are language independent. You can write scripts in any language that is registered with WSH. When you double-click a filename with a .js, .vbs, or other registered extension, wscript.exe (the default execution host) executes the script by passing it to one of the registered script engines. WSH selects the appropriate script engine based on the script extension. This information is written to the HKEY_CLASSES_ROOT Registry hive during the script engine registration process. You can change the default execution host to cscript.exe, or you can specify the desired host via the Run dialog box or the command line at the time you invoke your script. For example, you can enter
c:\> cscript d:\source\scripts\wsh\myscript.js
c:\> wscript d:\source\scripts\wsh\yourscript.vbs
on the command line to specify the execution host you prefer.
Wscript.exe and cscript.exe also provide several runtime options, including an interactive or batch-mode switch and a maximum number of seconds that a script can run. Both hosts support interactive and batch modes. But cscript.exe's interactive mode uses a command-line interface and wscript.exe's interactive mode uses simple graphical dialog boxes; using either host in batch mode is easy.
To obtain a list of all supported options, at the command line, type
with no arguments, or type
c:\> wscript //?
(You use two slashes with all the WSH host options.)
The WSH Object Model is the runtime library that contains the objects and methods you need to create and control the script execution environment and perform administrative tasks. Table 1 lists the objects, methods, and properties the WSH Object Model provides. (You can find the complete WSH Programmer's Reference at http://www.microsoft.com/msdn/sdk/inetsdk/help/wsh/wobj.htm.) The WSH scripting engine creates the WScript object at the time you invoke your script; its methods and properties are immediately available. To use the additional WSH methods and properties, you must first create an object of type Shell or Network. For example, you can enter
set myShObj = Wscript.CreateObject("Wscript.Shell")
to create a Shell object, or type
set myNetObj = Wscript.CreateObject("Wscript.Network")
to create a Network object. When you obtain a reference to a Shell or Network object with the CreateObject Method, you can use the properties and methods these objects expose, as Table 1 outlines. In addition to the WSH objects, you'll also use the functions and language constructs of your preferred scripting engine (JScript, VBScript, or other third-party script engines) and any automation interfaces you call, such as ADSI, Excel, Internet Explorer, and OLE DB.
The scripting engines provide the language support you need to write scripts (e.g., variables, operators, control structures, and functions). The WSH scripting engines are COM based, which provides several important benefits: Third-party language developers can integrate their language into the WSH environment. Expect to see Perl-, Python-, Rexx-, and TCL-compatible scripting engines available soon. Also, software developers can implement and expose scripting capabilities in applications, and systems administrators can use the scripting language they're most comfortable with (provided a suitable WSH implementation exists).
Choosing between the two scripting engines Microsoft provides--JScript and VBScript--depends primarily on your environment. You can find complete language references and tutorials at http://www.microsoft.com/jscript and http://www.microsoft.com/vbscript.
Now let's look at the example script, AddUsers.vbs. Listing 1 shows the complete script, which adds users to an NT 4.0 directory in batch mode. AddUsers.vbs is an adaptation of a sample script of the same name that WSH includes. AddUsers.vbs demonstrates basic use of the WSH Object Model, basic use of the VBScript 3.0 scripting engine, and WSH's ability to create and control OLE automation servers.
To successfully run the example script, you'll need WSH 1.0, ADSI 2.0, and Excel 97 installed on your workstation. (For information about a DLL bug in WSH, see the online supplement, "The WSH Bug," at http://www.winntmag.com.) To install WSH 1.0, download the wsh.exe self-extracting executable from http://www.microsoft.com/management/wsh.htm. To install ADSI 2.0, download adsx86.exe from http://backoffice.microsoft.com/downtrial/moreinfo/adsi2.asp. Follow the ADSI 2.0 Setup instructions at this URL. Note that ADSI requires NT 4.0 Service Pack 3.
AddUsers.vbs begins by declaring the variables in the script. VBScript has only one data type: variant. You can use variants to store various subtypes including Boolean, byte, integer, currency, floating-point, date/time, string, and object. In VBScript, declarations are optional unless you use the Option Explicit statement; Option Explicit forces you to declare all variables before you use them. Next, the script initializes carriage return/line feed (CRLF) and dsRoot, respectively. The dsRoot variable contains the ADSI and NT 4.0-compliant directory name. Change LAB to your NT 4.0 test domain name to run this script in your local environment.
Next the script creates the wshShell object. You must include this step to use wshShell's Popup method. Popup's optional second argument lets you define how long (in seconds) to display the dialog box before the script continues. To avoid the overhead of creating the wshShell object, use VBScript's MsgBox function. Popup uses the same constants and return values as VBScript's MsgBox function. After creating the wshShell object, the code displays the popup dialog box that tells the user what action the script performs. If the user doesn't click Yes within 60 seconds, the script silently exits.
If the user clicks Yes, the script continues to the code at callout A, which obtains the path and file specification to the Excel file that contains the list of users to create. The script provides two mechanisms for the user to supply this information: via the command line at the time you invoke the script or via a prompt using VBScript's InputBox function. The code at A starts by assigning Wscript.Arguments to argv, which lets you query the properties that the WshArguments object provides. For example, the sample script uses argv.Count to test for the number of arguments. If the number of command-line arguments is zero, the script prompts the user for the file. Otherwise, the script assigns the first command-line argument, argv.Item(0), to xlFile. If no file specification is supplied using either input, the code displays an error message to the user for 10 seconds and kills the script.
Next, the script creates an Excel automation object and assigns to xlObj the reference Wscript.CreateObject("EXCEL.application") returns. When you have a valid reference to an EXCEL.Application object, you can use the objects, methods, and properties available in the Excel object library, as B shows. This code opens the user-defined input file, activating the AddUsers sheet and positioning the cursor in the A2 starting cell. The sample script has a rigid dependency on the format of the Excel file. Screen 1 shows an example of the input file I used to test the script.
Before cranking out users, you must obtain a reference to the NT 4.0 directory via ADSI. For this reference, AddUsers.vbs uses VBScript's GetObject function. The code passes GetObject to the ADSI and NT 4.0-compliant name-space name (WinNT://LAB in this example), and returns a reference to the directory in dsObj. You can use this reference to apply the methods and properties available via ADSI.
At the beginning of the Do While loop, the script tests the contents of the A2 active cell. If the string is not zero-length, the script defines the ADSI user object you want to create (usrObj), sets the object's properties (including FullName, Description, HomeDirectory, LoginScript, and Profile), and writes the newly defined object to the SAM database with SetInfo. At C, the script discards the user object in preparation for the next loop iteration, advances the focus in the Excel file to the next row, and begins again. The script continues until it hits the first empty cell in the first column of the Excel file. On exiting the loop, the script kills Excel, displays a success message for 10 seconds, and quits.
Scripts and the Web
Scripting is an important piece of any successful component architecture. Look no further than the Web for the most successful component architecture and implementation to date. Scripts played an important role in making the Web what it is today, and WSH is an example of Microsoft's component strategy. Is WSH Microsoft's COM glue? The fact that WSH scripts are appearing with products like Microsoft Transaction Server supports this idea. With WSH, NT systems administrators might have a scripting solution that works.