Batch script for checking if a server is online

2020-02-07 08:09发布

问题:

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:

  1. print a list of the descriptions of all the servers in the list to the screen.
  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.
  3. print online or offline next to the first server in the printed list
  4. 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!

回答1:

@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%


回答2:

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