VB Script to monitor files on Windows machines from a Zenoss server

85865 pts.
IT Scripts
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:
'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

Dim files(3,1)
Dim parameters(3,4)
fileNumber = -1
PeriodsOld1 = 0
PeriodsOld2 = 0
PeriodsOld3 = 0
PeriodsOld4 = 0

'Read the ini file

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
    periodsOld = minutes/PeriodLength
    select case i
    case 0
        PeriodsOld1 = periodsOld
    case 1
        PeriodsOld2 = periodsOld
    case 2
        PeriodsOld3 = periodsOld
    case 3
        PeriodsOld4 = periodsOld
    End Select

wscript.echo "PeriodsOld:" & PeriodsOld1 & " PeriodsOld2:" & PeriodsOld2 & " PeriodsOld3:" & PeriodsOld3 & " PeriodsOld4:" & PeriodsOld4
wscript.quit 0


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)
                periodNumber = periodNumber + 1
                parameters(fileNumber,periodNumber) = split(strTextLine,",")
                end if
            end if
        end if
    files(fileNumber,1) = periodNumber
  '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
    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

Answer Wiki

Thanks. We'll let you know when a new response is added.

Hi CarlosDL,

Just to say thanks for sharing.
As you say, this is for a specific task but the concepts can be used in a wide variety of scenarios.
I’ll keep this handy 😉

Discuss This Question: 3  Replies

There was an error processing your information. Please try again later.
Thanks. We'll let you know when a new response is added.
Send me notifications when members answer or reply to this question.
  • The Most-Watched IT Questions: September 27, 2011 - ITKE Community Blog
    [...] 1. This isn’t exactly a question, but it is Carlosdl’s entry to IT Knowledge Exchange’s current contest: VB Script to monitor files on Windows machines from a Zenoss server. [...]
    0 pointsBadges:
  • The Most-Watched IT Questions: October 4, 2011 - ITKE Community Blog
    [...] Check out Carlosdl’s VB script to monitor files on Windows machines from a Zenoss server, then submit your [...]
    0 pointsBadges:
  • Cacauetes
    Hi, Thanks for sharing this script, I think it will be of use to a friend of mine :)
    75 pointsBadges:

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to:

To follow this tag...

There was an error processing your information. Please try again later.

Thanks! We'll email you when relevant content is added and updated.


Share this item with your network: