\[Editor's Note: Share your scripting discoveries, comments, problems, solutions, and experiences with products with other readers. Email your contributions (500 words or less) to us at [email protected] We edit submissions for style, grammar, and length. If we print your submission, you'll get $100.\]
In "Query Workstations the Easy Way," September 2002, InstantDoc ID 26054, I discuss the advantages of creating a centralized batch file, Chkws (chkws.cmd), that you can easily expand to handle additional functions. Chkws has been useful, but one problem with batch files that process sequentially is that some commands, such as logging on to a workstation, have a long timeout value when an error occurs. These timeouts can significantly slow down the whole job. But if the batch file could connect to workstations in the background, then even workstations that take longer to finish wouldn't delay the rest of the workstations from continuing to process.
To put this approach into practice, I modified Chkws to use the Start command, which uses another process to start commands. (For the complete modified version of checkws.cmd, see Web Listing 1 at http://www.winscriptingsolutions.com, InstantDoc ID 26368.) The initial script that used this approach yielded two immediate problems. First, when the background jobs began running and logging results, jobs that finished at about the same time found the log file locked and couldn't write to it. Therefore, the results of those jobs were lost. Second, when I moved from testing 50 workstations to testing about 4000, I discovered that because the background jobs started faster than they finished, as the load increased, the jobs quickly consumed system resources and virtual memory. Eventually, the system ground to a halt.
To address these problems, I made two changes to the routine. To solve the logging problem, I changed the script so that instead of logging to a common log file, each job logs to its own text file stored in a temporary directory. At the end of the job, Chkws combines these text files into one file, which it then displays.
To solve the processing problem, I needed to limit the number of processes running at any one time. Doing so meant tracking and counting how many processes were active, then setting a limit on how many could be started at once. To count processes, I modified the WORK subroutine, which Listing 1 shows, in Chkws to first create a temporary file (ending in .beg) at the beginning of the subroutine. The last command of the subroutine deletes this file.
When Chkws starts, instead of immediately calling the WORK subroutine as before, it first calls a subroutine called CHKDIFF, which Listing 2 shows. CHKDIFF counts the number of temporary files to determine the number of active processes by piping the results of a dir /b (bare files) option to a FOR command, which adds up the number of lines in the output and stores the results in the variable PROCNUM. If PROCNUM reaches 30, which means that 30 active processes are active, the subroutine loops until the number of processes drops below 30.
If the number of processes is below the maximum of 30, CHKDIFF continues—using the Start command with the /b option to start another copy of Chkws and pass it the WRK parameter. The /b option causes the new copy of Chkws to start in the background instead of in a new window. Because the option still lets output from the command be displayed to the current window, you can see the workstation names as you can in the previous version of Chkws. When the new copy of Chkws encounters the WRK parameter, that copy skips immediately to the WORK subroutine, executes the WORK subroutine commands, then ends, which also causes the process to end.
I made one other adjustment that contributes to increased performance. Instead of checking the directory count on every loop of the CHKDIFF subroutine—a resource-intensive task—I set "batches" of Start commands to go out 15 at a time. I use the %COUNT% variable to increment to 16, then reset itself. After the count exceeds 15, CHKDIFF performs a directory check.
The modified Chkws script greatly increased the performance of my original chkws.cmd script. The process of scanning 52 workstations for the most recent reboot time went from 2 minutes, 5 seconds to just 8 seconds. The process of determining the Microsoft Internet Explorer (IE) version installed on 2960 workstations went from 2 hours, 5 minutes to a manageable 5 minutes, 50 seconds.
Like the original Chkws, the modified Chkws lets you incorporate almost any type of workstation query into Chkws, including Perl scripts, Windows Script Host (WSH) scripts, or VBScript scripts. With the preceding modifications, even these scripts can see a significant performance increase.