Running Your First ScriptIt is late at night and the cold air conditioning is drying out your eyes, making it impossible to keep them open. You have drunk nearly a dozen cups of coffee, and you try to steady your hands. The last item on your migration check-off list stares out at you eerily from the page: "Ensure all servers have the administrator tools installed." Slowly your predicament begins to sink in, through the caffeine cloud surrounding your eyes. "I should have been doing this hours ago." The hum of the equipment room seems to grow louder, and the rows of servers stretch for miles and miles. Supper is a distant memory and sleep a fleeting dream. "How in the world am I supposed to check a thousand servers for administrator tools?" The darkness of foreboding doom begins to envelop you but then suddenly vanishes with a single fulgurant idea: I bet we can script this! Within five minutes, the following script is tested on a single server and works like a charm: DisplayAdminTools.vbs Set objshell = CreateObject("Shell.Application") Set objNS = objshell.namespace(&h2f) Set colitems = objNS.items For Each objitem In colitems WScript.Echo objitem.name Next Just the Steps A good way to learn how to write scripts is to read scripts. So what is a script? For our purposes, a script is nothing more than a collection of commands that we include in a text file. In this regard, scripts are like batch files that many network administrators have used since DOS days. Just like batch files, scripts can be written using nothing more sophisticated than Microsoft Notepad. An important difference between a batch file and a script is that a script has greater flexibility and its language is more powerful. In this section, you'll look at several scripts and learn to identify their common elements. I know some of you probably want to start typing your first script, but be patient. In the long run, you'll benefit from taking the time now to understand the elements common to most enterprise ready scripts. Just the Steps
After you open the script, the following text appears. We'll be referring to it again in the next few sections. Note
DisplayComputerNames.vbs Option Explicit On Error Resume Next Dim objShell Dim regActiveComputerName, regComputerName, regHostname Dim ActiveComputerName, ComputerName, Hostname regActiveComputerName = "HKLM\SYSTEM\CurrentControlSet\Control\" & _ "ComputerName\ActiveComputerName\ComputerName" regComputerName = "HKLM\SYSTEM\CurrentControlSet\Control\" & _ "ComputerName\ComputerName\ComputerName" regHostname = _ "HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Hostname" Set objShell = CreateObject("WScript.Shell") ActiveComputerName = objShell.RegRead(regActiveComputerName) ComputerName = objShell.RegRead(regComputerName) Hostname = objShell.RegRead(regHostname) WScript.Echo ActiveComputerName & " is active computer name" WScript.Echo ComputerName & " is computer name" WScript.Echo Hostname & " is host name" As you can see, this script contains a lot of information. Let's break it down piece by piece so that it's not too overwhelming. For the purposes of our discussion, you can think of the script as being made up of four main parts: Header InformationYou can think of the header information as administrative overhead for your script. For most scripts, you can leave out the Header information section and lose none of the functionality. In fact, the preceding script would run just fine if the Header information section were deleted. (And it just so happens that you'll get a chance to prove this assertion during the step-by-step exercises at the end of this chapter.) If this information is so unrelated to the script's functionality, why should you include it? The header information should be a standard part of your script for two reasons: It makes the script easier to read and maintain, and it controls the way the script runs (as opposed to the way it might run by default). You'll learn more about how it controls the script later in the chapter when we look at the Option Explicit command and the On Error Resume Next command. In the DisplayComputerNames.vbs script, the header information consists of the following lines of code: Option Explicit On Error Resume Next Dim objShell Dim regActiveComputerName, regComputerName, regHostname Dim ActiveComputerName, ComputerName, Hostname Although this code might look complicated, in reality, only three different commands are being used: Option Explicit, On Error Resume Next, and Dim. Each of these commands is covered in detail in the following sections, but before we dive into the nuts and bolts, let's do a quick reality check.
Option Explicit and DimThe Option Explicit statement tells the script that each variable used in the script is going to be listed before it is actually used. Note
If you want to use a variable and you specify Option Explicit in the Header information section of the script, you have to tell the script you're going to use this variable before you actually use it. This is called declaring a variable. If you omit Option Explicit, VBScript assumes by default that any statement it doesn't recognize is a variable. To declare a variable, you must use the command Dim, as illustrated in the preceding code. We do not have to specify what kind of information we are going to store in the variable, as VBScript treats everything as a "varient." In VB.NET, we would use the following command: Dim j as int. In VBScript, we just Dim j and it is a varient, which means it can be anything from a string to a date. By treating everything as a varient, VBScript is very easy to use. One problem that "scripters" have when transitioning their VBScript code to VB.NET is the "as thing." Dim j as WHAT? J is just a variable many scripters often say because in VBScript we do not normally need to worry about data types. This code has a whole bunch of Dim stuff. As mentioned in the preceding paragraph, you use the word Dim to declare a variable. For instance, in the code at the end of this section, objShell and all the other words (except for Dim) are variable names I made up. I could have just as easily used a, b, c, d, and so on as the variables' names (kind of like the variables you used in high school algebra) and saved myself a lot of typing. However, a good variable name makes the code easier to read and to understand. For example, in the following code, you can assume that the variable named ComputerName actually holds a computer name. (I think you'd agree that ComputerName is much more descriptive than a.) And notice how similar regActiveComputerName, regComputerName, and regHostname are (except for the reg part) to the following variables: ActiveComputerName, ComputerName, and Hostname. The variables are arranged according to how they will be used. That is, variables used to hold registry keys are on one line, and variables containing the corresponding output values of those registry keys appear on the next line. Dim objShell Dim regActiveComputerName, regComputerName, regHostname Dim ActiveComputerName, ComputerName, Hostname On Error Resume NextWhat does On Error Resume Next sound like it's trying to do? Let's break it down. On Error means that you want the computer to do something if it finds an error. Resume Next is what you want it to do. But Next what? A very good question. The Next you want it to resume is the next line of code in the script. So On Error Resume Next tells the computer that when something is messed up (causing an error), you want the computer to just skip that line and try the next line in the script. This process is called error handling, and it's a very basic task when writing scripts. You should probably consider using On Error Resume Next when you're using VBScript for logon scripts so that you don't get lots of phone calls right at 9:00 A.M. when your script has a problem. Of course, you'll test the script prior to deploying it, but we all know that tests don't always catch every eventuality. You'll learn about error handling in more detail later, including some pretty cool tricks, so stay tuned. Note
Reference InformationThe Reference information section of the script gives you the ability to assign values to the variables you named in the Header information section of the script. Another reason for using a variable is to create a shortened alias for some value. Aliases make the script easier to work with. In the following code, values are assigned to some of the variables created in the Header information section of the script. regActiveComputerName = "HKLM\SYSTEM\CurrentControlSet\Control\" &_ "ComputerName\ActiveComputerName\ComputerName" regComputerName = "HKLM\SYSTEM\CurrentControlSet\Control" &_ "\ComputerName\ComputerName\ComputerName" regHostname = "HKLM\SYSTEM\CurrentControlSet\Services" &_ "\Tcpip\Parameters\Hostname" Notice that everything on the right-hand side of the equal sign looks like a registry key. If you caught that, you can probably figure out what the reg part of the variable name stands for. You got itregistry! Did you also notice that the three variable names (on the left-hand sides of the equal signs) are the same ones we talked about in the preceding section? What you're doing in this code is tying each of those variables to a registry key. For example, the first line of code shows that regActiveComputerName is equal to the very long string HKLM\SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerName\ComputerName. (By the way, HKLM is shorthand for HKEY_LOCAL_MACHINE. Because VBScript understands this abbreviation, using HKLM will save you some typing. But keep in mind that HKLM is case sensitive! It must be all caps.) The lines containing the registry keys are using two special characters. The & (ampersand) is the concatenation operator, and it is glue. When you use it you glue two things together. The _ (space underscore) is used to continue the code to the next line. This is necessary to make the code easier to read in the book. We talk about this in more detail in Chapter 2, "Looping Through the Script."
The Reference information section has the following purposes:
Worker InformationThe Worker information section of the script gets its name because it actually does something. The variables are declared in the Header section and referenced in the Reference section; in the Worker information section, the variables get busy. Note
Let's look at some code. Set objShell = CreateObject("WScript.Shell") ActiveComputerName = objShell.RegRead(regActiveComputerName) ComputerName = objShell.RegRead(regComputerName) Hostname = objShell.RegRead(regHostname) Because you've read through the header information and looked at all the Dim statements, you know which names in the preceding code are variables. For instance, objShell is a variable; that is, it is shorthand for something. The question is, shorthand for what? Let's walk through the first line of code: Set objShell = CreateObject("WScript.Shell") Notice that the sentence begins with Set. Set is a command in VBScript that is used to assign an object reference to a variable. For VBScript to be able to read from the registry, it must have a connection to it. This requirement is similar to that for reading from a databaseyou must first establish a connection to the database. To create an object reference, you use the Set keyword to assign the reference to a variable. VBScript uses automation objects as a way to use the capabilities of other programs to provide more power to the system administrator who needs to create powerful scripts to manage today's complex networking environments. For example, instead of dumping output to a black and white, text-only command prompt, you can use an automation object to leverage the display and formatting capabilities of the products in the Microsoft Office system and create multicolor, three-dimensional graphs and charts. You are setting the variable name objShell to the reference you created by using CreateObject. Notice the equal sign following objShell. It indicates that objShell should be equal to something elsein this case, to everything to the right of the equal sign, or CreateObject("WScript.Shell"). For now, pay attention to the CreateObject part of the expression. The use of the verb Create is a tip-off that some action is about to take place. As you'll see in a moment, this line assigns to objShell a connection that will enable the script to read the registry.
Note
You can now use the variables ActiveComputerName and regActiveComputerName to read the registry by taking advantage of the newfound power of the variable objShell. Remember that earlier you defined regActiveComputerName as equal to the registry key that contains the active computer name. You now define ActiveComputerName to be equal to the name that comes out of the registry key when you read the registry. You do the same thing for the other two registry keys. Let's take a moment to recap what you've done so far. You've stored three computer names into memory by using the variables named ActiveComputerName, ComputerName, and Hostname. To get the computer names into those variables, you read the values that are stored in three different registry keys on the computer. To do this, you created three variables named regActiveComputerName, regComputerName, and regHostname. You used the prefix reg to denote that the variables contain strings for the actual registry keys. You then used the RegRead capability of the objShell variable that you assigned to the object reference by using the CreateObject command. Now that you have this information stored into three variables, you need to do something with it. In the script you are examining, you will use the output capability of VBScript, described in the next section. Output InformationBeing able to read from the registry, though cool, doesn't do you much good when you can't use the information. That's why it's important for a script to have an Output section. Of course, you can write a script that uses the information to perform tasks other than creating output, such as monitoring the status of a service and restarting it when it fails, but even then most network administrators would want at least a log entry stating that the service was restarted. In our script, output is provided through a series of Echo commands. The use of the WScript.Echo command is illustrated in the following code: WScript.Echo activecomputername & " is active computer name" WScript.Echo ComputerName & " is computer name" WScript.Echo Hostname & " is host name" The WScript.Echo command is used to type text inside a command prompt or to produce a pop-up message box, depending on how the script is actually run. When the script is run by using CScript, as detailed in the earlier procedure titled "Just the Steps: To run an existing script," the script writes inside the command shell. Each variable name that you just set is equal to the registry key information in the last section of our script. So what does Echo do? You guessed itit repeats something. Because the variables are now linked to the strings contained within the registry keys (via the Reference information section), we can use WScript.Echo to write the information currently held by the variables. In the code, the ampersand (&), which simply means and, is followed by a phrase within quotation marks. The current value of the variable on the left side of the ampersand gets put together with the string value contained inside the quotation marks on the right side of the ampersand. This "putting together" of two things with the ampersand is called concatenation. You are echoing what is stored in memory for each of our three variables, and you're also adding some text to explain what each variable is. When you run this script by double-clicking the script, you're rewarded with the results in Figure 1-2. Figure 1-2. Screen output of DisplayComputerNames.vbs
Dealing with only three dialog boxes is a bit tedious, so imagine the frustration that dealing with a thousand or even just a hundred dialog boxes could cause. Some scripts can easily return a listing of more than a thousand items (for example, a script that queried all the users in a medium-sized domain). Clearly you need a more efficient way to write data. In fact, you have several ways to do this, such as using VBScript's MsgBox to display a pop-up box containing text, but I am going to save that for Chapter 2.
|