VBScript - Check Network by Web
Environment
Write this to monitor network via Nagios. It is because can't find one can on Windows, just find some can via Linux
Basically, these need four parts - VBScript, Batch, Wget and NSClient++
Version
2009MAY07
The VBScript code
- Microsoft Windows XP
- Microsoft Windows Server 2003
- Nagios 3.X
- NSClient++ 0.3.5
- Wget 1.10.X
Write this to monitor network via Nagios. It is because can't find one can on Windows, just find some can via Linux
Basically, these need four parts - VBScript, Batch, Wget and NSClient++
- VBScript: analyse and report the netwokr result
- Batch: run Wget to get the performance result, due to there is a problem of getting the result directly on VBScript. If directly, would be report the wrong result to Nagios
- Wget: download the data from the target
Version
2009MAY07
- Solve some bugs
- Improve the coding
- Add status - OK, WARNING, CRITICAL
- Handle can't read the result file, mostly due to speed is too slow
- Add checking intranet
- The first version is just for proxy
The VBScript code
'Which folder of thisThe Batch code
'Due to VBScript bug, can't run a application which folder name is with space,
'therefore, use the name is DOS format which the most easy way
DEFAULT_DIR = "C:\Progra~1\NSClient++\scripts\"
'Run which WGET
DEFAULT_WGET = DEFAULT_DIR & "wget.exe"
'Batch file for running wget
'Due to running WGET at servcice is difficult - set to use which proxy server and run it,
'run it via a batch
DEFAULT_WGET_BAT = DEFAULT_DIR & "RunWget.bat"
'WGET result
DEFAULT_RESULT = DEFAULT_DIR & "result.txt"
'Default value
Const DEFAULT_NOTUSEPROXY = "TRUE"
Const DEFAULT_TRUE = 1
Const DEFAULT_FALSE = -1
'Char for splitting
Const DEFAULT_CHAR_FOR_SPLIT = "***"
'Open text file mode
Const ForReading = 1
Const ForWriting = 2
Const ForAppending = 8
'Status of result report - OK, Warning or Critical
Const DEFAULT_RESULT_OK = 0
Const DEFAULT_RESULT_WARNING = 1
Const DEFAULT_RESULT_CRITICAL = 2
'What speed - Direct or Proxy
Const DEFAULT_DIRECT_SPEED = "Direct"
Const DEFAULT_PROXY_SPEED = "Proxy"
'Use which one units pre seconds
Const DEFAULT_UNIT_KB = "KB/s"
Const DEFAULT_UNIT_MB = "MB/s"
Const DEFAULT_UNIT_GB = "GB/s"
'Filter what
Dim DEFAULT_FILTER_WHAT(3)
DEFAULT_FILTER_WHAT(0) = "HTTP request sent" 'Success request, waiting response
DEFAULT_FILTER_WHAT(1) = "saved" 'Success to visit the site
DEFAULT_FILTER_WHAT(2) = "failed" ' Fail to connect
'Filter for checking what status
Dim DEFAULT_FILTER_STATUS(3)
DEFAULT_FILTER_STATUS(0) = "awaiting response... "
DEFAULT_FILTER_STATUS(1) = "OK"
DEFAULT_FILTER_STATUS(2) = "failed: "
'The default unit if no provide use which one
DEFAULT_UNIT = DEFAULT_UNIT_KB
'For get argument
Set args = WScript.Arguments.Named
'Change the speed unit to the one wanted
'Result format is XXX.XX
'If the formated result < 0.0.1, wil be reutrn 0.00001
'Only accept GB/s, MB/s, KB/s
'Param Double speed
'Param String unit
'Param String finalUnit
'Return Double changeUnit
Function changeUnit(speed, unit, finalUnit)
Dim changedUnit
If unit = finalUnit Then
changedUnit = CDbl(FormatNumber(speed, 2))
Else
Select Case unit
Case DEFAULT_UNIT_KB
If finalUnit = DEFAULT_UNIT_MB Then
changedUnit = CDbl(FormatNumber(speed / 1024, 2, 0, -1 , -1))
Else
changedUnit = CDbl(FormatNumber(speed / 1024 / 1024, 2, 0, -1 , -1))
End If
Case DEFAULT_UNIT_MB
If finalUnit = DEFAULT_UNIT_KB Then
changedUnit = CDbl(FormatNumber(speed * 1024, 2, 0, -1 , -1))
Else
changedUnit = CDbl(FormatNumber(speed / 1024, 2, 0, -1 , -1))
End If
Case DEFAULT_UNIT_GB
If finalUnit = DEFAULT_UNIT_KB Then
changedUnit = CDbl(FormatNumber(speed * 1024 * 1024, 2, 0, -1 , -1))
Else
changedUnit = CDbl(FormatNumber(speed * 1024, 2, 0, -1 , -1))
End If
End Select
End If
'If the wanted unit is too special
If changedUnit = 0.00 Then
changeUnit = 0.00001
Else
changeUnit = changedUnit
End If
End Function
'Filter the result according to split what is wanted
'Param String sResult
'Param Array aSplitWhat
'Return Dictionary filterResult
Function filterResult(sResult, aSplitWhat)
Dim dicFiltered
Set dicFiltered = CreateObject("Scripting.Dictionary")
'Split by VBScript paragraph break
aResult = Split(sResult, VBCrLf)
For Each s in aSplitWhat
For Each i In aResult
'Split the result by the wanted filter
aSplited = Split(i, s)
If UBound(aSplited) >= 1 Then
'If not exits on the result
'Add it the return result
If Not dicFiltered.Exists(i) Then
dicFiltered.Add s, i
End If
End If
Next
Next
Set filterResult = dicFiltered
End Function
'Get a report for Nagios
'Only accept GB/s, MB/s, KB/s
'Param Double speed
'Param String unit
'Param String finalUnit
'Param String whatSpeed
'Param Double warning
'Param Double critical
'Return String getNagiosData -> using || to split performance and status
Function getNagiosData(speed, unit, finalUnit, whatSpeed, warning, critical)
changedSpeedUnit = changeUnit(speed, unit, finalUnit)
status = isWarningOrCritical(changedSpeedUnit, warning, critical)
If warning = DEFAULT_FALSE Then
warning = ""
End If
If critical = DEFAULT_FALSE Then
critical = ""
End If
getNagiosData = whatSpeed & " Speed: " & changedSpeedUnit & finalUnit & " |speed=" & changedSpeedUnit & finalUnit & ";" & warning & ";" & critical & ";***" & status
End Function
'Check if it has a critical unit
'If not, return false
'Return int getCritical
Function getCritical()
If args.Exists("c") Then
critical = args.Item("c")
If IsNumeric(critical) Then
getCritical = CDbl(FormatNumber(critical, 2, 0, -1, -1))
Else
getCritical = DEFAULT_FALSE
End If
Else
getCritical = DEFAULT_FALSE
End If
End Function
'Show help options
Sub getOptions()
WScript.Echo "Get network speed result for Nagios"
WScript.Echo ""
WScript.Echo "/? Show help screen"
WScript.Echo ""
WScript.Echo "/c CRITICAL status if leass than INTEGER units of network speed"
WScript.Echo " WARNING should be provided also"
WScript.Echo ""
WScript.Echo "/n Select to use which unit. It is used for RESULT, WARNING and CRITICAL"
WScript.Echo " If not provide this, will use KB/s"
WScript.Echo " 0: KB/S"
WScript.Echo " 1: MB/S"
WScript.Echo " 2: GB/S"
WScript.Echo ""
WScript.Echo "/p Select to use proxy server"
WScript.Echo " If not provide this, will direct to visit"
WScript.Echo " e.g. /p:http://localhost:8080"
WScript.Echo ""
WScript.Echo "/u Select to visit which site for target"
WScript.Echo " e.g. /u:http://localhost"
WScript.Echo ""
WScript.Echo "/w WARNING status if leass than INTEGER units of network speed"
WScript.Echo " CRITICAL should be provided also"
WScript.Echo ""
WScript.Echo "Example"
WScript.Echo "Direct - C:\cscript CheckNetworkByWeb.vbs /u:http://localhost /n:0 /w:5.5 /c:3.3"
WScript.Echo "Proxy - C:\cscrtip CheckNetworkByWeb.vbs /p:http://localhost:8080 /u:http://localhost /n:0"
End Sub
'Get the speed and unit from the sucess result
'First element: speed
'Second element: unit
'Param String sRequest
'Return Array getSpeedAnUnit
Function getSpeedAndUnit(sRequest)
Dim aRespond(2)
'Split to like this: "09:42:07", "8.69 MB/s) - `index.html' saved [9632]"
split1 = Split(sRequest, "(", 2)
'Split to like this: "8.69 MB/s", " - `index.html' saved [9632]"
split2 = Split(split1(1), ")", 2)
'Split to like this: "8.69", DEFAULT_UNIT_MB
split3 = Split(split2(0), " ", 2)
aRespond(0) = split3(0)
aRespond(1) = split3(1)
getSpeedAndUnit = aRespond
End Function
'Check if it has a unit selection
'If not, use the default unit
'Return String getUnit
Function getUnit()
If args.Exists("n") Then
unit = CInt(args.Item("n"))
If unit = 2 Then
getUnit = DEFAULT_UNIT_GB
ElseIf unit = 1 Then
getUnit = DEFAULT_UNIT_MB
Else
getUnit = DEFAULT_UNIT_KB
End If
Else
getUnit = DEFAULT_UNIT_KB
End If
End Function
'Check if it has a url target
'If not, return false
'e.g. http://hk.yahoo.com
'Return String getURL
Function getURL()
If args.Exists("u") Then
getURL = args.Item("u")
Else
getURL = DEFAULT_FALSE
End If
End Function
'Check if it has a warning unit
'If not, return false
'Retrun int getWarning
Function getWarning()
If args.Exists("w") Then
warning = args.Item("w")
If IsNumeric(warning) Then
getWarning = CDbl(FormatNumber(warning, 2, 0, -1, -1))
Else
getWarning = DEFAULT_FALSE
End If
Else
getWarning = DEFAULT_FALSE
End If
End Function
'Run WGET to get speed result
'WGET is run by batch as not get a easy way to use this on NSClient++
'Assum RunWget.bat at the same folder
'Param String wget: use which wget.exe
'Param String url: use which web site
'Param String useProxy: use which proxy server
'Param String result: where to save result
Function getWgetResult(runWget, wget, url, useProxy, result)
Dim oShell
Set oShell = WScript.CreateObject("WScript.Shell")
'Assum RunWget.bat at the same location. Not use this likes parameter, due to can't run
If useProxy = DEFAULT_NOTUSEPROXY Then
oShell.Run "cmd /c " & runWget & " DIRECT """ & wget & """ """ & result & """ """ & url, 0, True
Else
oShell.Run "cmd /c " & runWget & " PROXY """ & wget & """ """ & result & """ " & url & " " & useProxy, 0, True
End If
End Function
'To check needed parameters are prvodied
'Param String options
'Param String url
'Param int warning
'Param int critical
'Return boolean
Function goToOptions(options, url, warning, critical)
If options = DEFAULT_TRUE Or url = DEFAULT_FALSE Then
goToOptions = DEFAULT_TRUE
ElseIf warning = DEAFULT_FALSE And critical = DEFAULT_FALSE Then
goToOptions = DEFAULT_FALSE
'Warning should be quicker than critical, and critical should be provided
ElseIf warning < critical And critical <= DEFAULT_FALSE Then
goToOptions = DEFAULT_TRUE
Else
goToOptions = DEFAULT_FALSE
End If
End Function
'Check if it is warning or crtical
'speed, arning and critical would be same unit
'0: OK
'1: Warning
'2: Critical
'Param Double speed
'Param Double warning
'Param Double critical
'Return int status
Function isWarningOrCritical(speed, warning, critical)
If speed > warning Then
isWarningOrCritical = DEFAULT_RESULT_OK
ElseIf speed < warning And speed > critical Then
isWarningOrCritical = DEFAULT_RESULT_WARNING
Else
isWarningOrCritical = DEFAULT_RESULT_CRITICAL
End If
End Function
'Read the result file of web access
'VBScript paragraph break default is VBCrLf
'Param String result
Function readResult(result)
Dim oFSO, oFile
'Read the result of web speed
Set oFSO = WScript.CreateObject("Scripting.FileSystemObject")
readResult = DEFAULT_FALSE
'To handle if the result is here
If oFSO.FileExists(result) Then
Set oFile = oFSO.GetFile(result)
Set oReadFile = oFSO.OpenTextFile(result, ForReading)
strContents = oReadFile.ReadAll()
oReadFile.Close
readResult = strContents
End If
End Function
'Remove the result file that is saved before
'For not to read the history
'Param String result
Function removeWgetResult(result)
Dim oShell
Set oShell = WScript.CreateObject("WScript.Shell")
'Remove result.txt
oShell.Run "cmd /c del /q /f " & result, 0, True
End Function
'Check if wanna to show help
'Return boolean
Function showOptions()
If args.Exists("?") Then
showOptions = DEFAULT_TRUE
Else
showOptions = DEFAULT_FALSE
End If
End Function
'Check if it has a use proxy parameter
'e.g. http://localhost:8080
'If not, return the default - Direct
'Return String useProxy
Function useProxy()
If args.Exists("p") Then
useProxy = args.Item("p")
Else
useProxy = DEFAULT_NOTUSEPROXY
End If
End Function
'Find the one wanted in dictionary
'If not find, retrun DEFAULT_FALSE
'Param Dictionary dicRequest
'Param String sFind: find what
'Param String sSplit: split the finded by what
'Param int iPart: wanna return which part
'Return Array aResult
Function whatResult(dicRequest, sFind, sSplit, iPart)
Dim aResult(3)
aResult(0) = DEFAULT_FALSE
If dicRequest.Exists(sFind) Then
aResponse = Split(dicRequest.Item(sFind), sSplit, 2)
'Handle if not have the wanted information
If iPart > UBound(aResponse) Then
iPart = UBound(aResponse)
End If
aResult(0) = DEFAULT_TRUE
aResult(1) = aResponse(iPart)
End If
whatResult = aResult
End Function
'main
Function main()
options = showOptions
proxy = useProxy()
unit = getUnit()
url = getURL()
critical = getCritical()
warning = getWarning()
'Handle still not receive performance data
performance = "Not Received Performance"
status = DEFAULT_RESULT_CRITICAL
'Need to show options?
If goToOptions(options, url, warning, critical) = DEFAULT_TRUE Then
getOptions()
Else
'WGET and Result just uses the defaule one
getWgetResult DEFAULT_WGET_BAT, DEFAULT_WGET, url, proxy, DEFAULT_RESULT
'Wait for the result due to there is running WGET
WScript.Sleep 5000
'Read the result file
sResult = readResult(DEFAULT_RESULT)
Set filteredResult = filterResult(sResult, DEFAULT_FILTER_WHAT)
'Check if it is success
res = whatResult(filteredResult, DEFAULT_FILTER_WHAT(1), DEFAULT_FILTER_STATUS(1), 0)
'Checking Follow by which once is occured most
If res(0) = DEFAULT_TRUE Then
whatSpeed = ""
aSpeedAndUnit = getSpeedAndUnit(res(1))
'Select what speed - proxy / direct
If proxy = DEFAULT_NOTUSEPROXY Then
whatSpeed = DEFAULT_DIRECT_SPEED
Else
whatSpeed = DEFAULT_PROXY_SPEED
End If
'Get the final result for nagios
nagiosData = getNagiosData(aSpeedAndUnit(0), aSpeedAndUnit(1), unit, whatSpeed, warning, critical)
finalRes = Split(nagiosData, DEFAULT_CHAR_FOR_SPLIT)
performance = finalRes(0)
status = finalRes(1)
Else
'Check if it is down
dow = whatResult(filteredResult, DEFAULT_FILTER_WHAT(2), DEFAULT_FILTER_STATUS(2), 1)
If dow(0) = DEFAULT_TRUE Then
performance = dow(1)
status = DEFAULT_RESULT_CRITICAL
Else
'Check if visiting is error
fau = whatResult(filteredResult, DEFAULT_FILTER_WHAT(0), DEFAULT_FILTER_STATUS(0), 1)
If fau(0) = DEFAULT_TRUE Then
performance = "Error: " & fau(1)
status = DEFAULT_RESULT_WARNING
End If
End If
End If
removeWgetResult(DEFAULT_RESULT)
WScript.StdOut.WriteLine performance
'Tell NSClinet++ which status
WScript.Quit(status)
End If
End Function
main()
@ECHO OFF
REM Check if via proxy or direct
IF "%1" == "PROXY" GOTO :PROXY
IF "%1" == "DIRECT" GOTO :DIRECT
:PROXY
set http_proxy=%5
"%2" -o %3 --delete-after -t 1 -T 10 %4
set http_proxy=
GOTO END
:DIRECT
"%2" -o %3 --delete-after -t 1 -T 10 %4
GOTO END
:END