Explain the Batch script to ping multiple computers

Hello,
Please comment and explain each liner of the script.

@echo off
if exist d:\tools\computers.txt goto Label1
echo.
echo Cannot find d:\tools\computers.txt
echo.
Pause
goto :eof

:Label1
echo PingTest executed on %date% at %time% > d:\tools\z.txt
echo ================================================= >> d:\tools\z.txt
for /f %%i in (d:\tools\computers.txt do call :Sub %%i
notepad d:\tools\z.txt
goto :eof

:Sub
echo Testing %1
set state=alive
ping -n 1 %1 | find /i "bytes=" || set state=dead
echo %1 is %state% >> d:\tools\z.txt

December 21st, 2009 11:47am

@echo off
Don't echo these batch file commands to the screen. Using the @ sign means including the current line.
if exist d:\tools\computers.txt goto Label1
If there is a file called d:\tools\computers.txt then jump to the section of the batch file called :Label1
echo.
Type a dot to the screen.
echo Cannot find d:\tools\computers.txt
As the file called  d:\tools\computers.txt  was not found then type "Cannot find Etc." to the screen. This file must exist in the location specified. It presumably contains a list of machine names or IP addresses; one per line.
Pause
Put a prompt on the screen which says "Press any key to continue..." and then wait until a key is pressed.
goto :eof
Go to the end of the batch file (i.e. terminate)

:Label1
Now there is a subsection called Label
echo PingTest executed on %date% at %time% > d:\tools\z.txt
Type the words "PingTest executed on " along with the current date and time " but instead of typing them to the screen, pass them (using the > symbol) to a file called d:\tools\z.txt
for /f %%i in (d:\tools\computers.txt do call :Sub %%i
There's actually a bracket missing from this, so the correct line should read:
for /f %%i in (d:\tools\computers.txt) do call :Sub %%i
Loop through each line of the file d:\tools\computers.txt which presumably contains a list of machine names or IP addresses. Call a subroutine called :Sub passing it the line that's just been read. For example this file might look like:
    193.1.1.1
    193.1.1.2
    193.1.1.200
notepad d:\tools\z.txt
The file d:\tools\z.txt is a log produced by the batch file. This line will launch NotePad with this file so you can view it.
goto :eof
Go to the end of the batch file (i.e. terminate)

:Sub
This is the subsection call Sub which gets called by the For loop.
echo Testing %1
Type to the screen the line that has been passed to this subsection. For example, "Testing 193.1.1.1"
set state=alive
Create a temporary value called "state" which is set to "alive"
ping -n 1 %1 | find /i "bytes=" || set state=dead
Call the PING executable. If you want to know more about this command then type PING /? from the command line. The output from this is then "piped" to the FIND executable which is set to ignore case (/i). Essentially it's looking for the PING command to be returning the text "bytes=" meaning that the IP address or machine name is responding to the ping. If the text is not found (so the find command failed) then the "state" value is changed from "alive" to "dead".
echo %1 is %state% >> d:\tools\z.txt
Type the IP address and the state value (dead or alive) to the file d:\tools\z.txt  . The presence of the two > characters means append rather than overwrite.

There is some very clever batch file stuff in here, especially the use of the FOR command calling the subroutine and passing it a line at a time read from the text file, and then in the subroutine the use of the output piped from the PING command into the FIND command and then setting the state value if the find fails.
Very underrated things batch files.

Free Windows Admin Tool Kit Click here and download it now
December 21st, 2009 1:37pm

Thanks a ton for your quick turn around.

have 2 qq's

1. When i run this script i get the successful ping status only on the command prompt window.
    What do I need to change if i want to get the failed oping status also?

2. Can you provide me any other simple batch file better than this.

Regards,
Suffice
December 23rd, 2009 4:59am

1. Just add this as the last line:
echo %1 is %state%
It will type to the screen the current value the Sub loop is working on (%1) and the value of the parameter state.

2. Better than what? Better than this batch file at identifying if a load of computers are on?
Better than this one you were given as homework?!
No - there is nothing better than this batch file. It's the best batch file in the whole world. Other batch files bow down before it and remark themselves out of existence.....except possibily for this batch file (courtesy of Mark Minasi at Windows IT Pro) which beats it by virtue of being a game:

@echo off
set guessesleft=16
set gamevalue=%random%
echo I'm thinking of a number between 0 and 32767.
echo %gamevalue%
:looptop
set /p latestguess=What's your guess (only %guessesleft% left)?
set guessright=false
set /a guessesleft=%guessesleft%-1

if /i %latestguess% equ %gamevalue% echo You got it! & set guessright=true
if /i %latestguess% lss %gamevalue% echo Too small.
if /i %latestguess% gtr %gamevalue% echo Too large.
if /i %guessesleft% leq 0 goto byebye
if NOT %guessright%==true goto looptop
:byebye
if NOT %guessright%==true echo Sorry ... you used up all your turns. The number was %gamevalue%.
Free Windows Admin Tool Kit Click here and download it now
December 23rd, 2009 10:16am

thanks and merry christmas wishes belated
December 27th, 2009 3:36am

I think this batch bows to that other batch too. :-)

echo I'm thinking of a number between 0 and 32767.
echo %gamevalue%


I'm thinking of a number between 0 and 32767.
16541
What's your guess (only 16 left)?16541
You got it!
  • Proposed as answer by titanyoda Tuesday, March 30, 2010 3:45 AM
Free Windows Admin Tool Kit Click here and download it now
December 27th, 2009 7:24am

Actually, this script is TONS better, more modular and resilient -

The-Cat or whoever wrote the other script; well... it doesn't work. Not for Windows 7. It works for XP, for the most part.

Reason being is that Windows 7 and some other systems do not reply with "bytes=" on each successful line of the ping.

@echo off
set fnm=c:\scripts\computers.txt
set lnm=c:\scripts\pingme.txt

if exist %fnm% goto Label1

echo.
echo Cannot find %fnm%
echo.
Pause
goto :eof

:Label1
echo PingTest STARTED on %date% at %time% > %lnm%
echo ================================================= >> %lnm%
echo.
for /f %%i in (%fnm%) do call :Sub %%i
echo.
echo ================================================= >> %lnm%
echo PingTest ENDED on %date% at %time% >> %lnm%
echo ... now exiting
goto :eof

:Sub
echo Testing %1
set state=alive
ping -n 1 %1
if errorlevel 1 set state=dead
echo %1 is %state% >> %lnm%

[let me know what you think]

TIPS:

1) I always have 2 folders on c: drive - "scripts" and "tools" - where I have most scripts & ... umm... tools
2) I always use variables to make scripts more modular; i.e., set fnm=c:\scripts\computers.txt
3) I always name the "log/results" file the same as the BAT file, but with ".txt" for the suffix
4) I always have a "Time Started" and "Time Ended" in the log/results file
5) Using "errorlevel," in this case, produces more accurate results than testing for "bytes="

Cheers!

 

March 30th, 2010 3:53am

Thanks. This script worked wondefully .
Free Windows Admin Tool Kit Click here and download it now
July 23rd, 2010 6:58am

Hi Titanyoda,

I found the problem and corrected it. It is working now.

 

August 23rd, 2010 5:49pm

Hi,

How can i get the status for continuos period of 20mins,can you please give the batch for the same?

Free Windows Admin Tool Kit Click here and download it now
September 1st, 2010 9:09pm

Actually, this script is TONS better, more modular and resilient -

The-Cat or whoever wrote the other script; well... it doesn't work. Not for Windows 7. It works for XP, for the most part.

Reason being is that Windows 7 and some other systems do not reply with "bytes=" on each successful line of the ping.

@echo off
set fnm=c:\scripts\computers.txt
set lnm=c:\scripts\pingme.txt

if exist %fnm% goto Label1

echo.
echo Cannot find %fnm%
echo.
Pause
goto :eof

:Label1
echo PingTest STARTED on %date% at %time% > %lnm%
echo ================================================= >> %lnm%
echo.
for /f %%i in (%fnm%) do call :Sub %%i
echo.
echo ================================================= >> %lnm%
echo PingTest ENDED on %date% at %time% >> %lnm%
echo ... now exiting
goto :eof

:Sub
echo Testing %1
set state=alive
ping -n 1 %1
if errorlevel 1 set state=dead
echo %1 is %state% >> %lnm%

[let me know what you think]

TIPS:

1) I always have 2 folders on c: drive - "scripts" and "tools" - where I have most scripts & ... umm... tools
2) I always use variables to make scripts more modular; i.e., set fnm=c:\scripts\computers.txt
3) I always name the "log/results" file the same as the BAT file, but with ".txt" for the suffix
4) I always have a "Time Started" and "Time Ended" in the log/results file
5) Using "errorlevel," in this case, produces more accurate results than testing for "bytes="

Cheers!

 

Thanks for the script! Can you also advice how to keep all outputs/ping results in file pingme.txt without overwriting it.

I would like to schedule a task that will execute this script every 2 minutes to check if destination is reachable. But I am not sure, how to modify the script to append/save all ping results in file pingme.txt. Any feedback would be appriciated.

 

Thank you so much!

Vik

 

February 16th, 2011 4:54pm

Thanks for the script! Can you also advice how to keep all outputs/ping results in file pingme.txt without overwriting it.

I would like to schedule a task that will execute this script every 2 minutes to check if destination is reachable. But I am not sure, how to modify the script to append/save all ping results in file pingme.txt. Any feedback would be appriciated.

 

Thank you so much!

Vik

Free Windows Admin Tool Kit Click here and download it now
February 16th, 2011 4:55pm

Change the line immediately after :Label1 to read ...

  echo PingTest STARTED on %date% at %time% >> %lnm%

That is, add another greater than symbol, ">", after the %time% variable.  This converts this line from creating a new file befor writing to appending to an existing file, if one exists.

BTW, a better way to post your question might be to cite this thread in a new question.  That way it is not marked as answered, so more people are likely to revi

February 16th, 2011 6:25pm

Tom,

 

Got you. Thanks a lot. It worked like a charm ;).

 

Vik

Free Windows Admin Tool Kit Click here and download it now
February 16th, 2011 6:37pm

Script works well when i execute it in a command prompt. But I want to schedule the command.

When i create a scheduled task under Windows2003 ( executable name is a .cmd) i get an error "Testing -n" in the command prompt.

What's wrong??

Help,

J

March 1st, 2011 9:22am

great piece of script
Free Windows Admin Tool Kit Click here and download it now
April 3rd, 2011 7:49am

Thanks for the script, i'm working on health check script, i would like to modify the script by adding uptime function to check uptime for 'alive' servers only and include it to the report, any idea how can i do this, i try to google arround but can't find anything similliar to it. Thanks.
May 30th, 2011 9:24am

Try using an internet search engine and putting in the query "How Can I Determine the Uptime for a Server", at which point it will possibly point you in the direction of this VBScript:
http://blogs.technet.com/b/heyscriptingguy/archive/2005/08/02/how-can-i-determine-the-uptime-for-a-server.aspx
Or you might be drawn to this PowerShell version:
http://technet.microsoft.com/en-us/magazine/2008.12.heyscriptingguy.aspx

If you wanted a pure batch file to do this then I reckon you're probably out of luck. You'd need a hybrid solution, perhaps using WMIC which is a command line WMI tool like this:

wmic /NODE:servername PATH "Win32_PerfFormattedData_PerfOS_System" GET "SystemUpTime" /VALUE
Free Windows Admin Tool Kit Click here and download it now
May 31st, 2011 10:36am

Try using an internet search engine and putting in the query "How Can I Determine the Uptime for a Server", at which point it will possibly point you in the direction of this VBScript:
http://blogs.technet.com/b/heyscriptingguy/archive/2005/08/02/how-can-i-determine-the-uptime-for-a-server.aspx
Or you might be drawn to this PowerShell version:
http://technet.microsoft.com/en-us/magazine/2008.12.heyscriptingguy.aspx

If you wanted a pure batch file to do this then I reckon you're probably out of luck. You'd need a hybrid solution, perhaps using WMIC which is a command line WMI tool like this:

wmic /NODE:servername PATH "Win32_PerfFormattedData_PerfOS_System" GET "SystemUpTime" /VALUE


Thanks for the advice, i'm really appriciate it, i'm thinking of using powershell as well, i have the batch script where i can pull the uptime info like below,

@echo off
(for /f "tokens=* delims= " %%a in (c:\batch\Servers.txt) do (uptime.exe %%a /p:2)) >> c:\temp\results.txt
@echo "Result were directed to C:\temp\result.txt"
pause

I'm thinking how it possible to merge it to script provided by titanyoda earlier and make the output to 1 file only.

 

May 31st, 2011 5:46pm

Just add the following to the end of that batch file then. It calls WMIC to get the SystemUpTime but you could use an EXE if you have one that does the same thing:

if %state%==alive wmic /NODE:%1 PATH "Win32_PerfFormattedData_PerfOS_System" GET "SystemUpTime" /VALUE | find "SystemUpTime" >>%lnm%

 

Free Windows Admin Tool Kit Click here and download it now
May 31st, 2011 6:22pm

Thanks it work like a charm, i using 'uptime' tool instead wmic as the output is properly state the uptime;

Health check STARTED on 01/06/2011 at  2:40:30,54
=================================================
Server1a.wmservice.corpnet1.com is alive
\\Server1a.wmservice.corpnet1.com has been up for: 9 day(s), 4 hour(s), 5 minute(s), 56 second(s)
Server1b.wmservice.corpnet1.com is down/unreachable
Server1c.wmservice.corpnet1.com is alive
\\STVSAWN733.wmservice.corpnet1.com has been up for: 9 day(s), 1 hour(s), 32 minute(s), 18 second(s)
=================================================
Health check ENDED on 01/06/2011 at  2:40:50,15

May 31st, 2011 6:43pm

Actually, this script is TONS better, more modular and resilient -

The-Cat or whoever wrote the other script; well... it doesn't work. Not for Windows 7. It works for XP, for the most part.

Reason being is that Windows 7 and some other systems do not reply with "bytes=" on each successful line of the ping.

@echo off
set fnm=c:\scripts\computers.txt
set lnm=c:\scripts\pingme.txt

if exist %fnm% goto Label1

echo.
echo Cannot find %fnm%
echo.
Pause
goto :eof

:Label1
echo PingTest STARTED on %date% at %time% > %lnm%
echo ================================================= >> %lnm%
echo.
for /f %%i in (%fnm%) do call :Sub %%i
echo.
echo ================================================= >> %lnm%
echo PingTest ENDED on %date% at %time% >> %lnm%
echo ... now exiting
goto :eof

:Sub
echo Testing %1
set state=alive
ping -n 1 %1
if errorlevel 1 set state=dead
echo %1 is %state% >> %lnm%

[let me know what you think]

TIPS:

1) I always have 2 folders on c: drive - "scripts" and "tools" - where I have most scripts & ... umm... tools
2) I always use variables to make scripts more modular; i.e., set fnm=c:\scripts\computers.txt
3) I always name the "log/results" file the same as the BAT file, but with ".txt" for the suffix
4) I always have a "Time Started" and "Time Ended" in the log/results file
5) Using "errorlevel," in this case, produces more accurate results than testing for "bytes="

Cheers!

 


How would you be able to record the IP's of each ping test with this script?

It's cool that it tells you if it's working or dead, just would like the IP to be listed as well next to the computer being pinged.  Thanks for all of your help!  This saves me ages of time!

Free Windows Admin Tool Kit Click here and download it now
January 22nd, 2012 2:20am

Actually, this script is TONS better, more modular and resilient -

The-Cat or whoever wrote the other script; well... it doesn't work. Not for Windows 7. It works for XP, for the most part.

Reason being is that Windows 7 and some other systems do not reply with "bytes=" on each successful line of the ping.

@echo off
set fnm=c:\scripts\computers.txt
set lnm=c:\scripts\pingme.txt

if exist %fnm% goto Label1

echo.
echo Cannot find %fnm%
echo.
Pause
goto :eof

:Label1
echo PingTest STARTED on %date% at %time% > %lnm%
echo ================================================= >> %lnm%
echo.
for /f %%i in (%fnm%) do call :Sub %%i
echo.
echo ================================================= >> %lnm%
echo PingTest ENDED on %date% at %time% >> %lnm%
echo ... now exiting
goto :eof

:Sub
echo Testing %1
set state=alive
ping -n 1 %1
if errorlevel 1 set state=dead
echo %1 is %state% >> %lnm%

[let me know what you think]

TIPS:

1) I always have 2 folders on c: drive - "scripts" and "tools" - where I have most scripts & ... umm... tools
2) I always use variables to make scripts more modular; i.e., set fnm=c:\scripts\computers.txt
3) I always name the "log/results" file the same as the BAT file, but with ".txt" for the suffix
4) I always have a "Time Started" and "Time Ended" in the log/results file
5) Using "errorlevel," in this case, produces more accurate results than testing for "bytes="

Cheers!


How would you be able to record the IP's of each ping test with this script?

It's cool that it tells you if it's working or dead, just would like the IP to be listed as well next to the computer being pinged.  Thanks for all of your help!  This saves me ages of time!


Perfect script! But I also would like to know how to modify this script to display the IP address of both "Alive" and "Dead" machine names. Has anyone come across the answer. Thanks again for the great script.
October 23rd, 2012 4:35pm

Asking a question at the end of a long, two year old thread is not the best approach to getting an answer.  It is better to start a new thread that references or links back to the old one.

First, what is the IP number of a machine that is not pingable?

Second, the ping output can be accessed to get IP addresses, when they are present using a FOR statement, something like this ...

:Sub
echo Testing %1
set state=alive
ver | find " 6.">nul && set "option_IP4=-4"||set "option="
set "IPAddr=UNKNOWN"
for /f "tokens=2 delims=[]" %%a in (
  'ping -n 1 %1 %option_IP4%|find "Pinging"') do set IPAddr=%%a
if errorlevel 1 set state=dead
echo Computer %1 at %IPAddr% is %state% >> %lnm%

Note that this assumes you want the IPv4 address on systems that support IPv6.  Otherwise remove the VER test line.

Free Windows Admin Tool Kit Click here and download it now
October 23rd, 2012 5:57pm

Hi Tom I have done what you advised but it didnt work, can you assist further. It simply did not run at all

This is after replacing the script below;

:Sub
echo Testing %1
set state=alive
ver | find " 6.">nul && set "option_IP4=-4"||set "option="
set "IPAddr=UNKNOWN"
for /f "tokens=2 delims=[]" %%a in (
  'ping -n 1 %1 %option_IP4%|find "Pinging"') do set IPAddr=%%a
if errorlevel 1 set state=dead
echo Computer %1 at %IPAddr% is %state% >> %lnm%

Thank you.

August 27th, 2014 6:20am

Hi Tom I have done what you advised but it didnt work, can you assist further.

Two years ago Tom wrote this:

Asking a question at the end of a long, two year old thread is not the best approach to getting an answer.  It is better to start a new thread that references or links back to the old one.

It is now five years after this thread was started. Please do as Tom recommends.

Free Windows Admin Tool Kit Click here and download it now
August 27th, 2014 8:01am

EPIC!
April 16th, 2015 5:06am

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics