• Aucun résultat trouvé

For…Next

Do While

Do Until

This chapter begins by examining a real script to see how you can use these powerful tools in your daily duties as network administrators.

For Each…Next

The For Each…Next tool is really the “For something—do it again” tool. For Each…Next lets you walk through a collection of objects and perform a particular action on the object, and then perform that action again on the next object.

In the following script, you use For Each…Next to examine characteristics of fixed drives on a server:

Option Explicit On Error Resume Next Const DriveType = 3 Dim colDrives Dim drive

set colDrives = _

GetObject(“winmgmts:”).ExecQuery _

(“select DeviceID from Win32_LogicalDisk where DriveType =“ & DriveType) For Each drive in colDrives

WScript.Echo drive.DeviceID Next

Let’s peruse this script and see what it’s doing. In your initial reading, you see some common elements you learned about in Chapter 1, “Starting From Scratch”: the Header information section of the script (Option Explicit, On Error Resume Next, and Dim); and the Reference information section (the part with set colDrives). Those are the only ele­

ments that should look familiar. This script introduces a number of new concepts, such as constants, Windows Management Instrumentation (WMI), and collections, in addi­

tion to the For Each…Next construct. Dive in! The scripting waters are fine.

Just the Steps

To use For Each…Next

1. On a new line in a script, type For Each and then a variable name.

2. On the next line, enter a command you want repeated.

3. On the line following the command you want repeated, type Next.

Header Information

The Header information section of your script contains commands that are rapidly becoming old hat:

Option Explicit On Error Resume Next Const DriveType = 3 Dim colDrives Dim drive

This script begins by using Option Explicit, which says that each variable must be spe­

cifically listed (declared) by using the Dim command. On Error Resume Next is a rudi­

mentary error handling technique that says “when an error occurs, skip the line that caused the problem and go on to the next line in the script.” You also see a new item in the third line—Const. Let’s talk about it now.

Defining Constants

The Const DriveType = 3 line is a new concept. In this line, you define a constant. This line says that the word DriveType is equal to the number 3. Why do you do this? You want to use the number 3 later in the script when you build the WMI query. Rather than hard-coding the number 3 into your query (hard-coding a value into a script is called creating a literal), you replace it with the constant DriveType. Just like a variable, the constant can be called anything you want. But since WMI uses the number 3 to refer to the type of drive, you called the constant DriveType.

Constants vs. Variables

Why did you use a constant instead of a variable? This is a good question, and the answer is that you could have used a variable in this instance. It would look something like this:

Dim colDrives ’Holder for what comes back from the WMI query Dim drive ’Holder for name of each logical drive in colDrives Dim DriveType

DriveType = 3

In this particular case, using a variable instead of a constant wouldn’t have made any difference. However, variables have a dark secret that will come back to haunt you one day (guaranteed). Their value can change during script execution, whereas the value of a constant is set before execution. This is illustrated in the following rather silly script. First is the normal Header information section: Option Explicit, On Error Resume Next, and a few Dim statements to declare the variables. Next, in the Refer­

ence section, you assign values to each variable and echo out the total. So far so good.

However, you then reassign the FirstValue to be equal to the total, and echo out the total. Because the variable total is assigned to FirstValue + SecondValue before the FirstValue is reassigned to the total, the script produces illogical results. If you added

total = FirstValue + SecondValue right before the second echo, the script would work as expected.

Option Explicit On Error Resume Next Dim total

Dim FirstValue Dim SecondValue FirstValue = 1 SecondValue = 3

Total = FirstValue + SecondValue

WScript.Echo “ the total of “ & FirstValue & “ and “ & _ SecondValue & “ Is “ & (total)

FirstValue = Total

WScript.Echo “ the total of “ & FirstValue & “ and “ & _ SecondValue & “ Is “ & (Total)

Shared Benefits of Constants and Variables

You gain several advantages by using either a constant or a variable:

■ The script is easier to read. When you read the WMI query, notice that you’re fil­

tering by DriveType. This makes more sense than filtering out number 3 drive types.

■ The script is easier to revise. To change the script to filter out CD-ROMs, simply change the constant to the number 5.

■ Reusing the value in the script later on is easier. This script does not reuse the con­

stant DriveType. However, in longer scripts, you’ll do this, and using constants is a good habit to get into.

■ The script is easier to document. You can easily add a comment or a series of com­

ments such as the following:

Const DriveType = 3 ’used by WMI for fixed disks

‘other drive types are 2 for removable, 4 for Network, 5 for CD

After the constant is defined, you list a couple of variables used by the script. In this case, you declared two. The first one is colDrives. Now, why did you call this colD­

rives? Because the WMI query returns a collection of drives. Let’s look at collections and see what they do for you.

Quick Check

Q. Name one advantage of using For Each…Next.

A. Using this construct provides the ability to iterate through a collection without knowing the number of members in advance.

Q. What is the difference between a variable and a constant?

A. A variable can change value, whereas a constant retains a constant value.

Q. List three reasons for using constants.

A. Using constants makes the script easier to read and revise. Reuse later in the script is also easy.

Collections

When you have the possibility of seeing a group of related items, thinking of them as a collection is useful. A collection is a familiar concept. For instance, my wife has a col­

lection of key chains. Although each of the key chains is different (some have city names, some have college names, and others have product names), they are also sim­

ilar enough to be in her collection called key chains. That is, they all have a ring on which keys are hung—without that common purpose, they would not be key chains.

In a similar fashion, when you run your script, the script will return all the permanently fixed hard disk drives on the server. These drives might be IDE or SCSI, but they will all be hard disk drives.

What’s so groovy about having a collection of hard disks (aside from the fact they’re pretty)? Consider the alternative. If you couldn’t return a collection of hard drives from a server, you’d need to know which drives are actually installed on the machine. You’d have to connect to the server and list the necessary information for each drive—for example, you’d need to connect to drives A, C, D, E, F, and so on. In addition, to keep the script from failing when a drive did not exist, you’d need error handling (such as On Error Resume Next), or you’d have to test for the presence of each drive prior to querying infor­

mation about it. Although that approach would work, it would be kludgy, to say the least.

There is only one bad thing about collections: you cannot simply perform a WScript.Echo (or a WriteLine for that matter) of the information returned from a query. Instead, you have to do something like a For Each…Next loop and go through the loop as many times as there are items in the collection. If you had five drives in your collection, guess what?

We, in our current script, make five passes through the loop and echo each of the drives out. Walking through the loop multiple times, once for each member of the collection, is called iteration and is a task routinely performed in administrative scripting.

If you have only one drive, guess what? It’s still returned as a collection, and you have to iterate through the collection using For Each…Next to get out your single drive. Major

bummer! Fortunately, by the end of this chapter, you’ll have so much experience doing this, it will seem like a piece of cake (or a piece of celery, if you’re on a diet like I am).

Reference Information

In the Reference information section of the script is a new concept mentioned earlier—

WMI. We’re using it here to look at our drives, but you’ll learn more about WMI later in this chapter. To connect to WMI, you have to use a string that looks like GetOb­

ject(“winmgmts:”). Then you simply run a query that selects the desired drives.

Remember that in the Reference information section of our script, you say that colD­

rives is equal to all the information on the right side of the equal sign. You are creating an alias for the long winmgmts connection string that we call colDrives. You can see this in the following code:

Set colDrives =_

GetObject(“winmgmts:”).ExecQuery _

(“select DeviceID from Win32_LogicalDisk where DriveType =“ & _ DriveType)

Worker Information

The Worker information section is really small in this script. In addition, the Output information section is sandwiched inside the For Each…Next loop. Let’s look at it:

For Each drive In colDrives WScript.Echo drive.DeviceID Next

Because you sent a fine-tuned query to WMI in the Reference information section of the script, and the purpose of the script was simply to list drives, the Worker informa­

tion section has little work to do. All it really needs to do is to walk through the col­

lection of drives returned from WMI. You use For Each and then the variable drive that you created to hold each of the drives returned from colDrives. Once you have the drive in your hands, you look for the DeviceID of the drive. But, interestingly enough, you use this in the Output information section of the script, which is the WScript.Echo part. After you echo the DeviceID, you do it again for the next drive in the collection using the Next command.