open source

Script para monitorear dispositivos.

Este pequeño script verifica que un dispositivo responde a ping (echo request) y guarda los cambios de estado en un archivo CSV.

Imágen de portada

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.

Imagen de portada.

unsplash-logoSharon McCutcheon



Comentarios