yyyymmdd print batch bat batch-file command-line windows-server-2008

batch-file - print - date format windows bat



Batch Script en el servidor de 2008: si Ping es exitoso, entonces (3)

Intento escribir un script que compruebe si hay una computadora en mi LAN antes de ejecutar el resto de mi script. Es un script de copia de seguridad simple que utiliza robocopy, pero me gustaría que muestre un archivo en función de si fue exitoso o no. Esto es lo que tengo.

set machine=userbox ping -n 1 %machine% > nul if errorlevel 1 goto BAD goto GOOD :GOOD robocopy source destination echo "backup complete" > c:/scripts/backupgood-%machine%.log shutdown /s /m //%machine% /t 600 goto END :BAD echo "Computer not on" > c:/scripts/%machine%-offline.log :END

En este momento, el script no detecta si el sistema está encendido o no y está asumiendo que está activado y continúa con el script como si la máquina pudiera conectarse.

¿Puede alguien señalar por qué el error no está pasando o quizás alguien tiene una mejor manera de determinar si un sistema está en línea?

Gracias por adelantado.


Puede verificar la presencia de su directorio remoto:

IF EXIST "//%machine%/Share/To/Check" ( ECHO %machine% is available. ) ELSE ( ECHO %machine% is not available. )


El "problema" con su código es la gestión del errorlevel para determinar si la máquina está o no en línea.

Las preguntas son: ¿cómo se comporta el ping ?, ¿cuándo se establece errorlevel ?

Si estamos trabajando con ipv6, las reglas son

  • errorlevel se establece cuando no hay respuesta para todos los paquetes enviados (se pierden todos los paquetes)

  • errorlevel no se establece si hay una respuesta a cualquiera de los paquetes enviados

ipv6 tiene un comportamiento constante y la comprobación del errorlevel es una forma confiable de saber si la máquina está en línea.

En ipv4 las reglas son diferentes

  • errorlevel se establece cuando no hay respuesta a al menos uno de los paquetes enviados

  • errorlevel no se establece cuando hay una respuesta a todos los paquetes enviados (no se pierde ningún paquete)

Pero hacer ping a una máquina no disponible en la misma subred no establece el nivel de errorlevel , se obtiene una respuesta "inalcanzable", con n packets sent, n packed received, 0 packets lost , todos los paquetes obtienen una respuesta de la misma máquina que envía los paquetes .

Este comportamiento en ipv4 cuando la máquina está en la misma subred hace que falle la comprobación de errorlevel.

¿Cómo resolver el problema en ipv4?

La salida del comando ping puede verificarse, si la cadena TTL= está presente en la salida, la máquina objetivo está en línea.

ping -n 1 10.0.0.1 | find "TTL=" >nul if errorlevel 1 ( echo offline ) else ( echo online )

Para una solución "general", esto (adaptado de una respuesta anterior) se puede usar (parece mucho código, pero casi todos son comentarios)

@echo off setlocal enableextensions disabledelayedexpansion if "%~1"=="" goto :eof call :isOnline "%~1" if not errorlevel 1 ( echo ONLINE ) else ( echo OFFLINE ) endlocal exit /b :isOnline address pingCount setlocal enableextensions disabledelayedexpansion :: send only one ping packed unless it is indicated to send more than one set /a "pingCount=0", "pingCount+=%~2" >nul 2>nul if %pingCount% lss 1 set "pingCount=1" :: a temporary file is needed to capture ping output for later processing set "tempFile=%temp%/%~nx0.%random%.tmp" :: ping the indicated address getting command output and errorlevel ping -w 1000 -n %pingCount% "%~1" > "%tempFile%" && set "pingError=" || set "pingError=1" :: :: When pinging, the behaviours of ipv4 and ipv6 are different :: :: we get errorlevel = 1 when :: ipv4 - when at least one packet is lost. When sending more than one packet :: the easiest way to check for reply is search the string "TTL=" in :: the output of the command. :: ipv6 - when all packet are lost. :: :: we get errorlevel = 0 when :: ipv4 - all packets are 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 :: :: We can try to determine if the input address (or host name) will result in :: ipv4 or ipv6 pinging, but it is easier to check the result of the command :: :: +--------------+-------------+ :: | 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 TTL= is not present, :: errorlevel is 0 and the address is ipv6 then host is online. In the rest :: of the cases 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 will be present in ping command output. set "exitCode=1" >nul 2>nul ( find "TTL=" "%tempFile%" && ( set "exitCode=0" ) || ( if not defined pingError ( findstr /r /c:" [a-f0-9:][a-f0-9]*:[a-f0-9:%%]*[a-f0-9]: " "%tempFile%" && set "exitCode=0" ) ) del /q "%tempFile%" ) :: cleanup and return errorlevel: 0=online , 1=offline endlocal & exit /b %exitCode%


Gracias a ambos. Intenté ambos, pero al final esto es lo que funcionó para mí

set machine=userbox ping -n 1 %machine% | find "TTL=" >nul IF errorlevel 1 ( echo "Computer Not On" %date% %time% > c:/scripts/%machine%-computeroff.log ) ELSE ( robocopy source destination shutdown.exe /s /m //%machine% /c "Mandatory Shutdown in progress. You have 10 minutes" /t 600 echo "shutdown command given" %date% %time% > c:/scripts/shutdown-%machine%.log

Aclamaciones