简单的打印机审计脚本

我正在使用Windows Server 2008 R2,我想创build一个简单的脚本来审计在公司中进行的打印。

我希望这些细节可以在共享文本文件中进行审计,并在有人发送要打印的内容后运行脚本:

“用户名,计算机名称,文档名称和path,页数,打印机名称,date,时间”

任何build议将不胜感激。

谢谢。

这里的人们是我以前用过的剧本。 这是在2003年的打印服务器上,但我认为他们在2008年也能正常工作。 我从某人的博客文章中获得了大部分的在线内容,但是我不记得那是在几年以前。

怎么运行的:

auditprinters.bat =batch file(每天计划)执行以下操作:

  1. 通过FOR循环打印服务器分析input。 在我的情况下,我只有一台打印服务器,但如果你有额外的,你可以修改FOR循环,以允许input文件等。
  2. 设置各种输出文件夹
  3. 删除超过30天的日志
  4. 使用DUMPEL转储打印机日志(确保已安装Windows资源工具包或获取dumpel并将其放在某处并修改batch file的该行)
  5. 进行当前日志的备份
  6. 处理日志调用processprinterlogs.vbs

ProcessPrinterLogs.vbs =parsing打印机日志的脚本(格式化等)

然后我使用Excel来打开这些文件,并根据需要进行自己的sorting和操作。


码:

auditprinters.bat

 For %%S IN (PRINTSERVER.MDMARRA.LOCAL) DO ( Set print_server=%%S Call :s_get_logs ) Goto eof :s_get_logs Set MainDir=C:\PrinterLogs\%print_server% Set PrintDir=%MainDir%\printdir Set LogDir=%MainDir%\logs :: Delete log files older than 30 days forfiles /p %LogDir% /d -30 /c "CMD /C del @FILE" :: Create needed directories If not Exist %PrintDir% MD %PrintDir% If not Exist %LogDir% MD %LogDir% :: Set date format For /f "tokens=1-8 delims=/:. " %%i IN ('echo %date%') do Set DateFlat=%%j%%k%%l :: Set log an backup files Set LogFile=%print_server%_jobs_%DateFlat%.csv Set BackFile=PrintJobs_%DateFlat%.csv :: Dump the printer log :: Using full path for safety "C:\Program Files\Resource Kit\dumpel" -s \\%print_server% -l System -e 10 -m Print -d 1 >> %logDir%\%LogFile% :: Make a backup copy Copy %logDir%\%print_server%_jobs_%DateFlat%.csv %PrintDir%\%BackFile% /y :: Process the logs cscript ProcessPrinterLogs.vbs /f:%LogDir% /o:%MainDir%\%print_server%_auditoutput.csv :eof 

ProcessPrinterLogs.vbs

 Const ForReading = 1, ForWriting = 2, ForAppending = 8 Set objFSO = CreateObject("Scripting.FileSystemObject") Set objShell = CreateObject("WScript.Shell") Main() Sub Main() If WScript.Arguments.Named.Exists("f") Then sSource = WScript.Arguments.Named("f") Else WScript.Arguments.ShowUsage() WScript.Echo "Source file or directory must be supplied" WScript.Quit(2) End If If WScript.Arguments.Named.Exists("o") Then sOutputFile = WScript.Arguments.Named("o") Else dNow = Now dLogDate = DatePart("yyyy", dNow) dLogDate = dLogDate & String(2 - Len(DatePart("m", dNow)), "0") & DatePart("m", dNow) dLogDate = dLogDate & String(2 - Len(DatePart("d", dNow)), "0") & DatePart("d", dNow) sOutputFile = Left(WScript.ScriptName, InStrRev(WScript.ScriptName, ".vbs") - 1) & "_" & dLogDate & ".csv" End If WScript.echo "Input file/dir: '" & sSource & "'" WScript.echo "Output file: '" & sOutputFile & "'" If objFSO.FileExists(sSource) Then sFileSet = sSource ' Process a single file WScript.echo "Single file specified - " & sFileSet ElseIf objFSO.FolderExists(sSource) Then WScript.echo "Source specified was a directory, reading files from '" & sSource & "'" sFileSet = "" Set oFolder = objFSO.GetFolder(sSource) ' Get the folder Set oFiles = oFolder.Files For Each oFile In oFiles ' For each file sFileset = sFileset & vbCRLF & oFile.Path ' Append to the fileset Next If Len(sFileSet) > Len(vbCRLF) Then sFileSet = Right(sFileSet, Len(sFileSet) - Len(vbCRLF)) ' Trim the leading CRLF End If Set dPrinters = CreateObject("Scripting.Dictionary") ' Create the dictionary objects Set dUsersPerPrinter = CreateObject("Scripting.Dictionary") Set dusers = CreateObject("Scripting.Dictionary") Set dDates = CreateObject("Scripting.Dictionary") Set dJobs = CreateObject("Scripting.Dictionary") For Each sFile In Split(sFileset, vbCRLF) ' For Each file Set objFile = objFSO.GetFile(sFile) If objFile.size > 0 Then ' Don't process the file if it is a 0 byte file WScript.echo "Processing '" & sFile & "'" sBuffer = "" Set objTextStream = objFSO.OpenTextFile(sFile, ForReading) sBuffer = objTextStream.ReadAll For Each sLine In Split(sBuffer, vbCRLF) ' For each line in this file Call ProcessLogEntry(sLine, dPrinters, dUsers, dDates, dJobs, dUsersPerPrinter) ' Process the log entry Next End If Next Call ProduceOutput(sOutput, dPrinters, dUsers, dDates, dJobs, dUsersPerPrinter) ' Produce the output Set objTextStream = objFSO.OpenTextFile(sOutputFile, ForWriting, True) objTextStream.Write sOutput WScript.echo "Output saved to '" & sOutputFile & "', " & Len(sOutput) & " characters." End Sub Function ProduceOutput(ByRef sOutput, ByRef dPrinters, ByRef dUsers, ByRef dDates, ByRef dJobs, ByRef dUsersPerPrinter) Dim strPrinter, strPort, dtmDate, strUser, strserver, strDocumentName, intSize, intPages, strInformation, strTotal Dim strUserTotal, strPrinterTotal, strDateTotal, strJobTotal, aJobTotal sOutput = "" For Each strPrinter In dPrinters.Keys sOutput = sOutput & vbCRLF & strPrinter & "," & dPrinters.Item(strPrinter) Next sOutput = sOutput & vbCRLF For Each strUser In dUsers.Keys sOutput = sOutput & vbCRLF & strUser & "," & dUsers.Item(strUser) Next 'new portion to output list of users per print queue sOutPut = sOutput & vbCRLF For Each strPrinter In dUsersPerPrinter.Keys sOutput = sOutput & vbCRLF & strPrinter & "," & dUsersPerPrinter.Item(strPrinter) Next 'end of new output sOutput = sOutput & vbCRLF For Each dtmDate In dDates.Keys sOutput = sOutput & vbCRLF & dtmDate & "," & dDates.Item(dtmDate) Next sOutput = sOutput & vbCRLF For Each strTotal In dJobs.Keys strJobTotal = dJobs.Item(strTotal) aJobTotal = Split(strJobTotal, ",") sOutput = sOutput & vbCRLF & "Total Jobs," & aJobTotal(0) sOutput = sOutput & vbCRLF & "Total Pages," & aJobTotal(1) sOutput = sOutput & vbCRLF & "Total Size (MB)," & aJobTotal(2) Next sOutput = sOutput & vbCRLF strUserTotal = UBound(dUsers.Keys) + 1 strPrinterTotal = UBound(dPrinters.Keys) + 1 strDateTotal = UBound(dDates.Keys) + 1 sOutput = sOutput & vbCRLF & "Printers," & strPrinterTotal sOutput = sOutput & vbCRLF & "Users," & strUserTotal sOutput = sOutput & vbCRLF & "Days," & strDateTotal aJobTotal = Split(strJobTotal, ",") sOutput = sOutput & vbCRLF sOutput = sOutput & vbCRLF & "Average jobs/person," & CInt(aJobTotal(0) / strUserTotal) sOutput = sOutput & vbCRLF & "Average pages/person," & CInt(aJobTotal(1) / strUserTotal) sOutput = sOutput & vbCRLF & "Average pages/person/day," & CInt(CInt(aJobTotal(1) / strUserTotal) / strDateTotal) sOutput = sOutput & vbCRLF & "Average pages/minute," & CInt(aJobTotal(1) / (strDateTotal * 8 * 60)) End Function Function ProcessLogEntry(ByRef sLine, ByRef dPrinters, ByRef dUsers, ByRef dDates, ByRef dJobs, ByRef dUsersPerPrinter) Dim strPrinter, strPort, dtmDate, strUser, strserver, strDocumentName, intSize, intPages, strInformation Dim aPrintJob, intOffset, strTemp, aTemp aPrintJob = Split(sLine, vbTAB) If UBound(aPrintJob) = 9 Then dtmDate = aPrintJob(0) ' & " " & aPrintJob(1) aTemp = Split(dtmDate, "/") dtmDate = Right("00" & Trim(aTemp(1)), 2) & "/" & Right("00" & Trim(aTemp(0)), 2) & "/" & aTemp(2) ' Trim, pad and switch to dd/mm/yyyy instead of mm/dd/yyyy strServer = aPrintJob(8) strInformation = Trim(aPrintJob(9)) strInformation = Right(strInformation, Len(strInformation) - InStr(strInformation, " ")) ' Remove the job ID intOffset = InStrRev(strInformation, " ") intPages = Right(strInformation, Len(strInformation) - intOffset) ' Extract the number of pages from the end strInformation = Left(strInformation, intOffset - 1) ' Trim the string intOffset = InStrRev(strInformation, " ") intSize = Right(strInformation, Len(strInformation) - intOffset) ' Extract the number of bytes from the end strInformation = Left(strInformation, intOffset - 1) ' Trim the string intOffset = InStrRev(strInformation, " ") strPort = Right(strInformation, Len(strInformation) - intOffset) ' Extract the port from the end strInformation = Left(strInformation, intOffset - 1) ' Trim the string intOffset = InStrRev(strInformation, " ") strPrinter = Right(strInformation, Len(strInformation) - intOffset) ' Extract the printer from the end strInformation = Left(strInformation, intOffset - 1) ' Trim the string intOffset = InStrRev(strInformation, " ") strUser = Right(strInformation, Len(strInformation) - intOffset) ' Extract the user from the end strInformation = Left(strInformation, intOffset - 1) ' Trim the string strDocumentName = strInformation If dPrinters.Exists(strPrinter) Then ' Does this printer already exist in the dictionary? aTemp = Split(dPrinters.Item(strPrinter), ",") ' Find the existing printer job/page count aTemp(0) = aTemp(0) + 1 ' Increment the job count aTemp(1) = aTemp(1) + CInt(intPages) ' Add to the page count aTemp(2) = aTemp(2) + CInt(intSize / 1024 / 1024) ' Add to the byte count dPrinters.Item(strPrinter) = Join(aTemp, ",") ' Update the dictionary Else aTemp = Array(1, intPages, CInt(intsize / 1024 / 1024)) ' Start the job/page count dPrinters.Add strPrinter, Join(aTemp, ",") ' Create this item End If If dUsers.Exists(strUser) Then ' Does this user already exist in the dictionary? aTemp = Split(dUsers.Item(strUser), ",") ' Find the existing user job/page count aTemp(0) = aTemp(0) + 1 ' Increment the job count aTemp(1) = aTemp(1) + CInt(intPages) ' Add to the page count aTemp(2) = aTemp(2) + CInt(intSize / 1024 / 1024) ' Add to the byte count dUsers.Item(strUser) = Join(aTemp, ",") ' Update the dictionary Else aTemp = Array(1, intPages, CInt(intsize / 1024 / 1024)) ' Start the job/page count dUsers.Add strUser, Join(aTemp, ",") ' Create this item End If If dDates.Exists(dtmDate) Then ' Does this date already exist in the dictionary? aTemp = Split(dDates.Item(dtmDate), ",") ' Find the existing date job/page count aTemp(0) = aTemp(0) + 1 ' Increment the job count aTemp(1) = aTemp(1) + CInt(intPages) ' Add to the page count aTemp(2) = aTemp(2) + CInt(intSize / 1024 / 1024) ' Add to the byte count dDates.Item(dtmDate) = Join(aTemp, ",") ' Update the dictionary Else aTemp = Array(1, intPages, CInt(intsize / 1024 / 1024)) ' Start the job/page count dDates.Add dtmDate, Join(aTemp, ",") ' Create this item End If If dJobs.Exists(JOB_TOTAL) Then ' Does the total already exist in the dictionary? aTemp = Split(dJobs.Item(JOB_TOTAL), ",") ' Find the existing total counts aTemp(0) = aTemp(0) + 1 ' Increment the job count aTemp(1) = aTemp(1) + CInt(intPages) ' Add to the page count aTemp(2) = aTemp(2) + CInt(intSize / 1024 / 1024) ' Add to the byte count dJobs.Item(JOB_TOTAL) = Join(aTemp, ",") ' Update the dictionary Else aTemp = Array(1, intPages, CInt(intsize / 1024 / 1024)) ' Start the job/page count dJobs.Add JOB_TOTAL, Join(aTemp, ",") ' Create this item End If ' This section creates a list of users that are using each print queue If dUsersPerPrinter.Exists(strPrinter) Then ' Does the printer exist as a key in the dictionary? Dim bTemp bTemp = dUsersPerPrinter.Item(strPrinter) & "," & strUser ' build up the list of users dUsersPerPrinter.Item(strPrinter) = DedupeString(bTemp, ",") ' dedupe sting of users and populate dictionary Else dUsersPerPrinter.Add strPrinter, strUser ' Create this item End If ' End of user list creation Else WScript.echo "skipped '" & sLine & "'" ' line skipped because number of elemnts in array not equal to 9 ( need to figure this one out) End If End Function ' Deduping a string ' must use this function so we end up with a unique list of users with no duplicates Function DedupeString(inString, strSeperate) Dim vObjects, myDict, index, strFinal strFinal = "" Set myDict = CreateObject("Scripting.Dictionary") vObjects = Split(inString, strSeperate) For index = 0 To UBound(vObjects) If (Not myDict.Exists(vObjects(index))) Then myDict.Add vObjects(index), vObjects(index) If (Len(strFinal)) > 0 Then strFinal = strFinal & strSeperate & myDict(vObjects(index)) Else strFinal = myDict(vObjects(index)) End If End If Next DedupeString = strFinal End Function