You regularly need to create a report detailing IP address usage in the class C subnet on your network. Manually pinging each address, waiting for a response, and recording the results would take a long time. In addition, because you'd have to manually record each IP address and its ping test result, you're concerned about potential inaccuracies in the report.
Company policy dictates that you can't use freeware or shareware programs on the network, so you decide to write a Windows NT shell script, PingReport.bat, to automate the task. You must meet four requirements:
- The script needs to sequentially ping all the IP addresses in the class C subnet.
- The IP addresses and the subnet must be easily configurable.
- The script needs to ping each IP address twice. For any positive response, the script must make sure an intermediate router didn't give a false-positive response.
- The script needs to record whether or not each IP address was in use in a Comma Separated Values (CSV) file that you can edit in Microsoft Excel.
Meeting Requirement 1
To test each IP address, you need to increment the IP address by 1 in each test loop. You can use the For command with the /l switch to perform this numeric iteration. Specifically, you can use the syntax
Do Command \[parameters\]
In this syntax, %%variable is the iterator variable. If you want to use this syntax for code that you'll run from the command prompt instead of a script, you must use a single percent sign (%) instead of double percent signs (%%) in the iterator variable. (For more information, see my article "Getting Started in NT Shell Scripting, Part 2," April 2000.)
The syntax (start,step,end) denotes that you're iterating through a sequence of numbers from the specified start number to the specified end number by the specified step amount. For example, the code (1,1,5) denotes that you want to iterate from 1 to 5 in increments of 1 (i.e., 1 2 3 4 5). If needed, you can use negative step values to perform a descending iteration. For example, the code (5,-1,1) denotes that you want to iterate from 5 to 1 in increments of -1 (i.e., 5 4 3 2 1). In this case, you want an ascending iteration from 1 to 254 in increments of 1, which means you use the code (1,1,254).
The syntax Do Command \[parameters\] specifies the command that you want to execute in each iteration. The optional \[parameters\] specifies any parameters that the command might need. In this case, you want to execute the Ping command for the 194.100 .57.0 class C subnet. Thus, the code you need to use is
Do Ping 194.100.57.%%i
This For /l loop starts at 18.104.22.168 and pings each address until it reaches 22.214.171.124.
Meeting Requirement 2
To make the IP addresses and subnet easily configurable, you need to replace the starting and ending values of the IP address's last octet (i.e., 1 and 254, respectively) and the subnet address (i.e., 194.100.57) with environment variables. You set these variables at the beginning of the script with code such as
That way, when you want to change the IP address test range, you have to change only these numbers.
Another way to make the script easily configurable is to set a variable for the CSV file's path. In this script, the example location is
Using a variable for the CSV file's path also makes the script more readable, especially if the path is long.
Meeting Requirements 3 and 4
To ping each IP address twice and test any positive responses, you need to move the Ping command out of the For /l loop into a separate block of code called the :NEXT procedure. However, before you create this procedure, you must adapt the For /l loop by replacing the Ping command with two concatenated commands:
- (Set Last_Octet=%%i). Because the iterator variable can exist only within the For /l loop, you need to assign the iterator variable's value to the Last_Octet environment variable so that you can use that value in the :NEXT procedure.
- (Call :NEXT). You use the Call command to move the script's flow to the :NEXT procedure.
Listing 1 shows the :NEXT procedure from PingReport.bat. (You can find the entire script in the Code Library on the Win32 Scripting Journal Web site at http://www.win32scripting.com. The script includes comments to help you understand the code.) As callout A shows, you use a For command with the file token parsing switch (/f) to ping IP addresses and filter the output for positive responses. You initiate two pings (Ping -n 2) to the IP address that the initial For loop provides. The code Find "Reply" tells the Find command to search the Ping command's output for any lines containing the string Reply, which potentially indicates a positive response.
If the Find /f command locates a line containing Reply, it sets that line to an iterator variable. The If /i command in callout B then determines whether the line contains a true-positive or false-positive response. The If /i command compares the string in the iterator variable with the string Reply from %First_3_Octets%.%Last_Octet%, where %First_3_Octets%.%Last_Octet% is the IP address you just pinged. The /i switch specifies that you want a case-insensitive comparison. If the strings match (i.e., a true-positive response indicating the IP address is in use), two actions occur. First, the Echo command outputs a message such as 126.96.36.199 used to the console screen and the CSV file. (An example output file, pingres.csv, is on the Win32 Scripting Journal Web site.) Second, the Goto command moves the script's flow to the :LAST procedure, which, in turn, moves the script's flow back to the For /l command.
If the strings don't match (i.e., a false positive indicating a response from the wrong IP address) or the line doesn't include the word Reply (i.e., no response from the IP address), the Echo command outputs a message such as 188.8.131.52 no response to the console screen and the CSV file. The script then proceeds to the :LAST procedure.
Configuring and Adapting the Script
Before you use PingReport.bat, you must configure the Set commands so that they contain the correct IP addresses, subnet, and CSV file path. You can also easily adapt PingReport.bat to meet any specific needs. For example, if you want to add ping attempts or change the timeout interval from the default of 500 milliseconds (ms), you can adapt the For /f command. In your adaptations, you must
- Enclose any command you nest in the For /f command in single quotes inside the parentheses to let the For command know where the command starts and stops.
- Place a caret (^) in front of any pipe symbols (|) because pipe symbols are reserved shell characters.
- Keep the For /f command on one line. (This rule also applies to any If commands you might adapt in Ping Report.bat. The various For and If commands in Listing 1 are wrapped because of space restrictions.)
One adaptation that I don't encourage you to make is using the @Echo Off command to stop PingReport.bat from echoing messages to the console screen. These messages let you know about the script's progress and might prevent you from prematurely exiting the script.