This is a script I created last year to monitor some files from a Zenoss server.
These files are created by an application that receives CDRs from an Asterisk server in another country, and sometimes these files have stopped getting updated even though no network errors seem to exist, so, the safest way to make sure they were always up to date was to monitor the files' modification time; and we wanted to do it from our central monitoring solution, which happens to be Zenoss.
This is a somewhat specific task, so this script will probably not help others without some modifications, but it shows the use of some concepts and functions that are widely used when creating VB Scripts.
It demonstrates the use of:
-Functions and Procedures
-File I/O (reading and writing files)
-Use of multidimensional arrays
-Date/Time manipulation functions (now,TimeSerial,DateDiff,DatePart,DateAdd,CDate)
-String manipulation functions (Mid,Left,Right,Replace,Len,InStrRev,Split,UCase)
-Execution of WMI queries
Here is the code:
'Script used to generate monitoring information based on the modification time of the specified files
'Designed to provide monitoring information for a Zenoss server
'Requires a parameter file stored in the root of "C" drive, called "time.ini"
'The ini file at most can define 4 files, and 5 time frames per file. File patterns are allowed.
'
'Example of an ini file with 1 file and 1 time frame:
'FILE1=C:sourceORAXMLClient_DIDDebugxml_$dd$mm%
'00:00:00,23:59:59,10
'
'
'This script returns the number of "monitoring periods" passed since the "last modified" time of the files
'Author: Carlos De Leon - 2010
'
'Parameters are stored this way in the parameters array
'Parameters(fileNumber,periodNumber)(parameter value). The third dimension is the parameter value.
'For each timeframe definition:
' The first position is the start time,
' The second one is the end time, and
' The third position is the number of minutes that represent a "monitoring period"
Const ForReading = 1
strFile="c:time.ini"
Dim files(3,1)
Dim parameters(3,4)
fileNumber = -1
PeriodsOld1 = 0
PeriodsOld2 = 0
PeriodsOld3 = 0
PeriodsOld4 = 0
'Read the ini file
ReadOptions
currentDate = now()
currentTime = TimeSerial(DatePart("h",currentDate),DatePart("n",currentDate),DatePart("s",currentDate))
for i = 0 to fileNumber
minutes = getMinsOld(files(i,0),currentDate)
if minutes < 0 then
wscript.quit(1) ' No files found
end if
for j = 0 to files(i,1)
startTime = TimeSerial(mid(parameters(i,j)(0),1,2),mid(parameters(i,j)(0),4,2),mid(parameters(i,j)(0),7,2))
endTime = TimeSerial(mid(parameters(i,j)(1),1,2),mid(parameters(i,j)(1),4,2),mid(parameters(i,j)(1),7,2))
minsPerPeriod = parameters(i,j)(2)
if currentTime >= startTime and currentTime <= endTime then
PeriodLength = minsPerPeriod
exit for
end if
next
periodsOld = minutes/PeriodLength
select case i
case 0
PeriodsOld1 = periodsOld
case 1
PeriodsOld2 = periodsOld
case 2
PeriodsOld3 = periodsOld
case 3
PeriodsOld4 = periodsOld
End Select
next
wscript.echo "PeriodsOld:" & PeriodsOld1 & " PeriodsOld2:" & PeriodsOld2 & " PeriodsOld3:" & PeriodsOld3 & " PeriodsOld4:" & PeriodsOld4
wscript.quit 0
'---------------------------------
' FUNCTIONS AND PROCEDURES
'---------------------------------
sub ReadOptions()
Set objFSO = CreateObject("Scripting.FileSystemObject")
if objFSO.fileexists (strFile) then
Set objTextFile = objFSO.OpenTextFile (strFile, ForReading)
Do Until objTextFile.AtEndOfStream
strTextLine = objTextFile.Readline
'ignore blank lines
if len(trim(strTextLine)) > 0 then
'at most 4 files are allowed
if fileNumber < 4 then
if ucase(mid(strTextLine,1,4)) = "FILE" then
fileNumber = fileNumber + 1
if fileNumber > 0 then
files(fileNumber-1,1) = periodNumber
end if
periodNumber = -1
files(fileNumber,0) = mid(strTextLine,7,len(strTextLine)-6)
else
periodNumber = periodNumber + 1
parameters(fileNumber,periodNumber) = split(strTextLine,",")
end if
end if
end if
loop
files(fileNumber,1) = periodNumber
else
'Ini file not found
wscript.quit(2) 'returning 2 raises the severity and generates an event in the monitoring engine (Zenoss)
end if
End Sub
'---------------------------------
function getMinsOld(files,currentDate)
Dim colFiles
Dim objFSO
'separates drive,dir and pattern
endOfDirPos = InStrRev(files,"")
dir = left(files,endOfDirPos)
initialPattern = mid(files,endOfDirPos+1,len(files)-endOfDirPos)
drive = mid(dir,1,2)
path = replace(mid(dir,3,len(dir)-2),"","")
pattern = constructPattern(initialPattern,currentDate)
getFiles pattern,drive,path,colFiles,objFSO
'if no files are found, tries with the date from the previous day
if colfIles.count = 0 then
pattern = constructPattern(initialPattern,DateAdd("d",-1,currentDate))
getFiles pattern,drive,path,colFiles,objFSO
end if
mins = -1
if colFiles.count > 0 then
For Each File in colFiles
set objFile = objFSO.GetFile(File.Name)
fileMins = datediff("n",CDate( objFile.DateLastModified),now())
'keep the samller value in variable "mins"
if fileMins < mins or mins < 0 then
mins = fileMins
end if
Next
else
getMinsOld = -1 ' 0 files found
end if
getMinsOld = mins
End function
'---------------------------------
function constructPattern(originalPattern,baseDate)
baseYear = DatePart("yyyy",baseDate)
baseMonth = right("0"&DatePart("m",baseDate),2)
baseDay = right("0"&DatePart("d",baseDate),2)
'replace variables with approriate values from the base date
newPattern = replace(replace(replace(replace(originalPattern,"$dd",baseDay),"$mm",baseMonth),"$yyyy",baseYear),"$yy",right(baseYear,2))
constructPattern = newPattern
end function
'---------------------------------
Sub getFiles(filePattern,drive,path,colFiles,objFSO)
'look in the local computer
strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!" & strComputer & "rootcimv2")
query = "Select name,lastmodified from CIM_DataFile where drive = '" & drive & "' and path = '" & path & "' and filename like '" & filePattern & "'"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set colFiles = objWMIService.ExecQuery (query)
end Sub
'---------------------------------
To use this script from the Zenoss server, a new data source must be created, with a command that would use the winexe tool to remotely execute the vb script. Something like this:
/usr/local/zenoss/common/bin/winexe -U "${dev/zWinUser}%${dev/zWinPassword}" //${dev/manageIp} "cscript //NoLogo c:something.vbs"
Feel free to post any comments or doubts in the discussion section below.
Software/Hardware used:
Zenoss server on Ubuntu Linux, Windows Clients
Hi,
Thanks for sharing this script, I think it will be of use to a friend of mine