Batch ERRORLEVEL ping response - windows

I'm trying to use a batch file to confirm a network connection using ping. I want to do batch run and then print if the ping was successful or not. The problem is that it always displays 'failure' when run as a batch. Here is the code:
#echo off
cls
ping racer | find "Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),"
if not errorlevel 1 set error=success
if errorlevel 1 set error=failure
cls
echo Result: %error%
pause
'racer' is the name of my computer. I'm having my computer ping itself so I can eliminate the variable of a poor connection. As I said before, the batch always results in failure. Oddly enough, the program works fine if I copy the code into the command prompt. Does anyone know why the program works fine in the command prompt but doesn't work as a batch?
Thanks

A more reliable ping error checking method:
#echo off
set "host=192.168.1.1"
ping -n 1 "%host%" | findstr /r /c:"[0-9] *ms"
if %errorlevel% == 0 (
echo Success.
) else (
echo FAILURE.
)
This works by checking whether a string such as 69 ms or 314ms is printed by ping.
(Translated versions of Windows may print 42 ms (with the space), hence we check for that.)
Reason:
Other proposals, such as matching time= or TTL are not as reliable, because pinging IPv6 addresses doesn't show TTL (at least not on my Windows 7 machine) and translated versions of Windows may show a translated version of the string time=. Also, not only may time= be translated, but sometimes it may be time< rather than time=, as in the case of time<1ms.

If you were to
echo "Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),"
you would see the % is stripped. You need to escape it as % has a special meaning within a batch file:
"Packets: Sent = 4, Received = 4, Lost = 0 (0%% loss),"
However its simpler to use TTL as the indication of success;
.. | find "TTL"

Testing for 0% loss may give a false positive, in this scenario:
Let's say you normally have a network drive on some_IP-address, and you want to find out whether or not it's on.
If that drive is off, and you ping some_IP-address, the IP address from which you ping, will respond:
Answer from your_own_IP-address: target host not reachable
... 0% loss
You might be better off using if exist or if not exist on that network location.

I 'm not exactly sure what the interaction between FIND and setting the error level is, but you can do this quite easily:
#echo off
for /f %%i in ('ping racer ^| find /c "(0%% loss)"') do SET MATCHES=%%i
echo %MATCHES%
This prints 0 if the ping failed, 1 if it succeeded. I made it look for just "0% loss" (not specifically 4 pings) so that the number of pings can be customized.
The percent sign has been doubled so that it's not mistaken for a variable that should be substituted.
The FOR trick serves simply to set the output of a command as the value of an environment variable.

Another variation without using any variable
ping racer -n 1 -w 100>nul || goto :pingerror
...
:pingerror
echo Host down
goto eof
:eof
exit /b

Yes ping fails to return the correct errorlevel. To check the network connection and the computer I used "net view computername" then checked %errorlevel% - simple and easy

First of all
>#echo off
>for /f %%i in ('ping racer ^| find /c "(0%% loss)"') do SET MATCHES=%%i
>echo %MATCHES%
Does not work. If it won't fail, it will detect 0%, because it has 0%.
If it fails, does not work either, because it will have 100% loss, which means, it found the 0% loss part behind the 10
10(0% loss)
Have it detect for 100% loss like so:
>for /f %%i in ('ping -n 1 -l 1 %pc% ^| find /c "(100%% loss)"') do SET check=%%i
Errorlevel might be a bit messed up, but it works like a charm:
>if '%check%'=='1' goto fail
>if '%check%'=='0' echo %pc% is online.&goto starting
1 means it failed
0 means it succeeded
In my script is use links.
Goto fail will go to :fail in my script which will message me that %pc% (which I'll have the user input in the beginning) is offline and will go for another run.
>:fail
>color 0c
>title %pc% is offline
>echo %pc% is offline
>PING -n 6 127.0.0.1>nul
>goto choice
I hope this helps.

The most simple solution to this I can think of:
set error=failure
ping racer -n 1 -w 100>nul 2>&1 && set error=success
Of course, -w needs to be adjusted if on a slow link (100ms might be too short over Dialup ;-))
regards

ping has an errorlevel output value. Success is 0, failure is 1.
Just do this:
C:\>ping 4.2.2.2
Pinging 4.2.2.2 with 32 bytes of data:
Reply from 4.2.2.2: bytes=32 time=28ms TTL=57
Reply from 4.2.2.2: bytes=32 time=29ms TTL=57
Reply from 4.2.2.2: bytes=32 time=30ms TTL=57
Reply from 4.2.2.2: bytes=32 time=29ms TTL=57
Ping statistics for 4.2.2.2:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 28ms, Maximum = 30ms, Average = 29ms
C:\>echo %errorlevel%
0
C:\>ping foo.bar
Ping request could not find host foo.bar. Please check the name and try again.
C:\>echo %errorlevel%
1
As you can see there is no need for all this scripting overkill.

Based on Alex K's note, this works for me on Windows 7:
#echo off
setlocal enableextensions enabledelayedexpansion
for /f %%i in (PCS.TXT) do (
SET bHOSTUP=0
ping -n 2 %%i |find "TTL=" > NUL && SET bHOSTUP=1
IF !bHOSTUP! equ 1 (
CALL :HOSTUP %%i
) else (
CALL :HOSTDOWN %%i
)
)
GOTO EOF
:HOSTUP
echo Host UP %1
GOTO EOF
:HOSTDOWN
echo Host DOWN %1
GOTO EOF
:EOF
exit /B

ping 198.168.57.98 && echo Success || echo failed

I liked the concept of the FIND in the ping results but why not just FIND the Reply from the Address being pinged?
In the example below I enter an IP address as a variable, PING that IP, then look for that variable in the reply string, using the FIND Command.
If the Reply String contains anything other than the correct IP it reports failure.
If you want you can just read the value of ERRORLEVEL from the FIND.
That will give you a reliable value to work with.
#echo off
Set /P IPAdd=Enter Address:
cls
ping %IPAdd% | find "Reply from %IPAdd%:"
if not errorlevel 1 set error=success
if errorlevel 1 set error=failure
cls
echo Result: %error%
pause

I needed to reset a wifi connection because it has issues. This was my quick solution.
#echo off
Rem Microsoft Windows 10 ping test to gateway.
Rem Run batch file from an administrative command prompt.
cls
:starting
Rem Send one ping to the gateway. Write the results to a file.
ping 192.168.1.1 -n 1 > pingtest.txt
Rem Search for unreachable in the file.
c:\windows\system32\findstr.exe "unreachable" pingtest.txt
Rem errorlevel 0 reset the adapter if 1 then wait 10 minutes and test again
if %errorlevel%==1 goto waiting
Rem unreachable was found reset the adapter.
Rem write the date and time the reset was done.
echo Reset date: %date% time: %time% >> resettimes.txt
Rem issue netsh interface show interface to find your adapter's name to reset
Rem my adapter is "wi-fi"
netsh interface set interface "wi-fi" disable
timeout /t 5
netsh interface set interface "wi-fi" enable
:waiting
echo "It is online waiting 10 minutes"
timeout /t 600
goto starting

Related

How to use ping command as a variable to be used as breaking condition in a batch file?

I want to create a batch file to first ping a share drive on start to see if it is ready to be mapped, then map when the ping is returned. As psuedo, something like this:
while true:
ping ipaddr -t
if (ping returned):
break
map drive
I believe the syntax would be something like:
:checkping
ping ipaddr -t
if ping:
goto mountZ
fi
goto checkping
:mountZ
net use Z:....
So how do I go about setting the ping in a usable variable to break the loop?
You could use the below. If there is a TTL (Time To Live) then it will go to A, otherwise it will continue.
:checkping
ping -n 1 www.google.com | findstr TTL && goto a
goto checkping
Break
:a
REM Mapped Drive is connected
:loop
net use K: \\127.0.0.1\C$
If errorlevel 1 goto loop
Is one simple way of doing it.
#echo off
:checkping
ping 8.8.8.8 > nul
IF ERRORLEVEL 1 echo Not Connected & goto checkping
IF ERRORLEVEL 0 echo Connected & net use Z:....
pause

Batch - Ping on Multiple sites

So I want to ping, 20 different sites 15 consecutive times with the same data size and take their Average RTT into a file. But I must also check the same IP for different sizes of ping data, from 8 to 2048 every time multiplied with 2 (8, 16, 32, 64 etc).
I tried to develop my own code and here is what I have so far.
#echo off
CLS
ping -n 1 %1|find "Reply" > nul
CLS
IF %ERRORLEVEL% == 0 ( FOR %%G IN (8,16,32,64,128,256,512,1024,2048) DO (echo Pinging with %%G byte of data... & ping -n 1 -l %%G %1|findstr /x "^.*Request.* ^.*Lost.* ^.*Average.*ms" >> results.txt)) ELSE (ECHO The Server %1 did not respond)
For easier reading:
#echo off
CLS
ping -n 1 %1
CLS
IF %ERRORLEVEL% == 0
(
FOR %%G IN (8,16,32,64,128,256,512,1024,2048) DO
(
echo Pinging with %%G byte of data... &
ping -n 15 -l %%G %1|findstr /x "^.*Request.* ^.*Lost.* ^.*Average.*ms" >> results.txt
)
ELSE
( ECHO "The Server did not respond" )
What I want to accomplish is, a batch file that, accepts 10 (or 15 if it is possible) parameters that are websites ping all of them with 8, 16, 32, ..., 2048 for 15 times each site and also if the server for any reason in some of my ping requests gives me a Request time out, I want to stop the loop for this parameter and continue with the next one but I want it to write to the file that "Request Time Out"
In my code, I am trying to check if the server responds on my ping requests, if I get a reply then begin my FOR loop.
Although, I can't check at any given time if the server still accepts my pings, this happens more often when I have packets of 2048 bytes. If the server give me a "NO" then I get a "Request time out".
So with some kind of code implementation I want to check if the command
ping -n 15 -l %%G %1|findstr /x "^.*Request.* ^.*Lost.* ^.*Average.*ms"
will print Request Time Out so I can stop the ping and move on the next parameter, so it won't bother pinging the same IP 15 times.
Also, with the above implementation I won't have to check at the start of the script if the server responds because it will do it inside the FOR loop.
I believe that the parameter switching is not that hard to implement, it's just a shift and some labels.
Thank you in advance for your time, I will be glad to give you more explanations on the commends below!

Batch script for checking if a server is online

I basically want to have a windows batch script which goes through a list of servers and checks every server with a ping if it is online.
The list of servers should be a simple plain text file and should look something like this:
...
"Google" www.google.com
"Node1" 221.12.123.1
"Download Server" dl.myserver.com
"Login Server" login.myserver.com
...
Here is a simple rundown what the program should do:
print a list of the descriptions of all the servers in the list to the screen.
ping the first server server 4 times if one ping succeeds it should return online if all 4 pings fail it should return offline.
print online or offline next to the first server in the printed list
run step 2 and 3 for all other servers in the list.
The output should look like the following:
...
Google: online
Stackoverflow: online
Node1: online
Download Server: offline
Login server: offline
...
I just want to know if this is even possible in (windows) batch and how to do it. If it isn't possible in batch, what programming language should I use? Would it be possible to program this in Python?
I would also be really thankful if anybody could post the code how to do this, Thanks!
#echo off
setlocal enableextensions enabledelayedexpansion
for /f usebackq^ tokens^=1^,2^ delims^=^" %%a in ("servers.txt") do (
call :isOnline %%b && set "status=online" || set "status=offline"
echo %%a : !status!
)
endlocal
exit /b
:isOnline address
setlocal enableextensions disabledelayedexpansion
:: a temporary file is needed to capture ping output for later processing
set "tempFile=%temp%\%~nx0.%random%.tmp"
:: ping the indicated address and get errorlevel
ping -w 1000 -n 4 %~1 > "%tempFile%" && set "pingError=" || set "pingError=1"
:: When pinging,
::
:: we get errorlevel = 1 when
:: ipv4 - when any packet is lost. It is necessary to check for "TTL="
:: string in the output of the ping command.
:: ipv6 - when all packet are lost.
:: we get errorlevel = 0 when
:: ipv4 - all packets received. But pinging a inactive host on the
:: same subnet result in no packet lost. It is necessary to
:: check for "TTL=" string in the output of the ping command.
:: ipv6 - at least one packet reaches the host.
::
:: +--------------+-------------+
:: | TTL= present | No TTL |
:: +-----------------------+--------------+-------------+
:: | ipv4 errorlevel 0 | OK | ERROR |
:: | errorlevel 1 | OK | ERROR |
:: +-----------------------+--------------+-------------+
:: | ipv6 errorlevel 0 | | OK |
:: | errorlevel 1 | | ERROR |
:: +-----------------------+----------------------------+
::
:: So, if TTL= is present in output, host is online. If errorlevel is 0
:: and the address is ipv6 then host is online. In the rest of the cases
:: the host is offline.
::
:: To determine the ip version, a regular expresion to match a ipv6
:: address is used with findstr. As it will be only tested in the case
:: of no errorlevel, the ip address should be present in the output of
:: ping command.
set "exitCode=1"
find "TTL=" "%tempFile%" >nul 2>nul && set "exitCode=0" || (
if not defined pingError (
findstr /r /c:" [a-f0-9:][a-f0-9]*:[a-f0-9:%%]*[a-f0-9]: " "%tempFile%" >nul 2>nul && set "exitCode=0"
)
)
:: cleanup and return errorlevel
if exist "%tempFile%" del /q "%tempFile%" >nul 2>nul
endlocal & exit /b %exitCode%
This can be done easily in batch, you just need some for /f loops, echo statements, if statements, goto/call statements and use the ping command.
1.print a list of the descriptions of all the servers in the list to the
screen.
You can use echo statement for this, like echo "Google" www.google.com
2.ping the first server server 4 times if one ping succeeds it should
return online if all 4 pings fail it should return offline.
inside a for /f loop [like for /f "tokens=5 delims==, " %%p in (], you can use the ping command with 4 trys like so ping -n 4 www.google.com
3.print online or offline next to the first server in the printed list
you can use and if statemenet here, like so: if "%status%"=="online" echo Google: online or just echo Google: %status%
4.run step 2 and 3 for all other servers in the list.
You can use a goto or a call statement here (use it like a function), for example: call :server_status_function www.google.com

Computer script for auto-reboot on network loss

I am working with a IP Camera network and need a script to run on each individual PC that will perform an auto-reboot when network loss happens. I would like to be able to have the PC ping the servers IP every 5 minutes and upon loss of connectivity the PC will reboot. Each PC has a Camera viewer but periodically looses network connection with the NVR. I found almost the same issue/solution here: http://www.cam-it.org/index.php?topic=2786.0
However the script provided didn't work for me. Below is the script I found and tried but didn't function the way I needed.
#Echo off
REM Put REM in front of Echo off to view the file output
REM ---------------------------------------------------------
REM WATCHDOG.CMD
REM Restarts PC after 3 unsuccessful attempts to PING the
REM POE switch
REM --------------------------------------------------------
SET COUNT=C:\Temp\WATCHDOG.txt
SET POESWITCH=192.168.1.253
SET ERRFLG=0
IF EXIST "%COUNT%" (
SET /P ERRFLG= <%COUNT%
)
IF %ERRFLG% GTR 2 (
Echo Restarting PC in 60 seconds. Run SHUTDOWN -a to abort.
DEL %COUNT%
SHUTDOWN -r -t 60 -f
GOTO :EOF
)
PING -n 1 %POESWITCH%|findstr /I /C:"timed out" /C:"unreachable" /C:"general failure"
if %ERRORLEVEL% == 1 Goto Done
SET /a ERRFLG +=1
ECHO %ERRFLG% > %COUNT%
:Done
(http://www.cam-it.org/index.php?topic=2786.0)
Any suggestions would be greatly appreciated.
Thanks,
Jordan
Add the reboot command and it should work for you to test a URL/IP address every 300 seconds
#echo off
set ip=www.google.com
:loop
ping -n 2 %ip% |find "TTL=" >nul || echo reboot command here
ping -n 300 localhost >nul
goto :loop

Script to start traceroute if continuous ping fails, output to log

I want to continuously ping my home public IP address, and if the ping fails automatically do a traceroute to see where it's failing.
I've been trying to follow the comments made here:
http://social.technet.microsoft.com/Forums/en-US/ITCG/thread/efc97c66-60a6-4fd7-8be4-4b454d040ce5
Windows compatible would be preferable, bat or vbs would be best.
From anywhere on the internet I will lose my connection to my home network. From work I have started a ping and when it drops I've done a traceroute and it fails before it gets to my IP.
I need a log file to prove that it is not my modem, or router, or computer.
#echo off
set Address=google.com
:Loop
PING -n 5 127.0.0.1>nul
echo Pinging %Address%
%SystemRoot%\system32\ping.exe -n 1 %Address% | %SystemRoot%\system32\find.exe "TTL=" > NUL >> C:\pingtest\logfile.log
if %ERRORLEVEL% EQU 0 goto :Loop
echo Trace route %Address% at %date% %time% >> C:\pingtest\logfile.log
tracert %Address% >> C:\pingtest\logfile.log
goto Loop
This is what I ended up going with, if anyone else ever needs this. Essentially the "Ping -n 127.0.0.1>Nul" is to add a 5 second counter so that it only pinged the destination every 5 seconds, 5 can be changed to whatever value is needed.
Windows 7 has this problem where a ping may result with something like "reply from 192.168.1.5: Destination host unreachable". So instead of erroring out it gets a reply from itself and not the error level 1.
Instead of looking for Error Level 1 I choose to look for no result for TTL with "%SystemRoot%\system32\ping.exe -n 1 %Address% | %SystemRoot%\system32\find.exe "TTL=" > NUL"
Anyway, I'm sure the other answers here were very similar and may have worked, so I am ranking them up, but marking this as the answer.
Thanks all!
#echo off
set Address=www.google.com
set LogDir=C:\pingtest
md %LogDir%
%SystemRoot%\explorer.exe "%LogDir%"
echo PingTest script to monitor network connection. Control-C to exit.
echo Tests connection by pinging %Address%. Logs to %LogDir%\logfile.log.
echo %date% %time% Initial tracert (trace route) to %Address% >> %LogDir%\logfile.log
tracert %Address% >> %LogDir%\logfile.log
:Loop
REM 5 second delay
PING -n 5 -w 1 127.0.0.1>nul
echo %date% %time% Pinging %Address%
echo %date% %time% Pinging %Address% >> %LogDir%\logfile.log
%SystemRoot%\system32\ping.exe -n 1 %Address% | %SystemRoot%\system32\find.exe "TTL=" > NUL
if %ERRORLEVEL% EQU 0 goto :Loop
echo %date% %time% PING ERROR - Tracing route to %Address%
echo %date% %time% PING ERROR - Tracing route to %Address% >> %LogDir%\logfile.log
tracert %Address% >> %LogDir%\logfile.log
goto Loop
You could make a simple batch file that tries a ping and if it fails does a tracert, eg:
setlocal
set host=www.bigpond.com
set logfile=nettest.log
echo %date% %time%>>%logfile%
ping %host%>>%logfile%
if ERRORLEVEL 1 tracert %host%>>%logfile
endlocal
There's plenty of scope for refinement here.
Then create a scheduled task that runs it every five minutes or whatever suits you.
Alternatively you could include a loop with a 'sleep' in it. There's a poor man's sleep at Sleeping in a batch file that uses:
choice /d y /t 5 > nul
:LOOP
FOR /F "usebackq tokens=1" %%F IN (`ping localhost -n 1 -w 1 ^| find "Request"`) DO (
IF "%%F"=="Request" (
tracert localhost
)
)>>log.txt
FOR /F "usebackq tokens=1-4 delims=:." %%G IN (`echo %time%`) DO IF %G%H GTR 1400 GOTO:EOF
GOTO LOOP
Basically, this states do ping, if it finds a line that has an instance of the word Request (which only appears if you can't ping the address) perform a tracert. The -n and -w switches in PING tell it to jump only once and timeout after 1 second of not getting a response. This is perfectly fine if you are pinging your localhost. The second FOR statement is to have a stopping point. Change the 1400 to a time you wish for the script to stop (in military time of course).
I have just been looking for the same thing to investigate why a VPN keeps dropping on a wired connection, used one of the batch file suggestions above which was great.
Also found a nice little Java App which packages it for you here
Internet Connectivity Monitor
Simple to use and does the job :-)

Resources