Windows IT Pro is the authoritative and independent resource for windows nt, windows 2000, windows 2003, windows xp. Features a collection of resources and magazines for windows IT professionals.
  
  
  Advanced Search 


January 16, 2008

How to Multi-Thread VBScript Scripts

Have your scripts complete in a fraction of the time that they would typically take
RSS
View this exclusive article with VIP access -- click here to join | See More Performance Articles Here | Reprints
Or sign up for our VIP Monthly Pass!

Download the Code Here

 Executive Summary:
On the Internet, you can likely find VBScript code that suits your needs. The real trick is figuring out how to put all the disparate parts together into a cohesive whole while circumventing some of VBScript's limitations. One of those limitations is that VBScript can do only one thing at a time. MultiThreader.vbs works around that limitation by simulating multi-threaded behavior

Once you learn the basics of VBScript, you can accomplish almost anything you want with ease. Armed with a browser and an Internet connection, you can find someone who has written code that collects the information you need or that sets the setting that you need to configure. The real trick is figuring out how to put all the disparate parts together into a cohesive whole while circumventing some of VBScript's limitations.

For example, you can find scores of Web sites that provide code that determines how much free space is on a computer. DiskSpace.vbs in Listing 1 shows a script that does just that. Or you can find code that lists all of the computers in a domain running a Windows server OS, like FindServers.vbs in Listing 2 does.

It doesn’t even take much effort to combine these code snippets and create a script that determines the amount of free disk space on all servers in a domain, as DiskSpaceAllServers.vbs in Listing 3 shows. But what do you do when you want to determine the amount of free space every 60 minutes, but the script takes 90 minutes to run against all the computers in your domain? That can take a little bit of creativity because VBScript can only do one thing at a time.

One solution is to break your list of servers into smaller lists and execute the script against each smaller list. However, this solution requires you to manually maintain lists that you'll need to modify every time you add or remove computers from your environment. What if a script could break down your large list of servers into manageable pieces for you? Or better yet, what if you had a separate script that simulates multi-threading for any script you happen to write?

MultiThreader.vbs, which Listing 4 shows, is such a script. It accomplishes three tasks:

  • Queries an external source for a list of computers.
  • Breaks that list of computers into smaller lists.
  • Executes a second "worker" script (i.e., a script that performs a specific job), using the computers in one of the smaller lists as arguments.

How MultiThreader.vbs Works
As always, we start our script with constants and variable declarations, as callout A in Listing 4 shows. We'll want to use this multi-threading script without having to modify it for every worker script we write, so we need to be able to pass in the worker script as an argument. The code at callout B accomplishes this.

Next, we need to obtain the list of servers that we want to execute the worker script against (callout C). In this case, we're using the same method as that used in FindServers.vbs in Listing 2: Query Active Directory (AD) for all computers in the domain that are running a Windows server OS and put those names into a recordset. Alternatively, we could get the computer names from other sources, such as a database or text file. The implementation might be a little different, but the general idea is the same.

Finally, we need to figure out a way to break that computer list into smaller pieces and execute the worker script for each smaller list. As callout D shows, we use the intCount variable to specify how many servers to group in each execution of the worker script. The value of intCount should be tested for your environment. I have successfully used groups with as many as 100 computers, but your results may vary based on the path of the scripts and the names of your computers. Keep in mind that the length of the command we're about to build is finite.

In Windows Script Host (WSH), the Run method of the WshShell object (objShell) lets us execute commands in an external command shell window (i.e., cmd.exe), so that's what we'll use to execute the command that launches the worker script. But first we need to build that command.

The command (strCommand) starts with the worker script's name. We then use VBScript's Do…Loop statement to iterate through the server names returned from the AD query, appending each server name as an argument to that command. The y variable keeps track of how many servers have been added. Once the count in the y variable equals the number of servers specified in the intCount variable, we execute the worker script using the WshShell object's Run method. There are two parameters in use with objShell that need some explanation: bWaitForCompletion and Hide_Window.

The bWaitForCompletion parameter defines whether or not the shell should wait for the external command to complete before continuing MultiThreader.vbs. Since the purpose of MultiThreader.vbs is to kick off multiple instances of a worker script, it’s clear that we don’t want to wait. So, the correct value for this functionality is False, which we defined earlier in the script. If you use the WshShell object in other scripts, you might want the script to wait for the command to finish before moving on. In those scenarios, set the bWaitForCompletion constant to True.

The Hide_Window parameter tells WSH whether or not to show the command shell window during execution. We have chosen to hide it here by setting the constant to the value of 0, but you can choose to show the window by changing this value to 1. There are also other options available. They're described in MSDN's Run Method (Windows Script Host) Web page at http://msdn2.microsoft.com/en-us/library/d5fk67ky.aspx.

After the worker script is launched, we set our count (y) back to 1 and eliminate the arguments that we have appended to the script by setting the command equal to just the name of the worker script. We then start the loop again, building a new command. When the Run method executes this newest command, it opens a new command shell window. This loop continues until it reaches the end of the recordset. After we exit the loop, we execute the worker script one final time if there are any arguments appended to the command.

How to Modify the Worker Script
We now have a script that can execute another script in parallel processes, simulating multi-threaded behavior. The only step left is to modify our worker script to handle a list of servers as an argument. We also need to write the output to a file so that the information is usable. After all, having the information reside in a dozen command shell windows, especially when those windows are hidden, isn’t very useful.

Listing 5 shows the modifications made to DiskSpace.vbs. Callout A in Listing 5 highlights one of the most important changes. This code retrieves the computer names from the command line. Without this code, the worker script won’t know which computers to process.

In callout B in Listing 5, notice that we're collecting all the data in an array before writing it to the output file. One shortcoming of launching a bunch of scripts that perform the same job is that they're all going to want to write to that file. The first script that does so will lock the text file until it’s done writing its data, and you end up losing all the other data. To avoid this problem, we save all the data in memory, then write it to the file all at once.

It's possible that multiple scripts will still try to write at the same time, but the chances are drastically reduced. I'm not going to provide specific examples on how to avoid this condition, but I'll offer two potential workarounds. One approach is to have each worker script write to a separate output file, then manually aggregate the data after all the scripts have finished. A second approach is to relaunch MultiThreader.vbs when a writing error occurs, making sure there is a small delay between launches. If you take the second approach, make sure that you limit the amount of retries. Otherwise, you might find yourself in an infinite loop.

How to Run MultiThreader.vbs
To run MultiThreader.vbs with DiskSpace_Threaded.vbs as the worker script, open a command shell window and execute the command

cscript.exe  MultiThreader.vbs
  "c:\scripts\DiskSpace_Threaded.vbs"

(Although this command wraps here, it should all be on one line in the command shell window.) DiskSpace_Threaded.vbs will now complete in a fraction of the time it would have taken one script to perform that job on all the servers.

One drawback to using multi-threaded scripts is that there is no clear way to tell when the worker scripts have all finished running. MultiThreader.vbs exits as soon as all the worker scripts have been launched. However, you can use Task Manager to see whether cscript.exe is still running. This drawback is a small price to pay when you can have your scripts run in a fraction of the time that they would typically take.

End of Article



Reader Comments
Thank you so much. I found this article to be very useful for some of the task my team needs to implement.

cbragdon February 15, 2008 (Article Rating: )


I'm glad that you found the article useful. If you'd like to see more articles on multi-threading, please let me know.
-- Karen (kbemowski@scriptingprovip.com)

kbemowski@scriptingprovip.com February 15, 2008 (Article Rating: )


You must log on before posting a comment.

If you don't have a username & password, please register now.




Top Viewed ArticlesView all articles
The Memory-Optimization Hoax

Don't believe the hype. At best, RAM optimizers have no effect. At worst, they seriously degrade performance. ...

Managing Virtual Sprawl

As some wise person once said, nothing is ever truly free. Such is the case with VMs, which can quickly mutate from a cost-reducing Dr. Jekyll into a time-consuming, profligate nightmare that would do Mr. Hyde proud. ...

What service packs and fixes are available?

...


Related Articles Another Way to Run Programs

Universal Command-Line Wrapper Tool for WSH

How to Preload Commands in a Command Shell Window

VBScripting Solutions: Emulating Windows Synchronization Objects

Task Automation Whitepapers Continuous Data Protection and Recovery for Microsoft Exchange

Protecting (You and) Your Data with Exchange Server 2007

Related Events Check out our list of Free Email Newsletters!

Task Automation eBooks Spam Fighting and Email Security for the 21st Century

A Guide to Windows Certification and Public Keys

Keeping Your Business Safe from Attack: Patch Management

Related Task Automation Resources Become a VIP member of the Windows IT Pro community!
Get it all with the VIP CD and VIP access. A $500+ value for only $279!

Subscribe to Windows IT Pro!
Solve your toughest technical problems with our experts and access 10,000 + articles online. 30% off

Monthly Online Pass - Only $5.95!
Get instant access to 10,000+ articles from Windows IT Pro Magazine!

TechNet Virtual Labs
Evaluate and test Microsoft's newest products.


ADS BY GOOGLE SPONSORED LINKS FEATURED LINKS

Critical Challenges of ESI & Email Retention
Are you storing too much electronic information? Get expert legal advice and better understanding of what you are required to do as an IT professional.

Become a fan of Windows IT Pro on Facebook!
Join us on Facebook and be a fan of Windows IT Pro!

Sustainable Compliance: Are You Having a Resource Crisis?
Read this white paper to examine trends in compliance and security management and review approaches to reducing the cost and operational burden of compliance.

Rev Up Your IT Know-How with Our Recharged Magazine!
The improved Windows IT Pro provides trusted IT content with an enhanced new look and functionality! Get comprehensive coverage of industry topics, expert advice, and real-world solutions—PLUS access to over 10,000 articles online. Order today!

Get It All with Windows IT Pro VIP
Stock your IT toolbox with every solution ever printed in Windows IT Pro and SQL Server Magazine plus bonus Web-exclusive content on hot topics. Subscribe to receive the VIP CD and a subscription to your choice of Windows IT Pro or SQL Server Magazine!



Order Your Fundamentals CD Today!
Gain an introduction to Exchange, learn server security requirements, and understand how unified communications can play a role in your messaging strategies with this free Exchange CD.
Windows IT Pro Home Register About Us Affiliates / Licensing Media Kit Contact Us/Customer Service  
SQL Connected Home IT Library SuperSite FAQ Wininfo News
Europe Edition Office & SharePoint Pro Windows Dev Pro Windows Excavator 
 
 Windows IT Pro is a Division of Penton Media Inc.
 Copyright © 2008 Penton Media, Inc., All rights reserved. Terms and Use | Privacy Statement | Reprints and Licensing