Print Audit

This print audit script simply grabs event log entries for successful prints from the Windows Event Log which I have used on a Windows print server meaning I can rather crudely examine how many pages have been printed between W and X dates, by user Y or and/on printer Z.

Ultimately this is a bit scrappy and there are some nasty nested IFs but I'm not an architect so don't be looking for such gracious code here (also pastebin has wrapped some of the lines around so grab this script by clicking the raw link for pastebin);

' EventLogFSO.vbs
' Sample VBScript to write event log data to text file
' Author Guy Thomas http://computerperformance.co.uk/
' Version 1.7 - May 2006
'
' Stolen and modified by James Bensley Jan 2010
' Converted to perform crude print auditing
'
' ------------------------------------------------------------------------------------------------


' ----------------------------------------DECLARATIONS--------------------------------------------

Option Explicit 'Good coding practice

Dim objFSO, objWMI, objItem, objShell, objLogFile
Dim strComputer, strPrinterName, strUsername, strLogFile, strLogDump, strLogType, strDateFrom, strDateTo
Dim intEvent, intEventType, intNumberID, intRecordNum, colLoggedEvents, intReadMode
Dim intPages, intTotalPages
Dim intArgCount, intL
Dim bolPageCError
Dim intMsgSize, intStart, intEnd, intDif, strGetPrinterName, strDatePrint

intArgCount = 5
intMsgSize = 255 ' Limit the size of the print message from the event log in case of events such as printing web pages,
' entries in the event log go a bit crazy logging giant URLs that can cause the script to hang :S


' ------------------------------------------------------------------------------------------------


' -----------------------------------------MAIN LOOP----------------------------------------------

' Check the parsed arguments
Argumentative()

' Event ID Number
intNumberID = 10
' 1 = Error, 2 = Warning, 3 = Information, 4 = Success, 5 = Failure
intEventType = 3
' The successful prints are just an information log
' Within the System log so type 3 is used here!?!?

strLogType = "'System'" ' Note the single quotes within doubles


' -----------------------------------------------------
' Section to create folder and hold file.
' Create the File System Object
Set objFSO = CreateObject("Scripting.FileSystemObject")

' Check weather are log file exists
If Not objFSO.FileExists(strLogFile) Then
       objFSO.CreateTextFile(strLogFile) ' If not then create it
       ' and set the read mode
       intReadMode = 2 ' 2 is for writing
Else
       intReadMode = 8 ' 8 is for appending
End If

strLogDump = "Started at: " & Date & "-" & Time & vbNewLine & vbNewLine

Wscript.echo "Starting record scan with arguments: " & strComputer & " " & strPrinterName & " " & strUsername & " " & strDateFrom & " " & strDateTo & " " & strLogFile


' ----------------------------------------------------------
' WMI Core Section
Set objWMI = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate,(Security)}!\\" _
& strComputer & "\root\cimv2")
Set colLoggedEvents = objWMI.ExecQuery _
("Select * from Win32_NTLogEvent Where Logfile =" & strLogType)


' ----------------------------------------------------------
' Next section loops through ID properties

' Reset our record counter for successful prints
intRecordNum = 0
intTotalPages = 0

For Each objItem in colLoggedEvents ' Loop round all returned records

       If objItem.EventCode = intNumberID Then ' Is it the correct EventID?

               If objItem.EventType = intEventType Then ' Is it the correct EventType?

                       'Get the date of the print event
                       strDatePrint = Mid(objItem.TimeWritten,5,2) & "/" & Mid(objItem.TimeWritten,7,2) & "/" & Left(objItem.TimeWritten,4)

                       intStart = InStr(objItem.Message,"was printed on") + 15
                       intEnd = InStr(intStart,objItem.Message," via")
                       intDif = intEnd - intStart

                       strGetPrinterName = Mid(objItem.Message,intStart,intDif) ' Get the printer name

                       If strPrinterName = "*" Then

                               If strUsername = "*" Then

                                       If strDateFrom = "*" Then

                                               LogEvent strDatePrint, Mid(objItem.TimeWritten,9,2) & ":" & Mid(objItem.TimeWritten,11,2) & ":" & Mid(objItem.TimeWritten,13,2), objItem.ComputerName, objItem.Logfile, objItem.SourceName, objItem.EventCode, objItem.EventType, objItem.Type, objItem.User, Right(objItem.Message,(Len(objItem.Message) - InStr(objItem.Message, "pages printed: ")) - 14), Left(objItem.Message, intMsgSize), strGetPrinterName

                                       ElseIf DateDiff("d", strDatePrint, strDateFrom) <= 0 Then

                                               If DateDiff("d", strDatePrint, strDateTo) >=0  Then

                                                       LogEvent strDatePrint, Mid(objItem.TimeWritten,9,2) & ":" & Mid(objItem.TimeWritten,11,2) & ":" & Mid(objItem.TimeWritten,13,2), objItem.ComputerName, objItem.Logfile, objItem.SourceName, objItem.EventCode, objItem.EventType, objItem.Type, objItem.User, Right(objItem.Message,(Len(objItem.Message) - InStr(objItem.Message, "pages printed: ")) - 14), Left(objItem.Message, intMsgSize), strGetPrinterName

                                               End If

                                       End If

                               ElseIf strUsername = objItem.User Then

                                       If strDateFrom = "*" Then

                                               LogEvent strDatePrint, Mid(objItem.TimeWritten,9,2) & ":" & Mid(objItem.TimeWritten,11,2) & ":" & Mid(objItem.TimeWritten,13,2), objItem.ComputerName, objItem.Logfile, objItem.SourceName, objItem.EventCode, objItem.EventType, objItem.Type, objItem.User, Right(objItem.Message,(Len(objItem.Message) - InStr(objItem.Message, "pages printed: ")) - 14), Left(objItem.Message, intMsgSize), strGetPrinterName

                                       ElseIf DateDiff("d", strDatePrint, strDateFrom) <= 0 Then

                                               If DateDiff("d", strDatePrint, strDateTo) >=0  Then

                                                       LogEvent strDatePrint, Mid(objItem.TimeWritten,9,2) & ":" & Mid(objItem.TimeWritten,11,2) & ":" & Mid(objItem.TimeWritten,13,2), objItem.ComputerName, objItem.Logfile, objItem.SourceName, objItem.EventCode, objItem.EventType, objItem.Type, objItem.User, Right(objItem.Message,(Len(objItem.Message) - InStr(objItem.Message, "pages printed: ")) - 14), Left(objItem.Message, intMsgSize), strGetPrinterName

                                               End If

                                       End If

                               End If ' Username If

                       ElseIf strPrinterName = strGetPrinterName Then

                               If strUsername = "*" Then

                                       If strDateFrom = "*" Then

                                               LogEvent strDatePrint, Mid(objItem.TimeWritten,9,2) & ":" & Mid(objItem.TimeWritten,11,2) & ":" & Mid(objItem.TimeWritten,13,2), objItem.ComputerName, objItem.Logfile, objItem.SourceName, objItem.EventCode, objItem.EventType, objItem.Type, objItem.User, Right(objItem.Message,(Len(objItem.Message) - InStr(objItem.Message, "pages printed: ")) - 14), Left(objItem.Message, intMsgSize), strGetPrinterName

                                       ElseIf DateDiff("d", strDatePrint, strDateFrom) <= 0 Then

                                               If DateDiff("d", strDatePrint, strDateTo) >=0  Then

                                                       LogEvent strDatePrint, Mid(objItem.TimeWritten,9,2) & ":" & Mid(objItem.TimeWritten,11,2) & ":" & Mid(objItem.TimeWritten,13,2), objItem.ComputerName, objItem.Logfile, objItem.SourceName, objItem.EventCode, objItem.EventType, objItem.Type, objItem.User, Right(objItem.Message,(Len(objItem.Message) - InStr(objItem.Message, "pages printed: ")) - 14), Left(objItem.Message, intMsgSize), strGetPrinterName

                                               End If

                                       End If

                               ElseIf strUsername = objItem.User Then

                                       If strDateFrom = "*" Then

                                               LogEvent strDatePrint, Mid(objItem.TimeWritten,9,2) & ":" & Mid(objItem.TimeWritten,11,2) & ":" & Mid(objItem.TimeWritten,13,2), objItem.ComputerName, objItem.Logfile, objItem.SourceName, objItem.EventCode, objItem.EventType, objItem.Type, objItem.User, Right(objItem.Message,(Len(objItem.Message) - InStr(objItem.Message, "pages printed: ")) - 14), Left(objItem.Message, intMsgSize), strGetPrinterName

                                       ElseIf DateDiff("d", strDatePrint, strDateFrom) <= 0 Then

                                               If DateDiff("d", strDatePrint, strDateTo) >=0  Then

                                                       LogEvent strDatePrint, Mid(objItem.TimeWritten,9,2) & ":" & Mid(objItem.TimeWritten,11,2) & ":" & Mid(objItem.TimeWritten,13,2), objItem.ComputerName, objItem.Logfile, objItem.SourceName, objItem.EventCode, objItem.EventType, objItem.Type, objItem.User, Right(objItem.Message,(Len(objItem.Message) - InStr(objItem.Message, "pages printed: ")) - 14), Left(objItem.Message, intMsgSize), strGetPrinterName

                                               End If

                                       End If

                               End If ' username If

                       End If ' Printer Name IF

               End If ' EventType If

       End If ' Print EventID If

Next



' Write the log file and info
Set objLogFile = objFSO.OpenTextFile (strLogFile, intReadMode, True)
objLogFile.WriteLine ("using command line options: " & strComputer & " " & strPrinterName & " " & strUsername & " " & strDateFrom & " " & strDateTo & " " & strLogFile)
objLogFile.WriteLine ("Number of successful print records: " & intRecordNum)
objLogFile.WriteLine ("Number of pages printed: " & intTotalPages & vbNewLine)
If(bolPageCError = True) Then
       objLogFile.WriteLine ("**There was an error counting the total number of pages printed**" & vbNewLine)
End IF

objLogFile.Write (strLogDump)

WScript.Quit ' Toodle-pip!

'------------------------------------------------------------------------------------------------


'-----------------------------------------SUBROUTINES--------------------------------------------
sub LogEvent(strDate, strTime, strComp, strLogf, strSource, intEventC, intEventT, strType, strUser, intPageC, strMsg, strPrint)

' Start building our log to write
strLogDump = strLogDump & "Date & Time: " & strDate & " - " & strTime & vbNewLine
strLogDump = strLogDump & "ComputerName: " & strComp & vbNewLine
strLogDump = strLogDump & "Printer: " & strPrint & vbNewLine
' strLogDump = strLogDump & "Logfile: " & strLogF & " source " & strSource & vbNewLine
' strLogDump = strLogDump & "EventCode: " & intEventC & vbNewLine
' strLogDump = strLogDump & "EventType: " & intEventT & vbNewLine
' strLogDump = strLogDump & "Type: " & strType & vbNewLine
strLogDump = strLogDump & "User: " & strUser & vbNewLine
strLogDump = strLogDump & "Pages Printed: " & intPageC
strLogDump = strLogDump & "Message: " & strMsg & vbNewLine
strLogDump = strLogDump & vbNewLine

If (IsNumeric(intPageC)) Then
       intTotalPages = intTotalPages + intPageC
Else
       bolPageCError = True
End If

intRecordNum = intRecordNum + 1

End Sub


Sub Argumentative()
' This sub handles the parsed arguments to the script to make sure
everything is honky-dory

       ' Make sure we haven't been given too many arguments otherwise
       ' the script is going to do what the user expected
       If WScript.Arguments.Count > intArgCount Then
               WScript.Echo "Error: to many arguments were given"
               Call PrintUsage() ' Remind the user of the usage details
               WScript.Quit ' Lets exit this town!
       End If

       ' What if not enough arguments were given?
       If WScript.Arguments.Count < intArgCount Then
               WScript.Echo "Error: not enough arguments were given"
               Call PrintUsage() ' Remind the use of the usage details
               WScript.Quit ' Lets exit this town!
       End IF

       On Error Resume Next

       strComputer = WScript.Arguments.item(0)
       strPrinterName = WScript.Arguments.item(1)
       strUsername = WScript.Arguments.item(2)

       If Wscript.Arguments.item(3) = "*" Then
               strDateFrom = "*"
               strLogFile = WScript.Arguments.item(4)
       Else
               strDateFrom = Left(Wscript.Arguments.item(3), 10)
               strDateTo = Right(Wscript.Arguments.item(3), 10)
               strLogFile = WScript.Arguments.item(4)
       End If


       ' Did an error occur getting the arguments?
       If Err.Number <> 0 Then
               WScript.Echo "Error: failed to set parsed arguments"
               WScript.Echo "Error Number: " & Err.Number
               WScript.Echo "Error Number (Hex): " & Hex(Err.Number)
               WScript.Echo "Source: " &  Err.Source
               WScript.Echo "Description: " &  Err.Description
               Call PrintUsage() ' Remind the use of the usage details
               WScript.Quit ' Lets exit this town!
       End If

End Sub


sub PrintUsage()
' This sub prints the usage info

       ' Print out the arguments parsed for aditional debugging help
       Wscript.Echo vbNewLine & "Arguments given:"
       For intL = 0 to WScript.Arguments.Count - 1
               Wscript.Echo WScript.Arguments.Item(intL)
       Next

       WScript.Echo vbNewLine & "Useage details:"
       WScript.Echo ".vbs     "
       WScript.Echo "PrintEventAudit.vbs . BlackNWhite * 02/21/2010-03/21/2010 C:\LogsDir\Local_E_Drive.log"
       WScript.Echo vbNewLine & "OR" & vbNewLine & "PrintEventAudit.vbs . * jsmith * C:\LogsDir\FS01_All_Drives.log" & vbNewLine

End Sub

Previous page: PortListener
Next page: Print Audit Wrapper