Wednesday 2 July 2014

Understanding Arrays in VBscript

Understanding Arrays

One fundamental scripting technique is to store data in an array and then use the data in a 
script. Arrays can be very complicated and multidimensional, but for our purposes, we keep 
them simple and basic. Think of an array as a collection of buckets, each bucket holding one 
piece of information. When we need that piece ofinformation, we retrieve it from its bucket. 
Each bucket has a number, starting with 0.
There are a few ways to get information into an array. One way is to use the Arrayfunction.
myArray=Array("Elm","Maple","Oak","Walnut","Hickory","Pine")
This technique works well when the information to be stored is known ahead of time 
and there is a relatively small amount of it. For a more dynamic approach, we use the Split
function.

strText="Elm,Maple,Oak,Walnut,Hickory,Pine" 
myArray=Split(strText,",")

The Splitfunction takes the specified text string and splits each element, in this case separated 
by a comma, into the individual buckets of the array.
After we have data in the array, we can access a bucket directly if we know its number. Thus if 
we want to use Walnut, we would reference myArray(3).Even though humans would count 
Walnutas the fourth element, because we typically start counting at 1, the array starts counting at 0. Thus the UBound(myArray)function, which displays the upper limit of the array, 
returns 5. If we want to return a human-friendly count of the array elements, we need to use 

UBound(myArray)+1.
To go through every element in the array, we can use a For…Nextloop, as follows.
For i=0 To UBound(myArray) 
WScript.EchomyArray(i) 
Next

Typically we pass the value from the array to a subroutine or function elsewhere in the script. 
We’ll give you a sample later.

Tuesday 1 July 2014

Using the FileSystemObjectLibrary

Using the FileSystemObjectLibrary

Working with files and directories is an important basic skill for a scripting administrator. You 
need to be able to read text files that might contain a list of computers as well as create text 
files that might be used as audit ortrace logs for your scripts. The FileSystemObjectlibrary is 
fairly extensive and we can’t possibly review everything here. We’ll focus on a few concepts 
that will be used throughout this book.
You can open a text file as follows.
strFile="c:\boot.ini" 
Set objFSO=CreateObject("Scripting.FileSystemObject") 
Set objTS=objFSO.OpenTextFile(strFile)
With just two lines of code, we’ve openedC:\boot.ini. After we create the basic Scripting.FileSystemObject, we create a text stream object that represents the contents of the file. After the 
file is open and the text stream object is created, we can read the file line by line. This is accomplished by using a Do…Whileloop and the AtEndOfStreamproperty.
Do while objTS.AtEndOfStream<>True 
Loop

As long as we aren’t at the end of the text file, we will loop through. We now need to read each 
line of the file and presumably do something with it. Conveniently, there is a ReadLine
method. If we simply want to read the file and echo back each line, we would use something 
like the following code.
Do while objTS.AtEndOfStream<>True 
Wscript.echoobjTS.ReadLine 
Loop
More than likely, you will want to do something with the information contained in that line. 
We prefer to set a temporary variable to hold the line’s contents. This makes it easier to clean 
up, manipulate, or validate the text string.
Do while objTS.AtEndOfStream<>True 
r=objTS.ReadLine 
if InStr(r,"XP") then strData=ProcessPC(r) 
Loop
In this little snippet, we search the read line for XPand if it is found, we set strDatato the value 
returned from a function in a script called ProcessPC(). When we are finished, we should clean 
up after ourselves by calling objTS.Closeto close the text file.
Before we leave OpenTextFile, we will briefly explain the different modes in which a file can be 
opened. You can open a file for reading only, for writing, or for appending. You simply specify 
the mode as one of the OpenTextFileparameters. This is generally done by defining constants 
in your script, as shown here.
Const FORREADING=1 
Const FORWRITING=2 
Const FORAPPENDING=8 
strFile="c:\boot.ini" 
Set objFSO=CreateObject("Scripting.FileSystemObject") 
Set objTS=objFSO.OpenTextFile(strFile,FORREADING)
If you open a file for writing, any existing data will be overwritten. If you open a file for 
appending, any data you write will be added to the end of the file. If you open a file for reading 
only, no changes can be made to the file. We generally use OpenTextFilefor reading or appending. If we need to write new data, we use the CreateTextFilemethod, as shown here.
strFile="c:\logs\myaudit.log" 
Set objFSO=CreateObject("Scripting.FileSystemObject") 
Set objTS=CreateTextFile(strFile,TRUE) 
objTS.WriteLine "Audit log: " & Now 
'script continues
With the addition of a CreateTextFileparameter, the code is pretty simple. When this parameter is set to TRUE, any existing file with thatname will be overwritten. If you don’t include 
a CreateTextFileparameter, existing files will not be overwritten, and your script won’t get 
very far unless you add some error handling. But after we’ve created the text file, we use the 

WriteLinemethod to add whatever data we want. As before, when we are finished, we need to 
close the file with objTS.Close.
The other common use of the FileSystemObjectis for working with folders and files. Listing 

 FileSystemObjectFile Sample

On Error Resume Next 
Dim objFSO,objFldr,objFiles,objTS 
strTitle="File Demo" 
strDir=InputBox("What folder do you want to examine?",_ 
strTitle,"c:\files") 
If strDir="" ThenWScript.quit 
Set objFSO=CreateObject("Scripting.FileSystemObject") 
If objFSO.FolderExists(strDir) Then 
'open folder 
Set objFldr=objFSO.GetFolder(strDir) 
'get log file information by calling 
'the GetFileName function 
strFile=GetFileName 
If strFile="" Then 
WScript.Quit 
Else 
'call validation subroutine 
ValidateFile strFile 
End If 
Else 
WScript.Echo "Can'tfind " & strDir 
WScript.Quit 
End If 
objTS.WriteLine "Folder Report for " & strDir 
'get files in this folder 
'objFiles is a collection 
Set objFiles=objFldr.Files 
'initialize our counter 
i=0 
'set variable for total number of files in folder 
t=objFiles.Count 
'enumerate the collection of files 
For Each file In objFiles 
'get file information and write to log file 
objTS.WriteLine file.Name & vbTab & file.size & " bytes" & vbTab &_ 
file.DateCreated & vbTab & file.DateLastModified 
i=i+1 
iPer=FormatPercent((i/t)) 
WScript.StdOut.Writeline(iPer& " complete") 
Next 
18 Part I: The Basics of Advanced Windows Scripting
'close file 
objTS.Close 
MsgBox "See " & strFile & " for results.",vbOKOnly+vbInformation,strTitle 
WScript.Quit 
'//////////////////////////////////////////////////////////////////////// 
Function GetFileName() 
On Error Resume Next 
GetFileName=InputBox("What is the name of theaudit file you " &_ 
"want to create?",strTitle,"c:\filelog.txt") 
End Function 
'//////////////////////////////////////////////////////////////////////// 
Sub ValidateFile(strFile) 
On Error Resume Next 
'check if log file exists and if so 
'prompt user if they want to overwrite. 
If objFSO.FileExists(strFile) Then 
rc=MsgBox(strFile & " already exists. Do you want " &_ 
"to overwrite it?",vbYesNoCancel+vbQuestion,strTitle) 
Select Case rc 
Case vbYes 
WScript.Echo"Overwriting file" & strFile 
Err.Clear 
'create our logfile by overwriting 
Set objTS=objFSO.CreateTextFile(strFile,True) 
IfErr.Number<>0 Then 
strMsg="There was an error creating " &_ 
strFile & VbCrLf & "Error#" & Err.Number &_ 
" " & Err.Description 
MsgBoxstrMsg,vbOKOnly+vbCritical,strTitle 
WScript.Quit 
End If 
Case vbNo 
strFile=GetFileName 
ValidateFile strFile 
Case vbCancel 
WScript.Echo "Aborting the script" 
WScript.Quit 
End Select 
Else 
'create our log file 
Err.Clear 
Set objTS=objFSO.CreateTextFile(strFile) 
If Err.Number<>0 Then 
strMsg="There was an error creating " &_ 
strFile & VbCrLf & "Error#" & Err.Number &_ 
" " & Err.Description 
MsgBox strMsg,vbOKOnly+vbCritical,strTitle 
WScript.Quit 
End If 
End If 
End Sub

If you’ve been reading from the beginning of this chapter.
includes a lot of the suggestions and tips made earlier, plus a little something extra to reward 
you for getting this far in the chapter.
Listing 1-12 examines all the files in a specified folder and creates a log with specific file information. This common use of the FileSystemObjectworks with any local or mapped drives, as 
well as Universal Naming Convention (UNC) paths. The script starts by asking the user for 
the folder path to examine.
strDir=InputBox("What folder do you wantto examine?",_ 
strTitle,"c:\files")
Assuming the user entered something, we can use the FolderExistsmethod to validate the 
entry.
If objFSO.FolderExists(strDir) Then 
'open folder 
Set objFldr=objFSO.GetFolder(strDir) 
...
We want a log file for the audit results, and now that we know we can continue, we need to 
create a text file. Recall that typically a function returns a value,and a subroutine is a section 
of modularized code that you can call as needed. We need to get the name of the log file from 
the user, so the script has a function called GetFileNamethat works as an InputBoxwrapper.
Function GetFileName() 
On Error Resume Next 
GetFileName=InputBox("What is the name of theaudit file you " &_ 
"want to create?",strTitle,"c:\filelog.txt") 
End Function
Again, assuming the user entered something, we need to validate the logfile. We call the 
ValidateFilesubroutine that takes a file name as a parameter. If the file already exists, we ask 
the user if he or she wants to overwrite the file.
If objFSO.FileExists(strFile) Then 
rc=MsgBox(strFile & " already exists. Do you want " &_ 
"to overwrite it?",vbYesNoCancel+vbQuestion,strTitle)
Depending on the answer, we can either create the text file and overwrite the existing version 
or prompt the user to specify a new log file name.
Select Case rc 
Case vbYes 
WScript.Echo "Overwriting file " & strFile 
Err.Clear 
'create our logfile by overwriting 
Set objTS=objFSO.CreateTextFile(strFile,True) 
If Err.Number<>0 Then 
strMsg="There was an error creating " &_ 
strFile & VbCrLf & "Error#"& Err.Number &_ 
20 Part I: The Basics of Advanced Windows Scripting
" " & Err.Description 
MsgBox strMsg,vbOKOnly+vbCritical,strTitle 
WScript.Quit 
End If
Notice the error handling in case there is a problem overwriting the file. If the user clicks No, 
we call the GetFileNamefunction again and then call the ValidateFilesubroutine, basically 
rerunning the code.
Case vbNo 
strFile=GetFileName 
ValidateFile strFile
Of course the user could tire of this and click Cancel, in which case we simply exit the script.
Case vbCancel 
WScript.Echo "Aborting the script" 
WScript.Quit 
End Select
If the file doesn’t exist, we create it and returnto the main part of the script. Again notice the 
error handling and MsgBox.
'create our log file 
Err.Clear 
Set objTS=objFSO.CreateTextFile(strFile) 
If Err.Number<>0 Then 
strMsg="There was an error creating " &_ 
strFile & VbCrLf & "Error#" & Err.Number &_ 
" " & Err.Description 
MsgBox strMsg,vbOKOnly+vbCritical,strTitle 
WScript.Quit 
End If
Now that we have the audit log taken care of, let’s get down to business and use the FileSystemObjectto look at the files in the folder. We createa collection object that will represent all the 
files in the folder by calling the Filesmethod.
Set objFiles=objFldr.Files 
We can enumerate this collection with a For…Each…Nextloop and write information about 
each file to the log.
For Each file In objFiles 
'get file information and write to log file 
objTS.WriteLine file.Name & vbTab & file.size & " bytes" & vbTab &_ 
file.DateCreated & vbTab & file.DateLastModified 
i=i+1 
iPer=FormatPercent((i/t)) 
WScript.StdOut.Writeline(iPer& " complete") 
Next
Chapter 1: Getting Started 21
The FileSystemObjectexposes file properties such as its name; its size; the date it was created, 
modified, and accessed; and a few others. This script creates a tab-delimited file, but it could 
easily be a comma-separated value (CSV) log instead.
After we’ve finished examining every file in the folder, we close the log file and display a completion message to the user.
objTS.Close 
MsgBox "See " & strFile & " for results.",vbOKOnly+vbInformation,strTitle
By the way, the script as written does not recurse through any subfolders. We’ll leave that as 
an exercise for you. But there’s one more goody in this script—we added code to provide some 
progress feedback to the user. The only catch isthat you must run the script from a command 
line using CScript.
There is a Countproperty for our files collection that will show the number of files in the 
current folder. If we know the total number of files and the number of files processed, we can 
calculate the percentage complete. We just need some variables.
'initialize our counter 
i=0 
'set variable for total number of files in folder 
t=objFiles.Count
In the For…Eachloop, we increment our counter variable and calculate the percent complete. 
We use the FormatPercentfunction to tidy up the math.
i=i+1 
iPer=FormatPercent((i/t))
All that is left is to display the result. We’ve decided to use the StdOutmethod of the Wscript
object to write directly to the command prompt window.
WScript.StdOut.Writeline(iPer& " complete")
The method will not work if the script is run with WScript. It must be run with CScript at a 
command prompt by typing cscript listing1-12.vbs. The percent complete scrolls down the 
screen, informing the user about how the script is progressing.

InputBox | InputBox with Menu | MsgBoxYesNo Sample |

InputBox

One of the great advantages of VBScript over traditional scripting, such as batch files, is the 
ability to solicit information or input from the user executing the script. This is typically done 
with the InputBoxfunction, as shown here.
Dim objFSO, objTS 
strTitle="Select Text File" 
strFile=InputBox("Whatfile do you want to open?",strTitle,"C:\boot.ini") 
'if value of strFile is blank then either nother was entered 
'or Cancel was clicked. In either case we can't continue 
If strFile="" Then WScript.Quit 
Set objFSO=CreateObject("Scripting.FileSystemObject") 
Set objTS=objFSO.OpenTextFile(strFile) 
'script continues
 The Basics of Advanced Windows Scripting
As you can see in this brief example, the script asks the user for a file name by using the InputBoxfunction. Although the only parameter required is text to explain what the user should 
enter, your script will be more user-friendly if you include a title and a default choice. The 
advantage of offering a default choice is that users have a better idea of exactly what format 
they should use.
After you get input, you should validate it, as we did in the code just shown. If the user clicks 
Cancel or doesn’t enter anything, there is no reason to continue, so the script silently quits. 
Depending on the type of information you are seeking, you might want to do further validation, such as checking the length or size of the entry. Or as you can validate 
the value itself.

InputBox with Menu Sample

On Error Resume Next 
strTitle="Option Menu" 
strMenu="Please select one of the following choices:" & VbCrLf 
strMenu=strMenu & "1 - Banana Cream" & VbCrLf 
strMenu=strMenu & "2 - Cherry" & VbCrLf 
strMenu=strMenu & "3 - Apple Walnut" & VbCrLf 
strMenu=strMenu & "4 - Peach" 
rc=InputBox(strMenu,strTitle,1) 
If rc="" ThenWScript.Quit 
Select Case rc 
Case "1" 
WScript.Echo "One slice of Banana Cream, coming up!" 
Case "2" 
WScript.Echo "Sorry, we are all out of cherry." 
Case "3" 
WScript.Echo "Do youwant ice cream with that?" 
Case "4" 
WScript.Echo "You get the lastpiece of Peach." 
Case Else 
WScript.Echo Chr(34) & rc & Chr(34) &_ 
" is not a valid choice. Please try again." 
WScript.quit 
End Select 
'script continues
we build a text string in the strMenuvariable. This variable is passed as the message parameter for the InputBoxfunction. Assuming the value returned by the InputBoxis not 
blank, we can use Select Caseto determine the next course of action.
Even though we expect the user to enter a number, he or she might accidentally type some 
non-numeric character. By enclosing the choices in quotes for the Casestatement, we treat the 
value as a literal text value. In this way, we are assured that the error handling code in Case 
Elsewill work. If the user enters anything other than 1, 2, 3, or 4, the error message is displayed. Entering A,which should be invalid, returns the code for Case 1.Copy the script for 
Alas, the InputBoxfunction is the only graphical input option we have, other than using an 
HTML Application (HTA) (which we cover later in the book) or developing your own input 
box in a higher-level programming language such as Microsoft Visual Basic 2005 (which is 
beyond the scope of this book).
MsgBox
Closely related to the InputBoxfunction, the MsgBox function also displays a message to the 
user in a graphical dialog box. At its simplest, all you need to code is the MsgBoxfunction and 
text to be displayed.
MsgBox "Welcome to the company!"
This line displays a message box in which the user must click OK to proceed. Script execution 
halts until the message box is dismissed. Recall that you use the WshShell.Popupmethod to set 
a time interval that determines how long to display the message. You can force a popup window to behave like a message box by setting the timeout value to –1, which requires the user 
to click a button to dismiss it.
You can use a MsgBoxfunction to display information or to get information, such as whether 
the user wants to continue working on the current task. The MsgBoxfunction returns a value 
determined by the button clicked. You can create a message box that offers the button options 
OK, Yes, No, or Cancel.
Note There are other button types available, but these are the ones you are most likely to 
use in a script. See the Windows Script Host 5.6 documentation for additional information.

MsgBoxYesNo Sample

strMsg="The file already exists. Do you want to overwrite it?" 
strTitle="File Confirm" 
rc=MsgBox(strMsg,vbYesNo,strTitle) 
If rc=vbYes Then 
Script.Echo "Overwriting file" 
'insert code here 
Else 
strNewName=InputBox("Enter a new filename.",_ 
strTitle,"c:\logs\newlog.txt") 
'insert code here 
End If 
'script continues
A MsgBoxfunction asks whether the user wants to overwrite the file and uses the constant 
vbYesNoto create Yes and No buttons. We set a rcvariable to return a value from the MsgBox 
14 Part I: The Basics of Advanced Windows Scripting
depending on what button the user clicked.We can then add code depending on the returned 
value. But what if the user has a change of heart and wants to abort the entire script? Take a 
look at 

MsgBoxYesNoCancel Sample

strMsg="The file alreadyexists. Do you want to overwrite it?" 
strTitle="File Confirm" 
rc=MsgBox(strMsg,vbYesNoCancel,strTitle) 
'take next steps based onvalue returned by 
'MsgBox function 
Select Case rc 
Case vbYes 
WScript.Echo"Overwriting file" 
'insert code here 
Case vbNo 
strNewName=InputBox("Enter a new filename.",_ 
strTitle,"c:\logs\newlog.txt") 
'insert code here 
Case vbCancel 
WScript.Echo"Aborting the script" 
WScript.Quit 
End Select 
'script continues
we use a Select Casestatement to handle the MsgBoxvalue. The code for vbYes
and vbNois unchanged. All we did was add code to handle vbCancel.
Tip You can also use vbYesNo, vbOKOnly, and vbYesNoCancelas button options in a 
WshShellpopup. The value returned is an integer, depending on what button is clicked, but it 
is easier to use the intrinsic constants like vbYes. If you don’t use the constants, you have to figure out what the constant equivalent is and use that in your code, and that probably won’t be 
as meaningful unless you comment heavily. Use the constants and make your life easier.
There is one more feature of the MsgBoxfunction that also works for the WshShell popup—the 
ability to add an icon to the dialog box. Table 1-1 shows the icons available.
To include an icon, simply add it with the appropriate button type, for example, 
vbOkOnly+vbInformation. Take a look at Listing 1-11, which is the script from Listing 1-10 
slightly modified to use icons.

 MsgBoxIcon Constants

VBScript Constant Integer Value Icon Displayed
vbCritical 16 Critical Message
vbQuestion 32 Warning Query
vbExclamation 48 Warning Message
vbInformation 64 Information

 MsgBoxwith Icon Sample

strMsg="The file already exists. Do you want to overwrite it?" 
strTitle="File Confirm" 
rc=MsgBox(strMsg,vbYesNoCancel+vbQuestion,strTitle) 
'take next steps based on value returned by 
'MsgBox Function 
Select Case rc 
Case vbYes 
MsgBox "Overwriting file",vbOKOnly+vbInformation,strTitle 
'insert code here 
Case vbNo 
strNewName=InputBox("Enter a new filename.",_ 
strTitle,"c:\logs\newlog.txt") 
'insert code here 
Case vbCancel 
MsgBox "Aborting the script",vbOKOnly+vbCritical,strTitle 
WScript.Quit 
End Select 
'script continues
Now our message boxes not only have a little morepizzazz, but they also provide visual reinforcement to the user. You can use these icon constants in a WshShellpopup, but unfortunately, you can’t use them with an InputBox.

WshNetwork | Error Handling | VBscript

WshNetwork

The WshNetworkobject exposes some basic network information for the current user, such as 
the username or computer name. This object can also be used to manage printer and drive 
mappings. Let’s take a quick look at this object’s functionality by incorporating it into the 
script.

WshNetworkSample

dim objShell,objNetwork,collDrives 
set objShell=CreateObject("Wscript.shell") 
Set objNetwork=CreateObject("WScript.Network") 
'title for popup window 
strTitle="Welcome" 
'enumerate mapped drives 
strMappedDrives=EnumNetwork() 
'enumerate mapped printers 
strMappedPrint=EnumPrint() 
'compose popup message text 
strMsg=objNetwork.UserName & ", thank you for logging in to " &_ 
objNetwork.ComputerName & VbCrLf & vbcrlf 
strMsg=strMsg & strMappedDrives & VbCrLf & VbCrLf 
strMsg=strMsg & strMappedPrint & VbCrLf & VbCrLf 
strMsg=strMsg & "It is now " & Now & VbCrLf 
strMsg=strMsg & "Have a nice day." 
'set time to -1 to neverdismiss popup window 
objShell.Popup strMsg,10,strTitle,vbOKOnly+vbInformation 
WScript.quit 
Function EnumNetwork() 
On Error Resume Next 
Set colDrives = objNetwork.EnumNetworkDrives 
'If no network drives were enumerated, then inform user, else display 
'enumerated drives 
If colDrives.Count = 0 Then 
ret="There are no network drives to enumerate." 
Else 
ret = "Current network drive connections: " & vbCRLF 
For i = 0 To colDrives.Count - 1 Step 2 
ret = ret & VbCrLf & colDrives(i) & vbTab & colDrives(i + 1) 
Next 
End If 
EnumNetwork=ret 
End Function 
Function EnumPrint() 
On Error Resume Next 
Set colPrint = objNetwork.EnumPrinterConnections 
Chapter 1: Getting Started 9
'If no network printers enumerated, then inform user,else display 
'enumerated printers 
If colPrint.Count = 0 Then 
ret="There are no printers to enumerate." 
Else 
ret = "Current Printer connections: " & vbCRLF 
For i = 0 To colPrint.Count - 1 Step 2 
ret = ret & vbCRLF & colPrint(i) & vbTab & colPrint(i + 1) 
Next 
End If 
EnumPrint=ret 
End Function

we customize the message to display the user name, the computer the user is 
logging onto, and any mapped drives or printers. We also create an object in our script called 
objNetwork, which is an instance of the WshNetwork object. With the objNetwork object, we 
can build a list of mapped drivesand printers by calling the EnumNetworkand EnumPrint
functions. These functions use the EnumNetworkDrivesand EnumPrinterConnectionsmethods 
to create collections of mapped network drives and printers respectively, as follows.
For i = 0 To colPrint.Count - 1 Step 2 
ret = ret & vbCRLF & colPrint(i) & vbTab & colPrint(i + 1) 
Next
The function then loops through the collection and lists the mapped network resources.
Back in the main part of the script, we compose the message. We personalize it by calling the 
usernameand computernameproperties, as shown here.
strMsg=objNetwork.UserName & ", thank you for logging in to " &_ 
objNetwork.ComputerName & VbCrLf & vbcrlf
The only other addition to our display message is the information about mapped drives 
and printers. The user now sees a personalized message showing all his or her mapped 
drives and printers. The message appears for 10 seconds and then closes. We raised the timeout value because there’s more to read now than in the Listing 1-1 example.
Note The username property is the user’s NT4 style or sAMAccountNameattribute such as 
jhicksor donj. If you want the user’s full name or display name from Active Directory, you must 
add code to search for the account based on the sAMAccountNameattribute.
Error Handling
Any administrative script should have some degree of error handling. Even if you develop 
scripts that only you use, error handling makes them easier to develop, debug, and deploy. 
You certainly don’t need to examine every single place where an error could occur, but you 
should identify sections of code where an error or failure will have a significant and negative 
10 Part I: The Basics of Advanced Windows Scripting
effect on your script. For example, if you are creating a log file with the FileSystemObjectand 
attempt to write to a drive for which the user lacks proper permissions, that code will fail. The 
best approach is to catch this kind of error ahead of time and provide some meaningful feedback to the user, as shown in Listing 1-6.
Note The error handling we are discussing is specific to VBScript. The engine that runs our 
scripts, Windows Script Host, is language independent. We could have written our scripts in 
JScript and handled errors in an appropriate manner for that scripting language.

 Error Handling Sample: Err

Dim objFSO,objTS 
On Error Resume Next 
Set objFSO=CreateObject("Scripting.FileSystemObject") 
Err.clear 
Set objTS=objFSO.CreateTextFile("R:\Logs\auditlog.txt") 
If Err.Number<>0 Then 
strMsg="There was an error creating the logfile" & VbCrLf 
strMsg=strMsg & "Error#" & Err.Number & " " & Err.Description 
WScript.Echo strMsg 
WScript.Quit 
End If 
'script continues from here

we attempt to create a log file. If this attempt fails, there is no reason to continue 
with the script. Before we try to capture error information, we make an Err.Clearstatement. In 
a short script like this it probably isn’t necessary, but in a longer and more complicated script, 
calling Err.Clearremoves any errors that occurred earlier in the script and were ignored. For 
example, you might be creating a user object in Active Directory from new user information 
stored in a text file. If one of the user attributes you want to populate is telephonenumber, but 
not every new user has this attribute populated,you want the script to continue regardless 
(hence the On Error Resume Nextat the beginning of the script). However, when you try to set 
this attribute in the script, an error is still raised. If you don’t call Err.Clear, the next time you 
check for the value of Err.Number, it might return the value of the previous error. In Listing 
It's is a highly unlikely event—nevertheless, we wanted to be very clear about how and 
when to use Err.Clear.
The actual error checking is looking for the value of Err.Number. A value of 0 indicates 
success. Any value other than 0 indicates some failure or error in the previous command. 
Depending on what the script was trying to accomplish, you might get a lot of error information or a little. At a minimum, we recommend displaying the Err.Numberand Err.Description
information to the user in some sort of error message. Keep in mind that not every error will 
have a corresponding description. Depending on the nature of your script and the value of 
Err.Number, you might add more sophisticated error handling. First intentionally induce 
errors that a user might cause and make note of the error numbers and descriptions. Then use 

a Select Casestatement to take more sophisticated steps or offer more detailed information 
based on the error, as follows.
Select Case Err.Number 
Case 76 
WScript.Echo "Verify that path is available" 
Case 71 
WScript.Echo "You seem to be attempting to access a drive" &_ 
" that isn't ready, like a CD" 
Case 70 
WScript.Echo "You don't seem to have permission to write to" &_ 
" that file." 
Case Else 
WScript.echo "Error #" & Err.Number & " " & Err.Description 
End Select
Of course, there is more to error handling than just the Err object. Some of the objects you 
might include in your script have their own mechanisms for avoiding or detecting errors. For 
example, the FileSystemObjectincludes the FolderExists, DriveExists, and FileExists methods. 
These methods return TRUE if the item in question exists, which means you can write code 
like that. 

Error Handling Sample: FileSystemObject

On Error Resume Next 
Dim objFSO,objTS 
strFile="R:\logs\audit.log" 
Set objFSO=CreateObject("Scripting.FileSystemObject") 
If objFSO.FileExists(strFile) then 
Set objTS=objFSO.OpenTextFile(strFile) 
Else 
Wscript.echo "Can’tfind " & strFile 
Wscript.quit 
End if 
'script continues

Monday 30 June 2014

Registry Reading

Registry Reading

The WshShellobject is often used to read the local registry. To read or manipulate a remote registry, you must use Windows Management Instrumentation (WMI.) Assuming the user executing the script has the appropriate permissions, you can easily read and write information 
from the registry. Here is a quick example of reading owner and product information from the 
local registry.

dim objShell 
Set objShell=CreateObject("wscript.shell") 
strRegisteredUser=objShell.RegRead("HKLM\Software\Microsoft\" &_ 
"Windows NT\CurrentVersion\RegisteredOwner") 
strProduct=objShell.RegRead("HKLM\Software\Microsoft\Windows NT\" &_ 
"CurrentVersion\ProductName") 
WScript.Echo strRegisteredUser & " is running " & strProduct

Program Launching
You will often need to call another script or program from your main administrative script. 
Fortunately, the WshShellobject makes this possible, as shown in Listing 1-2.

WshShell RunSample


dim objShell 
'Window style 
Const WINDOWHIDDEN=0 
Const WINDOWNORMAL=1 
Const WINDOWMINIMIZE=2 
Const WINDOWMAXIMIZE=3 
6 Part I: The Basics of Advanced Windows Scripting
Set objShell=CreateObject("wscript.shell") 
'enter in full path to command or script if not in %Systemroot% 
strCommand="Notepad" 
objShell.Run strCommand,WINDOWNORMAL,True 
'this line won't echo until previous command finishes 
WScript.Echo "Script complete"

The important parameters are the window style and whether the command 
should wait before continuing with script execution. In this example, we set up constants for 
typical window styles. (Again, refer to the Windows Script Host 5.6 documentation for additional window styles.) You will likely want to run a program or script and hide it from the user. 
Depending on the program or script, you can do this by setting the window type parameter to 0.
If you want execution in your main script to wait for the command to finish, set the WaitOnReturnvariable to TRUE. In Listing 1-2, the line of code that displays Script Completewon’t 
execute until the command launched by the WshShellobject has completed.
Another way to execute a command is with the Execmethod. This technique is especially useful for parsing out the results of a command-line tool or utility. Often, you might find yourself 
developing a script that could use the output of another command for reporting or as parameters. Listing 1-3 takes the output of a Dircommand that displays all executables, and modifies it so that it displays only the directory name and file information. You must run this script 
from a command prompt using CScript.

WshShell ExecSample: Dir


Dim objShell,objExec 
Set objShell=CreateObject("wscript.shell") 
'command to Execute 
strCommand="cmd /c DIR c:\*.exe /s" 
'text to look for in the output 
strFind=".exe" 
'Create Exec object 
Set objExec=objShell.Exec(strCommand) 
'parse output and only display lines With 
'target text 
Do While objExec.StdOut.AtEndOfStream<>True 
strLine=objExec.StdOut.ReadLine 
'parse out lines 
If InStr(strLine,"Directory") Then 
WScript.Echo Trim(strLine) 
Elseif InStr(strLine,strFind) Then 
WScript.EchovbTab & strLine 
End If 
Loop

At run time, the script passes the specified command to the WshShellobject and executes it. 
The output of that command is then redirected to a new object, called objExecin our script. 
With this object, we can leverage the power of StdOutand manipulate the data that would 
ordinarily be written in the command prompt window. As long as the command is running, 
the AtEndOfStreamproperty will be FALSE. Because we want to display specific information 
from what would generally be a lengthy output, we set a variable, strLine, to the value of the 
next line of StdOut. Then we can use the InStrfunction to find strings of interest. If there is a 
match, the line is displayed. In Listing 1-3, we want to display the directory name as well as 
each line that includes the file name.
Tip With StdOut, you can use any text stream property from the FileSystemObjectlibrary, 
such as ReadLine, SkipLine, and AtEndOfStream.

WshShell ExecSample: Nslookup


Dim objShell,objExec 
Set objShell=CreateObject("wscript.shell") 
'command to execute 
strCommand="Nslookup www.microsoft.com" 
'Create Exec object 
Set objExec=objShell.Exec(strCommand) 
'skip lines that contain information about our DNS 
'server 
objExec.StdOut.SkipLine 
objExec.StdOut.SkipLine 
Do While objExec.StdOut.AtEndOfStream<>True 
strLine=objExec.StdOut.ReadLine 
WScript.Echo strLine 
Loop 
WScript.Quit

demonstrates another way to use the Execmethod: executing an Nslookupcommand. Our script parses out the lines of interest, namely the IP address of the specified name, 
and neatly displays them. The script simply skips the first two lines of any Nslookupoutput 
that contains the DNS server name and IP address.
Tip Although not an absolute requirement, you will find it easier and neater to run scripts 
that take advantage of StdOutand StdInfrom the command line by using CScript. For example, 
if you run the script in Listing 1-4 by double-clicking it, you will see a few blank popup windows. If you run the script from a command prompt by using CScript, you will get cleaner looking results.

Understanding (VBscript) Windows Script Host Basics

Understanding Windows Script Host Basics

We assume you have Microsoft Windows Script Host 5.6 installed. If you aren’t sure, open a 
command prompt and type cscript //logo //?. You should see something like this.
Microsoft (R) Windows Script Host Version 5.6 
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved. 
Usage: CScript scriptname.extension [option...] [arguments...] 
Options: 

//B :Batch mode: Suppresses script errors and promptsfrom displaying 
//D :Enable Active Debugging 
//E  :engine Use engine for executing script 
//H  :CScript Changes the default script host to CScript.exe 
//H  :WScript Changes the default script host toWScript.exe (default) 
//I    :Interactive mode (default, opposite of //B) 
//Job :xxxx Execute a WSF job 
//Logo :Display logo (default) 
//Nologo :Prevent logodisplay: No banner will be shown at execution time 
//S      :Save currentcommand line optionsfor this user 
//T      :nn Time outin seconds: Maximum time a script is permitted to run 
//X      :Execute script indebugger 
//U      :Use Unicode for redirected I/O from the console

In the next sections, we’ll cover a few key WSH elements that recur in our scripts throughout 
the book.
Note Many of the scripts and samples in this book require administrator privileges, either 
locally or on remote systems. We assume you will be running any scripts as a local or domain 
administrator. Where appropriate, we will point out how and where to use alternate credentials.
WshShell
The WshShellobject offers a lot of functionality to scripting administrators. You can use it to 
send a message to the user through a popup, read and write to the registry, launch other programs, and more. Let’s take a quick look at this object.

Popup

The Popupmethod displays a graphical message to the user, complete with buttons and icons. 
One advantage to using the Popupmethod instead of the similar MsgBoxfunction (discussed 
later in this chapter) is that you can configure the popup window to dismiss itself automatically after a specified number of seconds. This is ideal when you want to display information 
to a user but you don’t want to rely on t he user to click OK. Listing 1-1 illustrates t he use of t he 
Popupmethod with a sample script.

 WshShell PopupSample

dim wshShell 
set wshShell=CreateObject("wscript.shell") 
'title for popup window 
strTitle="Welcome" 
'compose popup message text 
strMsg="Thank you for logging in." & VbCrLf 
strMsg=strMsg & "It is now " & Now & VbCrLf 
strMsg=strMsg & "Havea nice day." 
'set time to -1 to never dismiss popup window 
wshShell.Popup strMsg,7,strTitle,vbOKOnly+vbInformation

Notice that we use some intrinsic constants, vbOkOnly and vbInformation, as part of our 
popup parameters. These constants display the OK button and the information icon, respectively. These same constants are also used with the MsgBoxfunction. You can find more information about them in the Windows Script Host 5.6 documentation.