24.5.2019
Este pequeño script verifica que un dispositivo responde a ping (echo request) y guarda los cambios de estado en un archivo CSV.
Es posible que en algún momento se te haya presentado la necesidad de verificar si un dispositivo en la LAN pierde conectividad. Si este está conectado a internet no tenemos demasiado problema, se puede utilizar algunos de los servicios gratuitos de monitoreo cómo uptime robot o status cake. ¿Pero qué pasa si el chequeo es interno y no tenemos una gran cantidad de dispositivos que justifique la instalación de un server Zabbix o Nagios?. Fear not my friends, programamos un script en VBScript para que verifique si el host responde un echo request
.
El funcionamiento es bastante simple:
- Hace ping a un objetivo (
testTarget
) que se ingresa como parametro. - Compara la respuesta con el resultado del chequeo anterior.
- Si son distintos: guarda el estado, objetivo y una marca de tiempo en el archivo
estado.csv
. - Sólo se escriben los archivos cuando hay cambios de estado (up o down).
Código y uso.
Copia el código y guardalo como monitor.vbs
. El uso del script es monitor.vbs [IP o dominio]
. Ejemplos:
monitor.vbs 192.168.1.1
monitor.vbs google.com
Const ERR_MISS_PARAM = 1
if WScript.Arguments.Count = 0 then
Wscript.Quit(ERR_MISS_PARAM)
end if
Const ForReading = 1, ForAppending = 8
Dim resultado
Dim fEstado
Dim fUltimoRes
Dim sUltimoRes
Dim basePath
Dim testTarget
basePath = GetScriptPath()
testTarget = WScript.Arguments(0)
fEstado = basePath & "estado.csv"
fUltimoRes = basePath & "ULTIMORES.txt"
' Crear los archivos si no existen
if not FileExists(fEstado) then
resultado = EscribirArchivo(fEstado,"", ForReading)
end if
if not FileExists(fUltimoRes) then
resultado = EscribirArchivo(fUltimoRes,"0", ForReading)
end if
resultado = Ping(testTarget)
' 0: DOWN
' 1: UP
if resultado then
resultado = "1"
else
resultado = "0"
end if
sUltimoRes = LeerConfiguracion(fUltimoRes)
if resultado <> sUltimoRes then
if resultado then
resultado = EscribirArchivo(fUltimoRes,"1", ForReading)
resultado = EscribirArchivo(fEstado,"1;" & testTarget & ";" & TimeStamp, ForAppending)
else
resultado = EscribirArchivo(fUltimoRes,"0", ForReading)
resultado = EscribirArchivo(fEstado,"0;" & testTarget & ";" & TimeStamp, ForAppending)
end if
end if
' =====================
' FUNCIONES AUXILIARES
' =====================
' TIMESTAMP FUNCIONS BY Bill Stewart
' https://social.technet.microsoft.com/Forums/scriptcenter/en-US/adf80daa-a531-4ea6-832a-853394627862/generating-a-timestamp-in-a-log-file-in-a-vbs-script-hosted-by-cscriptexe?forum=ITCG
Function TimeStamp
Dim CurrTime
CurrTime = Now()
TimeStamp = CStr(Year(CurrTime)) & "-" _
& LZ(Month(CurrTime)) & "-" _
& LZ(Day(CurrTime)) & " " _
& LZ(Hour(CurrTime)) & ":" _
& LZ(Minute(CurrTime)) & ":" _
& LZ(Second(CurrTime))
End Function
Function LZ(ByVal Number)
If Number < 10 Then
LZ = "0" & CStr(Number)
Else
LZ = CStr(Number)
End If
End Function
Function Ping( myHostName )
' This function returns True if the specified host could be pinged.
' myHostName can be a computer name or IP address.
' The Win32_PingStatus class used in this function requires Windows XP or later.
' This function is based on the TestPing function in a sample script by Don Jones
' http://www.scriptinganswers.com/vault/computer%20management/default.asp#activedirectoryquickworkstationinventorytxt
Dim colPingResults, objPingResult, strQuery
strQuery = "SELECT * FROM Win32_PingStatus WHERE Address = '" & myHostName & "'"
Set colPingResults = GetObject("winmgmts://./root/cimv2").ExecQuery( strQuery )
For Each objPingResult In colPingResults
If Not IsObject( objPingResult ) Then
Ping = False
ElseIf objPingResult.StatusCode = 0 Then
Ping = True
Else
Ping = False
End If
Next
Set colPingResults = Nothing
End Function
Function FileExists(FilePath)
Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FileExists(FilePath) Then
FileExists=CBool(1)
Else
FileExists=CBool(0)
End If
End Function
Function GetScriptPath()
Set objShell = CreateObject("Wscript.Shell")
Dim strPath
strPath = Wscript.ScriptFullName
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.GetFile(strPath)
Dim strFolder
strFolder = objFSO.GetParentFolderName(objFile)
strFolder = strFolder & "\"
GetScriptPath = strFolder
End Function
Function EjecutarComando(comando)
' Ejecuta un comando de sistema
' Argumento:
' comando [string] Comando a ejecutar
'
' Retorna:
' Codigo de salida del comando, generalmente 0 si termino OK, otro numero si fallo
Set oShell = WScript.CreateObject ("WScript.Shell")
EjecutarComando = oShell.run(comando,0,true)
End Function
Function EscribirArchivo(path, contenido, modo)
' Escribe una cadena de caracteres a un archivo
' Argumento:
' path [string] Ruta donde crear/guardar el archivo sin \ al final
' contenido [string] La cadena de caracteres a almacenar en el archivo
' modo [int] El modo de apertura, 0 sobreescribe - 8 agrega contenido
'
' Retorna:
' El resultado de la operacion, true si escribio correctamente false si fallo
Set objFSO=CreateObject("Scripting.FileSystemObject")
outFile = path
if debugMode then
MsgBox(outFile)
end if
if modo = 8 then
Set objFile = objFSO.OpenTextFile(outFile, ForAppending, True)
objFile.WriteLine contenido
objFile.Close
else
Set objFile2 = objFSO.CreateTextFile(outFile,True)
objFile2.Write contenido
objFile2.Close
end if
End Function
Function LeerConfiguracion(path)
' Ejecuta un comando de sistema
'
Set objFileToRead = CreateObject("Scripting.FileSystemObject").OpenTextFile(path,1)
Dim strFileText
strFileText = objFileToRead.ReadAll()
objFileToRead.Close
Set objFileToRead = Nothing
LeerConfiguracion = strFileText
End Function
Por último, deberías crear una tarea programada para que se ejecute cada determinado tiempo y así tener el sistema de monitoreo completamente automático.