如何使用批处理脚本ping多个服务器并返回IP地址和主机名?

6

因此,我必须仅使用批处理。基本上,服务器HOSTNAMES都列在一个txt文件中。我使用以下代码Ping所有服务器并在txt文件中显示其结果。

For /f %%i in (testservers.txt) do ping -n 1 %%i >>pingtest.txt

上面ping了所有的服务器。现在,我想要将IP地址和主机名输出到一个单独的文件中。我该怎么做呢? 我知道我可以运行一个for循环搜索像"TTL"这样的单词,然后查找第三个标记(用于IP)和像"PINGING"这样的单词作为第二个标记(HOSTNAME)。但我遇到了错误,无法正确显示它。我想要在不同的文件中输出IP和主机名,是为了制作一个已经DOWN或UP的服务器列表。
将不胜感激。:)
编辑:只是为了不让你们感到困惑,我想让你们知道有三个不同的文件,testservers.txt中有HOSTNAMES,pingtest.txt中有ping结果,result.txt将具有IP地址以及与其当前状态为DOWN或UP的主机名。

这个链接 https://dev59.com/ZnA75IYBdhLWcg3w49UR 可以帮助你。 - SeanC
8个回答

20

很遗憾,你没有发布自己的代码,以便进行更正。
无论如何,这是我自己的解决方案:

@echo off
setlocal enabledelayedexpansion

set OUTPUT_FILE=result.txt
>nul copy nul %OUTPUT_FILE%
for /f %%i in (testservers.txt) do (
    set SERVER_ADDRESS=ADDRESS N/A
    for /f "tokens=1,2,3" %%x in ('ping -n 1 %%i ^&^& echo SERVER_IS_UP') do (
        if %%x==Pinging set SERVER_ADDRESS=%%y
        if %%x==Reply set SERVER_ADDRESS=%%z
        if %%x==SERVER_IS_UP (set SERVER_STATE=UP) else (set SERVER_STATE=DOWN)
    )
    echo %%i [!SERVER_ADDRESS::=!] is !SERVER_STATE! >>%OUTPUT_FILE%
)

外部循环迭代主机,内部循环解析 ping 输出。前两个 if 语句处理 IP 地址解析的两种情况:

  1. 主机名是主机 IP 地址。
  2. 主机 IP 地址可以从其名称解析出来。

如果无法解析主机 IP 地址,则将地址设置为 "ADDRESS N/A"。

希望这可以帮到你。


2
当然可以!这个帖子提供了德语、葡萄牙语、法语和波兰语的样本输出。 - dbenham
1
了不起的EitanT。谢谢你。很抱歉我不能发布我的代码,因为其中有一些属于公司的东西。不能随便发布它。但是无论如何,我所做的事情与此大致相似,只是我使用了两个单独的for循环来提取IP和主机名,但由于这是两个不同的for循环,所以我无法进行“UP”和“DOWN”的检查。 - Gutsygibbon
那么,我需要对上面的脚本做些特殊处理吗?我按照上述指示创建并运行了该脚本,但它将我的内存占满了,达到了16GB,我不得不重新启动服务器。 - Anthony Fornito
@user2566483 我不确定这是否相关,这个脚本本身并没有使用太多的内存。 - Eitan T
它处理目标不可达的情况,但在请求超时时不提取IP。例如,对于msn.com,它显示DOWN,但是当我手动ping它时,我得到“pinging msn.com [23.101.196.141] Request timed out”,因此可以检测到IP,并且此主机从浏览器中也是完全可达的。 - Suncatcher
显示剩余4条评论

4
解析pingtest.txt文件中每个主机名和结果的批处理非常困难,因为名称和结果位于不同的行。直接测试每个PING命令的结果(返回的错误代码)要比重定向到文件更容易。将整个结构括在括号中,并仅重定向最终输出,也更有效率。
>result.txt (
  for /f %%i in (testservers.txt) do ping -n 1 %%i >nul && echo %%i UP||echo %%i DOWN
)

整洁,但这并没有提取IP地址,这需要解析ping而不是将其重定向到“nul”。无论如何+1。 - Eitan T

2
我修改了Eitan-T之前的代码,使其输出为CSV文件。发现之前的代码结果并不总是正确的,所以我进行了改进。
测试服务器列表.txt
SOMESERVER
DUDSERVER

results.csv

HOSTNAME    LONGNAME                    IPADDRESS   STATE 
SOMESERVER  SOMESERVER.DOMAIN.SUF       10.1.1.1    UP 
DUDSERVER   UNRESOLVED                  UNRESOLVED  DOWN 

pingtest.bat

 @echo off
    setlocal enabledelayedexpansion
    set OUTPUT_FILE=result.csv

    >nul copy nul %OUTPUT_FILE%
    echo HOSTNAME,LONGNAME,IPADDRESS,STATE >%OUTPUT_FILE%
    for /f %%i in (testservers.txt) do (
        set SERVER_ADDRESS_I=UNRESOLVED
        set SERVER_ADDRESS_L=UNRESOLVED
        for /f "tokens=1,2,3" %%x in ('ping -n 1 %%i ^&^& echo SERVER_IS_UP') do (
        if %%x==Pinging set SERVER_ADDRESS_L=%%y
        if %%x==Pinging set SERVER_ADDRESS_I=%%z
            if %%x==SERVER_IS_UP (set SERVER_STATE=UP) else (set SERVER_STATE=DOWN)
        )
        echo %%i [!SERVER_ADDRESS_L::=!] !SERVER_ADDRESS_I::=! is !SERVER_STATE!
        echo %%i,!SERVER_ADDRESS_L::=!,!SERVER_ADDRESS_I::=!,!SERVER_STATE! >>%OUTPUT_FILE%
    )

即使服务器宕机并且在 Excel 中轻松可用,它仍然显示 IP 地址。最佳解决方案是什么? - IT hero

0

试试这个

$servers = Get-Content test.txt

$reg=""

foreach ($server in $servers) 

{

$reg=$reg+$server+"`t"+([System.Net.Dns]::GetHostAddresses($server) | foreach {echo $_.IPAddressToString})+"`n"

 }
$reg >reg.csv

你的脚本是Bash编写的。问题是关于批处理的。 - Eitan T
@EitanT,这不是Bash,而是Powershell。 - Suncatcher
@Suncatcher 我改正了。不过,问题的要求仍然是批处理... - Eitan T

0

ping存在的问题是,如果主机不可用,您的本地计算机通常会返回一个答案,即被ping的主机不可用,因此ping的错误代码将为0,并且您的代码将在错误中运行,因为无法识别宕机状态。

最好这样做

ping -n 4 %1 | findstr TTL
if %errorlevel%==0 (goto :eof) else (goto :error)

这样你可以查找一个典型的字符串ttl,它总是在良好的ping结果中,并检查此findstr上的错误,而不是烦人的ping。

总体来说,看起来像这样:

@echo off
SetLocal


set log=path/to/logfile.txt
set check=path/to/checkfile.txt

:start
echo. some echo date >>%log%

:check
for /f %%r in (%check%) do (call :ping %%r)
goto :eof

:ping
ping -n 4 %1 | findstr TTL
if %errorlevel%==0 (goto :eof) else (goto :error)

:error
echo. some errormessage to >>%log%
echo. some blat to mail?

:eof
echo. some good message to >>%log%

0

这个很好用,我只是在ping命令中添加了-a选项来解析主机名。谢谢https://stackoverflow.com/users/4447323/wombat

@echo off setlocal enabledelayedexpansion set OUTPUT_FILE=result.csv

>nul copy nul %OUTPUT_FILE%
echo HOSTNAME,LONGNAME,IPADDRESS,STATE >%OUTPUT_FILE%
for /f %%i in (testservers.txt) do (
    set SERVER_ADDRESS_I=UNRESOLVED
    set SERVER_ADDRESS_L=UNRESOLVED
    for /f "tokens=1,2,3" %%x in ('ping -n 1 -a %%i ^&^& echo SERVER_IS_UP') do (
    if %%x==Pinging set SERVER_ADDRESS_L=%%y
    if %%x==Pinging set SERVER_ADDRESS_I=%%z
        if %%x==SERVER_IS_UP (set SERVER_STATE=UP) else (set SERVER_STATE=DOWN)
    )
    echo %%i [!SERVER_ADDRESS_L::=!] !SERVER_ADDRESS_I::=! is !SERVER_STATE!
    echo %%i,!SERVER_ADDRESS_L::=!,!SERVER_ADDRESS_I::=!,!SERVER_STATE! >>%OUTPUT_FILE%
)

0

@echo off

set workdir={你的工作目录,例如 - C:\work} set iplist=%workdir%\IP-list.txt

setlocal enabledelayedexpansion
set OUTPUT_FILE=%workdir%\result.csv

>nul copy nul %OUTPUT_FILE%
echo HOSTNAME,LONGNAME,IPADDRESS,STATE >%OUTPUT_FILE%
for /f %%i in (%iplist%) do (
    set SERVER_ADDRESS_I=UNRESOLVED
    set SERVER_ADDRESS_L=UNRESOLVED
    for /f "tokens=1,2,3" %%x in ('ping -a -n 1 %%i ^&^& echo SERVER_IS_UP') do (
    if %%x==Pinging set SERVER_ADDRESS_L=%%y
    if %%x==Pinging set SERVER_ADDRESS_I=%%z
        if %%x==SERVER_IS_UP (set SERVER_STATE=UP) else (set SERVER_STATE=DOWN)
    )
    echo %%i [!SERVER_ADDRESS_L::=!] !SERVER_ADDRESS_I::=! is !SERVER_STATE!
    echo %%i,!SERVER_ADDRESS_L::=!,!SERVER_ADDRESS_I::=!,!SERVER_STATE! >>%OUTPUT_FILE%
)

请解释一下你的答案是如何解决问题的,这将有助于每个人更清楚地理解你的解决方案并为将来的参考留下记录。 - Aziz

0

这适用于西班牙操作系统。

脚本接受两个参数:

  • 包含IP或域名列表的文件
  • 输出文件

script.bat listofurls.txt output.txt

@echo off
setlocal enabledelayedexpansion
set OUTPUT_FILE=%2
>nul copy nul %OUTPUT_FILE%
for /f %%i in (%1) do (
    set SERVER_ADDRESS=No se pudo resolver el host
    for /f "tokens=1,2,3,4,5" %%v in ('ping -a -n 1 %%i ^&^& echo SERVER_IS_UP') 
    do (
        if %%v==Haciendo set SERVER_ADDRESS=%%z
        if %%v==Respuesta set SERVER_ADDRESS=%%x
        if %%v==SERVER_IS_UP (set SERVER_STATE=UP) else (set SERVER_STATE=DOWN)
    )
    echo %%i [!SERVER_ADDRESS::=!] is !SERVER_STATE! >>%OUTPUT_FILE%
    echo %%i [!SERVER_ADDRESS::=!] is !SERVER_STATE!
)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接