command-linebatch-fileping

How to check if ping responded or not in a batch file


I want to continuously ping a server and see a message box when ever it responds i.e. server is currently down. I want to do it through batch file.

I can show a message box as said here Show a popup/message box from a Windows batch file

and can ping continuously by

ping <servername> -t

But how do I check if it responded or not?


Solution

  • The following checklink.cmd program is a good place to start. It relies on the fact that you can do a single-shot ping and that, if successful, the output will contain the line:

    Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
    

    By extracting tokens 5 and 7 and checking they're respectively "Received" and "1,", you can detect the success.

    @setlocal enableextensions enabledelayedexpansion
    @echo off
    set ipaddr=%1
    :loop
    set state=down
    for /f "tokens=5,6,7" %%a in ('ping -n 1 !ipaddr!') do (
        if "x%%b"=="xunreachable." goto :endloop
        if "x%%a"=="xReceived" if "x%%c"=="x1,"  set state=up
    )
    :endloop
    echo.Link is !state!
    ping -n 6 127.0.0.1 >nul: 2>nul:
    goto :loop
    endlocal
    

    Call it with the name (or IP address) you want to test:

    checklink 127.0.0.1
    checklink localhost
    checklink nosuchaddress
    

    Take into account that, if your locale is not English, you must replace Received with the corresponding keyword in your locale, for example recibidos for Spanish. Do a test ping to discover what keyword is used in your locale.


    To only notify you when the state changes, you can use:

    @setlocal enableextensions enabledelayedexpansion
    @echo off
    set ipaddr=%1
    set oldstate=neither
    :loop
    set state=down
    for /f "tokens=5,7" %%a in ('ping -n 1 !ipaddr!') do (
        if "x%%a"=="xReceived" if "x%%b"=="x1," set state=up
    )
    if not !state!==!oldstate! (
        echo.Link is !state!
        set oldstate=!state!
    )
    ping -n 2 127.0.0.1 >nul: 2>nul:
    goto :loop
    endlocal
    

    However, as Gabe points out in a comment, you can just use ERRORLEVEL so the equivalent of that second script above becomes:

    @setlocal enableextensions enabledelayedexpansion
    @echo off
    set ipaddr=%1
    set oldstate=neither
    :loop
    set state=up
    ping -n 1 !ipaddr! >nul: 2>nul:
    if not !errorlevel!==0 set state=down
    if not !state!==!oldstate! (
        echo.Link is !state!
        set oldstate=!state!
    )
    ping -n 2 127.0.0.1 >nul: 2>nul:
    goto :loop
    endlocal