Better way to use findstr to get packet loss, batch - batch-file

Looking to use findstr to get it to find "0% loss" after a ping command.
Perhaps an array of anything up to "50% loss".
This is for checking and ensuring a connection to the internet is 100% established before launching something online.
Currently it's structured:
ping %ip% -n 3 -w 3000 | findstr "0% loss"
pause
goto Starting
It's currently ignoring findstr and no matter what it refuses to find what I'm looking for
Ideally it would flow like:
ping %ip% -n 3 -w 3000 | findstr "0% loss" || goto Echo
pause
goto Starting
:echo
Could not find "0% loss"
pause
And I have tried that, it will go to echo, but even with 100% connection so it's clearly just not operating how I'd like it to.
Is there a better way to find % packet loss?
Or
Is there a better way to test internet connection, given ping doesn't work when a device is totally offline.

The search string you are looking for is too broad. When you check findstr for "0% loss", you are inadvertently picking up "100% loss" as well. Fortunately, ping puts the packet loss in parentheses, so you can simply include the open parenthesis in the search string.
#echo off
title Restart
color 0A
cls
:start
Cls
set ip=www.google.com
:Pingcheck
echo Checking ping..
timeout /t 3
ping %ip% -n 5 -w 3000 | findstr /C:"(0% loss" || goto Loss
pause
:NoLoss
echo We found 0 packet loss, at %ip% on %date% at %time%
pause
goto start
:Loss
echo We found some packet loss.
pause
I've also changed the name of the :Echo label because echo is already a command and having it also be a label would be confusing.

You can also check ping status with wmi. The advantage to this method is that it'll goto :fail on the first failure, and not continue its lost cause of completing 5 ping attempts, while also providing a simple way to preserve the average response time. It uses set /a to check whether the result of the wmi query contains a numeric value. If it does, pass. If not, fail.
#echo off & setlocal
set "host=www.google.com"
echo Pinging %host%...
for /L %%I in (1,1,5) do (
for /f "delims=" %%x in (
'wmic path win32_pingstatus where "address='%host%' and timeout=3000"^
get ResponseTime /value ^| find "="'
) do (
2>NUL set /a "%%x, avg += ResponseTime" || goto fail
)
)
set /a "avg /= 5"
echo 0%% packet loss. Woo. Average response time was %avg%ms.
exit /b
:fail
echo Aw snap. Packet loss.

Related

Power Management Batch File to shutdown pc when another pc shuts down/hibernates/looses connectivity

this is my first post here so please excuse me for getting anything wrong.
I have a few computers that run Octane renderer. One is the "Master" and the others are "Slaves". When the Master is unreachable the Slaves can't render so I'd like to save money and the environment by having a small batch script for when this happens.
My thinking to a solution was to have a batch script on the Slaves to ping the Master every 5 mins to check there is a connection. When the ping fails it tries again 3 times and if it fails every time the Slave shuts down.
I've got this script from another post here that I did minor edits to : Batch File to reboot pc on network connectivity loss but it doesn't work for what I need. When I run it with the ping ip set to the Master's ip it says my connection is active. When attempting to ping the Master in a command prompt I get "destination host unreachable". Any help would be greatly appreciated!
set ping_ip=1.1.1.1
set failure_count=0
set timeout_secs=300
set connection_error_count=0
set max_connection_error_count=3
:start
:: calling the ping function
call :connection_test
:: Processing the network "up" state
if "%network_state%"=="up" (
echo INFO: You have an active connection.
set connection_error_count=0
) else (
set /a connection_error_count+=1
)
:: Processing the network "down" state
if "%network_state%"=="down" (
if %connection_error_count% geq %max_connection_error_count% (
echo ERROR: You do not have an active connection.
goto poweroff
) else (
echo INFO: FAILURE: That failed [%connection_error_count%] times, NOT good. lets try again...
goto start
)
)
timeout /t %timeout_secs%
goto start
:: connection_test function
goto skip_connection_test
:connection_test
:: Getting the successful ping count
echo INFO: Checking connection, please hang tight for a second...
for /f "tokens=5 delims==, " %%p in ('ping -n 4 %ping_ip% ^| findstr /i "Received"') do set ping_count=%%p
:: Check the ping_count against the failure_count
if "%ping_count%" leq "%failure_count%" (
set network_state=down
) else (
set network_state=up
)
goto :eof
:skip_connection_test
:: Power off
:poweroff
echo INFO: Shutdown PC in 60 seconds. Press any key to abort.
shutdown -s -t 60 -f
pause > nul
shutdown -a
goto end
:end ```
Your code is quite large for something so simple. First, the address you set on ipv4 is not the correct address!
You can access my repository to read how to acquire your IPv4 code here.
After obtain your IPv4 address, add to your code:
ping %ipv4% -n 9 | findstr /i "unreach">filex.txt
set /p stop=<filex.txt
if "%stop%" neq "" (
:: put here your shutdown preferences.
)
If you want something like what you are searching for:
#echo off
:verif
set points=
echo INFO: Checking connection, please hang tight for a second...
ping %ipv4% -n 3 | findstr /i "unreach">filex.txt
set /p stop=<filex.txt
if "%stop%" neq "" set /a points=%points%+1
del /q /f filex.txt
ping %ipv4% -n 3 | findstr /i "unreach">filed.txt
set /p stopd=<filed.txt
if "%stopd%" neq "" set /a points=%points%+1
:: Add points as you want.
if "%points%" geq "2" (
set shutdown=y
)
if "%shutdown%" equ "y" (
echo ERROR: You do not have an active connection.
shutdown -s -t 60 -f
echo INFO: Shutdown PC in 60 seconds. Press any key to abort.
pause>nul
shutdown -a
goto verif
)
echo INFO: You have an active connection.
goto verif
Hope this helps,
K.

How to play sound if phone connects to network?

I try to write a little batch script. It should play a sound if my phone joins my network.
#echo off
:A
ping -n 1 xxx.xxx.xxx.xx | findstr TTL && start airsiren.wav
goto A
The problem is now that if the phone is detected, it repeatedly starts the sound. But it's supposed to just play once.
Does anyone know a simple fix? Maybe with an IF condition?
I haven't been doing much with batch, but I think I got some basic knowledge.
I suggest following code:
#echo off
set "LastExitCode=1"
:Loop
%SystemRoot%\System32\ping.exe -n 1 xxx.xxx.xxx.xx | %SystemRoot%\System32\find.exe /C "TTL" >nul
if not %ErrorLevel% == %LastExitCode% set "LastExitCode=%ErrorLevel%" & if %ErrorLevel% == 0 start "Play sound" airsiren.wav
%SystemRoot%\System32\timeout.exe /T 5 /NOBREAK
if not errorlevel 1 goto Loop
PING outputs a line with TTL if there is a response on echo request and exits usually with value 0 on receiving a response and with 1 on getting no response. But PING does not always exit with 0 on a positive response which is the reason for using FIND.
FIND processes the output of PING and searches for lines containing the string TTL. FIND exits with value 0 on finding at least one line with TTL and otherwise with 1 for indicating no line found containing the search string. The output of FIND to handle STDOUT is of no interest and therefore reduced to a minimum by using option /C and redirected to device NUL.
Now the exit code of FIND is compared with an environment variable which holds last exit value of FIND initialized with value 1.
On current exit code being equal last exit code, there is no change in availability of the pinged device on network and therefore nothing to do.
Otherwise on a difference the current exit code is assigned to the environment variable for next loop run and current exit code is compared with value 0. If this second condition is true the pinged device sent the first time a positive response on echo request by PING. In this case the sound is played.
There is nothing else done on pinged device not available anymore on network, i.e. the exit code changes from 0 to 1.
Then a delay of 5 seconds is started using TIMEOUT with giving the user to break it with Ctrl+C. This reduces the processor core usage giving Windows the possibility to use the processor core for other processes and also reduces network usage when the pinged device is available at the moment on network. And of course the pinged device does not need anymore to permanently response on echo requests.
A jump to label Loop is done if TIMEOUT exited normally without a user break. Otherwise on user pressing Ctrl+C the batch file processing also ends.
TIMEOUT with parameter /NOBREAK requires Windows 7 or a later Windows version.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
find /?
goto /?
if /?
ping /?
set /?
start /?
timeout /?
See also single line with multiple commands using Windows batch file for an explanation of operator & and meaning of if not errorlevel 1.
This can be fixed very easily using %errorlevel% and an IF statement.
Original script by Jelle Geerts.
#ECHO OFF
:Search
ping -n 1 "xxx.xxx.xxx.xx" | findstr /r /c:"[0-9] *ms"
if %errorlevel% == 0 (
echo Device was found!
start airsiren.wav
pause.
) else (
goto Search
)
My solution:
#echo off &:: modem_tester_xp+.bat
REM original https://www.elektroda.pl/rtvforum/topic2917839.html
setlocal EnableDelayedExpansion
rem set connection name (for newer than Win XP) from Network Connections (preferred name doesn't have space)
set _connection_name=internet
rem make file which close this script
echo #echo.^>"%~dpn0.exit"^&#del /q "%%~f0">"%~dp0close_%~nx0"
for /f "tokens=2-4 delims==." %%a in ('wmic os get Version /value ^|find "="') do if "%%~c" neq "" set "_system_version=%%~a.%%~b"
set "_con_ip="
set "_my_ip.last="
:start
::-n (seconds+1)
ping 127.0.0.1 >nul -n 3
set "_my_ip="
if not defined _con_ip call :get_con_ip "%_connection_name%"
if defined _con_ip for /f "tokens=3-5 delims= " %%p in ('route print ^|find " 0.0.0.0 "') do if "%%~r" neq "" if /i "%%~p"=="%_con_ip%" ( set "_my_ip=%%~p" ) else if /i "%%~q"=="%_con_ip%" set "_my_ip=%%~q"
rem if connection lost clean variable _my_ip.last
if not defined _my_ip (
set "_con_ip="
set "_my_ip.last="
) else if /i "%_my_ip%" neq "%_my_ip.last%" (
rem remember last connection addres
set "_my_ip.last=%_my_ip%"
call :2run
)
if not exist "%~dpn0.exit" goto start
del /q "%~dpn0.exit"
endlocal
goto :eof
:get_con_ip &::ConnectionName:return variable _con_ip
if "%_system_version%"=="5.1" (
rem XP find modem address
for /f "tokens=2 delims== " %%a in ('netsh diag show gateway WAN* ^|find "." ^|find "="') do if "!_con_ip!"=="" set "_con_ip=%%~a"
) else (
rem if newer works like win7, if not: if "%_system_version%"=="6.1" (rem Windows 7
if "%~1" neq "" for /f "tokens=1,4* delims= " %%n in ('netsh interface ipv4 show interfaces ^|find /i "%~1"') do if "!_con_ip!"=="" if /i "%%~p"=="%~1" for /f "tokens=1* delims=:" %%i in ('netsh interface ipv4 show addresses %%~n ^|find "." ^|find /i "ip"') do if "!_con_ip!"=="" set "_con_ip=%%~j"
if "!_con_ip!" neq "" set "_con_ip=!_con_ip: =!"
)
goto :eof
:2run
rem run external
rem start "modem started" /min /b cmd /c "echo %date% %time% '%_my_ip%'&pause"
start airsiren.wav
There are two problems with your code
Your code will unconditionally goes to the beginning even after the phone is connected, so it repeats playing the sound. You could use ... && (start airsiren.wav & goto :EOF) to terminate the batch file or use another label other than :EOF to do something else. But this doesn't give you the option to keep monitoring the phone for disconnection and re-connection.
You have to check the setting of the default media player (Typically Windows Media Player) and make sure that it is not set to continuously loop or repeat the media. Also it is overkill and somewhat inconvenient to launch a full fledged media player just for playing back a short notification sound, and usually you have to close the media player afterwards.
So this is the code I propose which solves the above mentioned obstacles by providing the option to continuously monitor the phone's connection status and also provide a more programmatic way to play the notification sound in a self contained player by using a hybrid BAT/JSCript solution.
#if (#Code)==(#BatchScript) /* Hybrid BAT/JScript line */
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set #PlaySound=start "" /b cscript //nologo //e:JScript "%~f0"
set "SoundFile.Connect=%SystemRoot%\media\ringout.wav"
set "SoundFile.Disconnect=?"
set "GenFail.Localized.Text=General failure"
:: set to 0 to disable continuous connection monitoring
set "ContinuousMonitoring=1"
set "PhoneIP=xxx.xxx.xxx.xxx"
set "Timeout=3000"
setlocal EnableDelayedExpansion
set "CheckGeneralFailure=1"
echo [%TIME%] Waiting for connection...
:WaitForConnection
ping -n 1 %PhoneIP% -w %Timeout% | findstr "TTL" >nul && (
echo [!TIME!] Phone Connected.
!#PlaySound! "!SoundFile.Connect!"
if %ContinuousMonitoring% NEQ 0 goto :MonitorConnection
goto :EOF
) || (
if !CheckGeneralFailure! NEQ 0 (
ping -n 1 %PhoneIP% -w 100 | findstr /i /c:"%GenFail.Localized.Text%" >nul && (
ping -n 1 -w %Timeout% 127.255.255.255 >nul
(call,) %= Set errorlevel to 0 =%
) || set "CheckGeneralFailure=0"
)
goto :WaitForConnection
)
:MonitorConnection
ping -n 1 %PhoneIP% | findstr "TTL" >nul && (
ping -n 1 -w %Timeout% 127.255.255.255 >nul
goto :MonitorConnection
) || (
echo [!TIME!] Phone Disconnected.
echo [!TIME!] Waiting for connection...
set "CheckGeneralFailure=1"
REM Play another sound for disconnect?
goto :WaitForConnection
)
goto :EOF
/*** End of batch code ***/
#end
/*** JScript Sound Player ***/
var wmpps = {
Undefined : 0,
Stopped : 1,
Paused : 2,
Playing : 3,
ScanForward : 4,
ScanReverse : 5,
Buffering : 6,
Waiting : 7,
MediaEnded : 8,
Transitioning : 9,
Ready : 10,
Reconnecting : 11,
Last : 12
};
var SoundFile;
if (WScript.Arguments.length) SoundFile = WScript.Arguments(0);
var WaitCount = 0;
var objPlayer = new ActiveXObject("WMPlayer.OCX.7");
with(objPlayer) {
URL = SoundFile;
settings.volume = 100;
settings.setMode("loop", false);
controls.play();
while(playState == wmpps.Transitioning) {
WaitCount+=1;
if (WaitCount > 200) break;
WScript.Sleep(10);
}
if (playState == wmpps.Playing) {
while(playState != wmpps.Stopped) WScript.Sleep(1000);
}
close();
}

In batch, How can i create an IF statement that checks if a variable includes a specific string or data?

I want to make a basic pinger in batch as my learning project and i came into a problem.Here is the code:
#echo off
color B
title Pinger v1.0
:OK
echo.
echo.
set /p t=Target I.P.:
echo.
echo.
echo This is not an IP address!
echo.
goto OK
set /p a=Packet size:
echo.
:start
set ifer=
set /p ifer=Start Ping (y/n):
if %ifer%==y goto 8
if %ifer%==Y goto 8
if %ifer%==n goto OK
if %ifer%==N goto OK
:8
echo.
echo.
echo.
echo.
ping %t% -t -l %a%
My question is, How can i check if t contains a valid IP address an not some random data?
and also, how can i make a code that translates a web address to an ip address(Don't have to answer this though)
I don't know exactly what you're trying to get at here. I made a program that will take your IP or host name and ping it with a user determined packet size, and amount of times to ping. I only tried 1.1.1.1 and www.google.com, but it should work for anything else.
#echo off
#title Pinger v1.1
color B
setlocal EnableDelayedExpansion
:ipInput
cls
set /p tryIP=Target IP:
:: pinging ip once (-n 1) with one byte of data (-l 1) to check if it's valid
ping -n 1 -l 1 !tryIP! >nul & if errorlevel 1 (
echo IP: !tryIP! is invalid, try correcting your input or using a different IP
pause
goto ipInput
)
cls
echo IP: !tryIP! is Valid
set /p pingCount=Enter number of pings:
set /p packets=Enter packet size:
echo Pinging !tryIP! with !packets! bytes for !pingCount! time^(s^)
:: You can either use this line (beneath)
REM ping -n !pingCount! -l !packets! !tryIP!
:: Or you can use this for loop from here.........
:: for /l indicates type of operation in this case it will take (start at, add or
subtract by, end at)
:: %%a in this case, based on /l will always equal the number
:: of times it's looped through..
:: (starting at 1, moving up by 1 each time, and ending after 32)
for /l %%a in (1,1,%pingCount%) do (
ping -n 1 -l !packets! !tryIP! >nul
cls
echo Pinging !tryIP! with !packets! bytes for !pingCount! time^(s^)
set /a percentage=%%a*10000/!pingCount!
if !percentage! LSS 100 echo ......!percentage:~0,0!.!percentage:~0,2!%%
if !percentage! GEQ 100 if !percentage! LSS 1000 echo ......!percentage:~0,1!.!percentage:~1,2!%%
if !percentage! GEQ 1000 echo ......!percentage:~0,2!.!percentage:~2,2!%%
)
:: the if statements are used to correct the formating on the percentages
:: since batch can't use floating point decimals,
:: you have to get a little creative sometimes.
:: dual % signs are so it doesn't think you're trying to set a variable
:: using ( or ) without that >>>^ (eg on lines 20 and 34)
:: will sometimes mess things up.
:: ........ to here. the benefit of a for loop is that you can see your progress,
:: and it's much much faster as the ping command will wait between pings.
echo Done
pause
goto ipInput

batch file for sporadic internet connection

i've seen pingers and auto redials when theres a request time out.
problem:
but im having a hard time researching the 'counter or increment' part.
idea:
heres how it should be:
start pinging continuously while connected to internet,
otherwise
count (or accumulate) request time out until 1min or 60 request time out,
if connection went back after request time out & less than '60 times request time out',reset the
'request time out counter' to zero
if request time out reached 60x :
run another batch or reconnect re-dial up.
loop to internet connection pinging
the closest that i saw:
(but for some reason its not working on my xp)
#echo off
setLocal EnableDelayedExpansion
:loop
ping -n 2 10.174.10.48 >> log
find /i "Reply" < log > nul
if not errorlevel 1 type nul > log & goto :loop
for /f "tokens=1" %%a in ('find /c /i "Request timed out" ^< log') do (
if %%a geq 10 echo file.exe && type nul > log
)
goto :loop
source: http://www.computing.net/answers/programming/ping-bat-file/16605.html
credits to the original poster.
thank you
It would be good to know why the above script is not working. Because possibly other solutions will also not work. If you use a non-English version of windows, you need to replace the text "Reply".
I think the following should work. It just implements the counter. But you can try yourself how you need to set the counter to execute the script after 60 seconds.
#echo off
:reset
set count=0
:loop
ping -n 2 10.174.10.48 | find /i "Reply"
if not errorlevel 1 goto :reset
set /A count=%count%+1
if %count% lss 100 got :loop
call reconnect
goto :reset

Batch file - loop ping - output to file hosts that are up

I would like to make a .bat file that will do a for loop like below:
#echo off
FOR /L %%G IN (1, 1, 69) DO (
ping -n 1 192.168.%%G.3
ping -n 1 192.168.%%G.4
)
Then look through the output and send only the IPs that replied successfully to the ping to a txt file. Is this possible with a CMD batch file?
#ECHO OFF
SET output=%USERPROFILE%\output.txt
IF EXIST "%output%" DEL "%output%"
FOR /L %%G IN (1, 1, 69) DO (
CALL :ping 192.168.%%G.3
CALL :ping 192.168.%%G.4
)
GOTO :EOF
:ping
ping -n 1 %1 >NUL && ECHO %1>>"%output%"
Basically, you use && to add the command that is only executed if the previous command (the one before the &&) completed successfully (technically speaking, returned the exit code of 0).
There's a similar approach for the opposite case. If you want to perform some actions on the unsuccessful result of a command, you put || after it and then the command implementing your action.
EDIT
One note about ping. Sometimes you get a notification from the router that the host is not accessible. In this case ping still exits with 0 code ('successful'), because it does get a reply, even if it's from the router and not from the actual host.
If that can be the case with your hosts and you don't want to have such false positives in the output file, you'll have to parse the output of ping for some keywords indicating whether the pinging was successful indeed. So far you can rely on the lines showing the aggregate stats: they only appear if the reply was from the intended host.
So, here's the alternative approach:
#ECHO OFF
SET output=%USERPROFILE%\output.txt
IF EXIST "%output%" DEL "%output%"
FOR /L %%G IN (1, 1, 69) DO (
CALL :ping 192.168.%%G.3
CALL :ping 192.168.%%G.4
)
GOTO :EOF
:ping
ping -n 1 %1 | find "Approximate round trip" >NUL && ECHO %1>>"%output%"
EDIT 2
Changed both solutions to use subroutine call in order to avoid premature expansion of %ip% inside the for loop. (Could also be fixed by enabling delayed expansion instead.)
Also quoted %output% everywhere.
#echo off
:A
FOR /L %%G IN (1, 1, 69) DO (
ping -n 1 192.168.%%G.3
ping -n 1 192.168.%%G.4
)
:GoTo

Resources