Working with Folders
In your day-to-day life as a network administrator, you must create folders hundreds of times if for no other reason than to hold numerous files. In my life as a consultant, I am constantly creating folders that hold project data for my clients. During the year I wrote this book, I had to create more than two dozen folders to organize the support materials, labs, and scripts so that I could keep track of them and maintain versioning information.
Just the Steps  | To create a folder
1. | Create a file system object by using CreateObject.
| 2. | Use the CreateFolder command to create the folder.
|
|
Creating the Basic Folder
Creating your basic folder requires only two lines of code. The first line of code creates an instance of the FileSystemObject class by using the CreateObject method. The second line of code sets the handle returned by CreateObject to a variable, which is used to call the CreateFolder method. The only parameters required by CreateFolder are the path and name of the folder to be created. This process is illustrated in the CreateBasicFolder.vbs script. For simplicity's sake, I am omitting the standard Header section.
CreateBasicFolder.vbs
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.CreateFolder("c:\fso1")
Creating Multiple Folders
Suppose you need to create some folders for a number of temporary users. You decide to call the users tempUser1 through tempUser10. It would actually take a while to create these folders for the users, if one had to use the graphical user interface (GUI) tools and perform the operation by hand. However, by making some changes to the CreateBasicFolder.vbs script, you can easily accomplish this task. The revised script, called CreateMultiFolders.vbs, follows.
CreateMultiFolders.vbs
Option Explicit
Dim numFolders
Dim folderPath
Dim folderPrefix
Dim objFSO
Dim objFolder
Dim i
Dim objSHell
Dim myDocs
Set objSHell = CreateObject("wscript.shell")
myDocs = objSHell.SpecialFolders("mydocuments")
numFolders = 10
folderPath = myDocs & "\"
folderPrefix = "TempUser"
For i = 1 To numFolders
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.CreateFolder(folderPath & folderPreFix & i)
Next
WScript.Echo(i - 1 & " folders created")
Caution  | FSO will not create a folder unless its parent folder already exists. Thus, an attempt to create C:\tmp\tmpusers\tmpuser1 will fail unless C:\tmp\tmpusers already exists. |
Header Information
The Header information section of CreateMultiFolder.vbs begins with Option Explicit to ensure that no variables are misspelled or mistakenly introduced. You then declare six variables that are used in the script. The first variable, numFolders, holds the number of folders you want to create. The next variable, folderPath, points to the location in which you will create the folders. In this instance, you are going to create 10 folders off the root of the C drive, but these values aren't assigned until the Reference section. The next variable is folderPrefix. In this script, you assign a word or a set of characters that Microsoft Visual Basic, Scripting Edition (VBScript) will use to begin the creation of the folders. The beauty of this arrangement is that you can later change the prefix easily. The variable objFSO holds the connection to FileSystemObject, and objFolder holds the handle to the CreateFolder command. The last variable declared is i, which is used simply as a counter.
As you can see, we did not use On Error Resume Next. When actually modifying or moving data, it is a good idea to allow errors to cause the script to fail so that data is not harmed if something goes wrong.
Reference Information
The Reference information section of the script assigns values to some of the variables declared in the Header information section. The variable numFolders holds the number of folders you want to create. The variable folderPath is used by the CreateFolder command when it comes time to create the folders. The variable folderPrefix is set to TempUser, which is the folder prefix you will use for each folder that gets created.
Worker Information
On the first line of the Worker information section, we have a For...Next loop. In this section, we use the counter i to keep track of how many folders you want to create. The number of folders created is stored in the value numFolders. At any given time, you have created i number of folders. This counting continues for each number between 1 and numFolders (inclusive).
On the second line of the Worker information section of the script, you use the CreateObject command to create an instance of the FileSystemObject. This exact line was used in all the scripts in Chapter 6, "Working with the File System." In every situation in which you must create an instance of the FileSystemObject class, the syntax will be exactly the same: CreateObject("Scripting.FileSystemObject"). In most of your scripts, you'll set the handle to FileSystemObject equal to objFSO (although the variable can be named anything).
The third line of the Worker information section of the CreateMultiFolder.vbs script is used to actually create the folders. Note the syntax of this command:
CreateFolder (folderPath)
In the script, you concatenate folderPath with folderPrefix and a counter number. This enables you to reuse the script for a multitude of purposes. In our example, you'll create 10 folders, named TempUser1 through TempUser10. You could just as easily change folderPrefix to ch and then create folders labeled ch1 through ch10. In a school setting, you might want to change folderPrefix to student, and thus create folders labeled student1 through student10.
Best Practices  | In the CreateMultiFolders.vbs script, we have the CreateObject ("Scripting.FileSystemObject") code inside the For...Next loop. On my particular laptop, this code executes faster than if it were outside the For...Next loop. In the "Discovering the most efficient code" procedure (coming up next), we outline a method to test your machine and see the best place for this code. |
If you change the value of i, you can create 10,000 or more folders just as easily as you can create 10. As you can see, it is really easy to create folders using the FileSystemObject class. It can also shave hours off of lengthy setup procedures. The best thing, however, is that once the script is written and tested, you get repeatable results. Creating folders is done right every single time. The completed Worker section is seen below.
For i = 1 To numFolders
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.CreateFolder(folderPath & folderPreFix & i)
Next
Output Information
After you create the folders, you want confirmation that the task completed successfully. In this script, you use WScript.Echo to let you know that the script completed successfully. The reason you need to use i - 1 in our count is that the value of i gets incremented prior to the Echo command. This is shown in the following code:
WScript.Echo(i - 1 & " folders created")
 |
Q. | What is required to create a folder?
| A. | A connection to FileSystemObject is required.
| Q. | Which method is used to create a folder?
| A. | The CreateFolder method is used to create a folder.
|
|
|
Note  | If you ran the CreateMultiFolders.vbs script, you now have 10 temp folders in that folder. In the next procedure, we are going to create 100 temp folders, so you will need to delete the folders created in the previous script. Make sure you are careful not to delete any of your documents while deleting the folders. |
Discovering the most efficient code
1. | Open \My Documents\Microsoft Press\VBScriptSBS\ch07\CreateMultiFolders.vbs in Microsoft Notepad or your favorite script editor and save the script as YourNameEfficientFolder.vbs.
| 2. | In the Header section of the script, declare three new variables to be used to time the script execution: startTime, endTime, and totalTime. This is seen here:
Dim startTime, endTime, totalTime 'used for timer function
| 3. | On the next line, use the Timer function to capture the first time stamp for your script. You assign the value from the Timer function to the startTime variable, as seen here:
| 4. | Change the value of numFolders from 10 to 100. This will enable the script to run for a longer period of time and provide you with a better opportunity to monitor the performance of the script.
| 5. | After the For...Next loop, assign the Timer function to the endTime variable to provide an ending time stamp. This will go just before the WScript.Echo line at the bottom of your script.
| 6. | To figure out how long the script ran, subtract startTime from endTime and assign the resulting number to totalTime, as seen here:
totalTime = endTime - startTime
| 7. | After your WScript.Echo line at the bottom of your script, print out the resulting value. My output line looks like the following:
WScript.Echo "It took " & totalTime &" seconds"
| 8. | Save and run your script. Remember how long it takes for your script to run.
| 9. | Open up Microsoft Windows Explorer and delete the 100 tempuser folders that were created.
| 10. | Move the create FileSystemObject line from inside the For...Next loop to the line above the For...Next command. This will keep the script from creating 100 different FileSystemObject objects. This completed section of code will look like the following:
Set objFSO = CreateObject("Scripting.FileSystemObject")
For i = 1 To numFolders
Set objFolder = objFSO.CreateFolder(folderPath & folderPrefix & i)
Next
| 11. | Save and run the script. Compare how long it takes to run this time, with how long it took to run earlier.
| 12. | Based upon this test, does it make much difference where the CreateObject line is placed? (On my laptop, the script actually runs faster when it creates the file system object 100 times. It seems VBScript is more efficient at creating objects than re-using objects (at least with my laptop). Your results may differ.
| 13. | If your script does not run as expected, then compare your script with the EfficientFolder.vbs script from the Chapter 7 folder.
|
Logging test results
1. | Open the EfficientFolder.vbs script in Notepad or some other script editor and save the file as YourNameEfficientFolderLogging.vbs.
| 2. | At the very bottom of your script, define a subroutine called subLogging. Make sure you also end the subroutine. Your code will look like the following:
| 3. | Inside the subroutine, you will want to define four variables that will be used for the logging activities. One will be for a wshShell object so we can obtain the path to a special folder. Two will be used for the log file, and one will be used to actually create the log file itself. My Header section in the subroutine looks like the following:
Dim objShell 'wshShell object
Dim strDir 'directory for log file
Dim strFile 'path to the log file
Dim objFile 'the file object from OpenTextFile method
| 4. | To obtain the path for the current desktop, we will use the wshShell object. To create this object, we create an instance of WScript.shell, as seen below:
Set objShell = CreateObject("WScript.shell")
| 5. | Use the strDir variable to hold the path to the desktop. To obtain this information, we will use the specialFolders method from the WScript.shell object. This is seen below:
strDir = objshell.SpecialFolders("desktop")
| 6. | To create the log file, we need to specify the name of the file as well as the path to the file. This is seen in the following code:
strFile = strDir & "\myLog.txt"
| 7. | In the Reference section of the subroutine, you may want to define some constants. These do not increase functionality; however, they do make the code easier to read. I used the following constants:
Const forAppending = 8
Const blnCreate = True 'will create the text file if it does not exist
Const intWindowPos = 4 'use most recent window position
Const blnWait = True 'script will wait until I manually close log file
| 8. | The easiest way to create a log file is to use the OpenTextFile method of the FileSystemObject and specify an optional parameter to create the file if it does not exist. This is a Boolean parameter, which we have assigned to the constant blnCreate. Because we are using tstrFile for a log file, we will want to append to the file, not overwrite the file. This line of code is seen below:
Set objfile = objFSO.OpenTextFile (strFile,ForAppending,blnCreate)
| 9. | Once we have opened the text file, it is time to write to the file. You will want to use the WriteLine method for your log file, because the entries will be easier to read if they are on separate lines of the file. To do this, I used the following:
objFile.WriteLine("Running script" & VbCrLf & Now & " took " & totalTime)
| 10. | Having written to the file, it is now time to open the file so it can easily be read. To do this, we need to enclose the path to the file in quotation marks so we can use the Run method from wshShell. You will need four quotation marks to embed quotation marks inside quotation marks. This strange looking line of code is seen below:
strFile = """" & strFile & """"
| 11. | Now you can use the Run method of the WScript.shell object to open the log file. This relies upon the fact there is a file association between txt and Notepad.exe. Use the constant intWindowPos to indicate where the program will appear, and the blnWait constant to keep the script running until you exit Notepad.
objShell.run strFile,intWindowPos,blnWait
| 12. | The completed subroutine looks like the following:
Sub subLogging 'logs the time the script was run, and how long it took to run
Dim objShell 'wshShell object
Dim strDir 'directory for log file.
Dim strFile 'path to the log file
Dim objFile 'the file object from OpenTextFile method
Set objShell = CreateObject("WScript.shell")
strDir = objShell.SpecialFolders("desktop")
strFile = strDir & "\myLog.txt"
Const forAppending = 8
Const blnCreate = True 'will create the text file if it does not exist
Const intWindowPos = 4 'use most recent window position
Const blnWait = True 'script will wait until I manually close log file.
Set objFile = objFSO.OpenTextFile (strFile,ForAppending,blnCreate)
objFile.WriteLine("Running script" & VbCrLf & Now & " took " & TotalTime)
strFile = """" & strFile & """"
objShell.run strFile,intWindowPos,blnWait
End sub
| 13. | Call the subroutine by placing the name of the subroutine after the line that uses WScript.Echo to display the amount of time it takes to run the script. This will look like the following:
| 14. | Save and run the script. It should open up Notepad with a line that indicates how long it took to run the script. If it does not, then compare your script with the EfficientFolderLogging.vbs script from the Chapter 7 folder.
| 15. | Run the script several times while moving the CreateObject command in or out of the For...Next loop. Remember, you will need to delete the folders prior to each running of the script.
|
 |