Here's a familiar—and frustrating— scenario: Your IT team needs to deploy multiple Windows hotfixes on several hundred PCs overnight. But you can't push the patches out to all the PCs because inevitably, some users shut down their systems at the end of the day. If you can't force users to leave their PCs on, you can at least obtain statistics about your user community, such as how many PCs are on at any given time, which can improve your chances of successful deployments.

I wrote a script that provides such information. GetNodePingStatus produces a report that tells how many PCs (i.e., nodes) are on at any time. You can also use the script to ping a list of nodes and generate a report that tells you which of those nodes are offline. GetNodePingStatus removes all pingable nodes from the list each time it runs. By running the script for several days, you'll develop an accurate picture of how many nodes are online (and when) and which nodes are never on or might not even exist. This information can help you determine how much time you'll need to push a hotfix out to the greatest number of PCs. You can also use the statistics that GetNodePingStatus provides to clean up your Active Directory (AD) or PC inventory-control system by deleting defunct nodes.

Script Breakdown
GetNodePingStatus begins by obtaining a date and timestamp and setting the on and off counters to zero. The script uses the counters to determine the total number of nodes it's successfully pinged. After GetNodePingStatus performs these initial tasks, it executes either the nonincrementing or incrementing section of code, depending on the mode in which you run the script. The default is nonincremental mode, which returns statistics about the nodes' on or off status and echoes them to the log file once each time the script is run. In incremental mode, the script rotates the output file (i.e., reuses it as an input file) so that it can generate a running list of unsuccessfully pinged nodes on any run of the script.

In both the nonincremental and incremental modes, GetNodePing- Status performs three simple steps:

  1. Retrieves a node name from the input file, which contains one node name per line. The code at callouts A and D in Listing 1 performs this action.
  2. Performs a Ping test on that node, as the code at callouts B and E shows.
  3. Logs the results to a file. In incremental mode, the script uses the results as an input file, as the code at callout C shows. In nonincremental mode, the script distributes those results, as the code at callout F shows.

I use some special coding techniques in GetNodePingStatus. I include code to handle spaces in pathnames for input and output files and to rotate the input file. In addition to these techniques, I also reuse some code in the incrementing and nonincrementing sections. (For more information about reusing code, see the sidebar "Expanding Scope for Your Scripts,")

Handling spaces.Coding to accommodate spaces in the input and output file pathnames is problematic. You can code the output file pathname by encapsulating the output variable in double quotes. The following code echoes the %results% variable's value to the output file specified in the Set command:

Set output=D:\myscripts
  \output file.txt
Echo %results%>>"%output%"

Coding to handle spaces in input file paths is trickier because the For command doesn't support spaces in the input file pathname. The following code works as long as the pathname has no spaces but fails if the pathname includes a space:

Set InputList1=
For /f "tokens=1,*" %%i in
  (%InputList1%) Do
  (Set Target=%%i) &
  (Call :Pingit)

Fortunately, in Windows 2000 and later, the For command supports the usebackq switch, which lets you specify the use of double quotes to encapsulate a file path to be parsed so that the double-quoted contents aren't treated as a string or command to be executed. The following sample command shows how to use usebackq and successfully handles paths with and without spaces:

Set InputList1=
For /f "tokens=1,* usebackq"
  %%i in ("%InputList1%") Do
  (Set Target=%%i) &
  (Call :Pingit)

Rotating the input file. Typically, you use a static input file in scripts. This input file might contain a list of servers or PCs on which you want to perform an operation. In the incrementing section of GetNodePingStatus, I use the output file that contains a list of failed nodes, which was created in the previous script run, as the input file on the next run.

You can use any of several methods to rotate the input file. Regardless of the method you use, though, you need a working copy of the original input file so that you can rerun the script from that starting point. If the script modifies the original input file, you might not be able to recreate it or it might not match the original file. When you run GetNodePingStatus and it doesn't find the working copy, this simply means that the script is on a first run and will create the working copy. The Move command at callout C overwrites the previous working copy of the input file and prepares the script for the next run.

Using GetNodePingStatus
To use GetNodePingStatus, first download the GetNodePingStatus.bat script from the Windows Scripting SolutionsWeb site at http://www.winnetmag .com/windowsscripting, enter Instant- Doc ID 43310 in the InstantDoc ID box, then click the hotlink. (Column widths in the printed publication force us to wrap code lines, which might cause the printed code to run incorrectly.) Then, create a folder location for the script. The script will automatically locate and create the report files in that folder location.

By default, the output files will be comma-separated value (.csv) files that you can open and edit in Microsoft Excel. If you want to use a text or tab-separated value (.tsv) file format, you need to modify the script and change the output file extension to .txt or .tsv, respectively.

As I mentioned earlier, you can run GetNodePingStatus in incremental mode or nonincremental mode. To launch the script in incremental node, run the command

getnodepingstatus.bat -inc

The -inc switch specifies incremental mode. To run the script in the default nonincremental mode, run the same command without the -inc switch.

Useful Information
GetNodePingStatus lets you gather valuable statistics about your PCs' online and offline status. In doing so, you might learn some surprising information about your PC community. For instance, when I ran Get- NodePingStatus in my organization, I discovered that many more of our users' PCs were on at night than I expected. I also discovered that many PCs in our active inventory list weren't actually online. This discovery motivated us to reevaluate the validity of our inventory-control system information. When you run GetNode- PingStatus, you'll probably discover some interesting trends in your own environment.