In this section, you explore building arrays. To help in the process, you'll take a few ideas from the script in the "Passing Arguments" section and use them in a starter file.
1. | Open the \My Documents\Microsoft Press\VBScriptSBS\ch04\OneStepFurther\OneStepFurtherStarter.vbs file and save it as YourNameOneStepFurther.vbs. Note that OneStepFurtherStarter.vbs will not run. It is provided to save you some typing so that you can spend more time working with arrays.
|
2. | You first need to declare your arrays. The first array you need to declare is array1. It is initialized without a specific number of elements, and so you use the format Dim array1().
|
3. | Declare the second array, array2. Because array2 is created automatically when you use the Filter command, you just simply use the format Dim array2.
|
4. | Initialize the variables a and i, which are used for counting the elements in the array. In fact, in this script you'll be creating two arrays. The code goes under the series of Dim statements, which are used to declare the variables used in this script.
|
5. | Now you come to the first of the For Each statements in this script. This will come on the line after you use set colServices to make the connection into WMI.
For Each objService In colServices
ReDim Preserve array1(i)
array1(i) = objService.ProcessID
i = i + 1
Next
Here you are creating a For Each...Next loop that you'll use to add elements into the first array, which is called array1. Recall our discussion about arrays: Because you wanted to add information to the array and keep the existing data, and because you didn't know how many elements you'd have in the array, you used the format array1() when you declared it. Now you want to keep the information you put into the array, so you must use the ReDim Preserve command. Then you add items to each element of the array by using the following command:
array1(i) = objService.ProcessID
Once you add the process ID into the array, you increment the counter and go to the beginning of the For Each loop.
|
6. | Save the script. Compare your script with the \My Documents\Microsoft Press\VBScriptSBS\ch04\OneStepFurther\OneStepFurtherPT1.vbs file. If you try to run your script, you will still get an error.
|
7. | Now you populate array2, once again using a For Each...Next loop. The significant item in the code in this step is the Filter command. If you didn't create a second array, when you ran the script, you'd get pages of junk because the looping would create duplicate process IDs. (Remember, you're performing a query for process IDs that are associated with services, so that behavior is to be expected.)
Because there is no unique command or method for arrays, you have to create a second arraynamed array2by using the Filter command, and you also have to use a comparison filter as you add elements into it. The input into the filter is array1. You are matching the ProcessIDs from objService. (This is actually rather sloppy coding. Because you used objService.ProcessID several times, you could have created an alias for it.) The false in the last position of the command tells VBScript that the item is brought into the array only if a match is not found, which gets rid of our duplicate problem. You might want to change this value to true and see what happens to your script!
For Each objService In colServices
array2 = Filter(array1,objService.processID, false)
a = a + 1
Next
|
8. | Save the script. At this point, the script should run. If yours does not run, then compare it with \My Documents\Microsoft Press\VBScriptSBS\ch04\OneStepFurther\OneStepFurtherPT2.vbs.
|
9. | You need to put a For...Next loop around the bottom WMI query. Because you're working with an array, determine the upper element in the array by using the UBound command, as shown in the following code:
For b = 0 To UBound(array2)
This line will be used by the second array. What you are doing now is running a second WMI query against only the unique elements that reside in the second array. Make sure you add the last Next command. You just added two statements around six statements already in the file. The completed section of script, called \My Documents\Microsoft Press\VBScriptSBS\ch04\OneStepFurther\OneStepFurtherPT3.vbs, looks like the following:
For b = 0 To UBound(array2)
wmiQuery = "Select * from Win32_Service Where ProcessID = '" & _
array2(b) & "'"
Set colServices = objWMIService.ExecQuery _
(wmiQuery)
WScript.Echo "Process ID: " & array2(b)
For Each objService In colServices
WScript.Echo VbTab & objService.DisplayName
Next
Next
|
10. | Run the script. The script should now run as intended. If it doesn't, compare your script with OneStepFurtherPT3.vbs.
|
11. | Now let's make some further changes to the script, to add functionality. Save your script from step 10 to a new name such as YourNameOneStepFurtherPartOne.vbs.
|
12. | Open the \My Documents\Microsoft Press\VBScriptSBS\ch04\OneStepFurther\OneStepFurtherPartTWOstarter.vbs script and save it as YourNameOneStepFurther PartTwo.vbs.
|
13. | Because you're going to feed a text file, you won't need the code that references the Arguments collection. You will, therefore, also have to remove the following lines of code:
If WScript.Arguments.count = 0 Then
WScript.Echo("You must enter a computer name")
Else
strComputer = WScript.Arguments(0)
colComputers = Split(strComputer, ",")
Make sure you leave the line that is used to create the dictionary object. In addition, do not forget to get rid of the End If line at the bottom of the script. See \My Documents\Microsoft Press\VBScriptSBS\ch04\OneStepFurther\OneStepFurtherPT4.vbs to make sure you removed the correct lines of code.
|
14. | Add code to accept a command-line text file. You'll need to create a variable named TxtFile for the text file and then point the variable to a valid text file on your computer. Inside the text file, you need a list of only those computer names reachable on your network, separated by a comma. (Refer to my Servers.txt file for a sample, or simply edit it to your needs.)
Next you create a constant called ForReading and set it equal to 1. This is a good way to simplify accessing the file. Now create the FileSystem object by using the CreateObject("Scripting.FileSystemObject") command, which you set equal to the objFSO variable.
After you do that, open the text file by setting the objTextFile variable to be equal to objFSO.OpenTextFilewe feed this the variable for our text file and also the constant ForReading. Code for accomplishing all this follows. You place this code right below the Dim commands. This code is saved as \My Documents\Microsoft Press\VBScriptSBS\ch04\OneStepFurther\OneStepFurtherPT5.vbs.
TxtFile = "Servers.txt"
Const ForReading = 1
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile _
(TxtFile, ForReading)
|
15. | Look over the text file so that you know where to look for services and processes. To do this, use a Do Until loop. The interesting thing about this section of the code is that the loop is rather large, because you want to work with one computer at a time and query its services and processes prior to making another round of the loop. Therefore, placement of the outside Loop command is vital. In addition, you need to change the variable used in the For Each computer line, which follows the outside loop. Change colComputers to be arrServerList. Also, add a variable for strNextLine and arrServerList to the Header information section of your script.
Do Until objTextFile.AtEndofStream
strNextLine = objTextFile.Readline
arrServerList = Split(strNextLine , ",")
|
16. | Save your file. You can compare your file with \My Documents\Microsoft Press\VBScriptSBS\ch04\OneStepFurther\OneStepFurtherPT6.vbs. This script now runs.
|
17. | To keep track of how the script runs, add the following line just above the wmiRoot = "WinMgmts:\\ line:
WScript.Echo" Processes and services on " & (computer)
|
18. | To control the creation of the dictionary, move the line Set objIdDictionary = CreateObject("Scripting.Dictionary") inside the For Each computer In arrServerList line. Save your file and compare it with \My Documents\Microsoft Press\VBScriptSBS\ch04\OneStepFurther\OneStepFurtherPT7.vbs, if you want to.
|
19. | Add a new variable called j.
|
20. | Change i to j in the following line: For i = 0 To objIdDictionary.Count 1. This gives us a new counter the second time the script is run. In addition, edit the other two places where colProcesses(i) appears in this section and change colProcesses(i) to j as well.
|
21. | To make sure you don't reuse dictionary items the second time the script runs, remove all items from the dictionary by employing the objIdDictionary.RemoveAll command. You need to do this outside the For j loop but inside the For Each computer loop. The completed section looks like the following:
For j = 0 To objIdDictionary.Count - 1
wmiQuery = "Select * from Win32_Service Where ProcessID = '" & _
colProcessIDs(j) & "'"
Set colServices = objWMIService.ExecQuery _
(wmiQuery)
WScript.Echo "Process ID: " & colProcessIDs(j)
For Each objService In colServices
WScript.Echo VbTab & objService.DisplayName
Next
objIdDictionary.RemoveAll
Next
Next
Loop
WScript.Echo "all done"
|
This completes the "One Step Further" exercise. Compare your work to the \My Documents\Microsoft Press\VBScriptSBS\ch04\OneStepFurther\OneStepFurtherPT8.vbs script.