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