Audit
簡單的列印機審核腳本
我正在使用 Windows Server 2008 R2,我想創建一個簡單的腳本來審核公司中進行的列印。
我希望在共享的文本文件中審核這些詳細資訊,並希望在有人發送要列印的內容後執行腳本:
“使用者名、電腦名、文件名和路徑、頁數、列印機名、日期、時間”
任何建議將不勝感激。
謝謝你。
伙計們,這是我在前世使用的腳本。這是在 2003 年的列印伺服器上,但我認為它們在 2008 年也可以正常工作。我從某人的部落格文章中獲得了大部分線上資訊,但我不記得在哪裡……那是幾年前的事了。
這個怎麼運作:
auditprinters.bat = 執行以下操作的批處理文件(每天安排):
- 通過列印伺服器的 FOR 循環解析輸入。就我而言,我只有一個列印伺服器,但如果你有額外的,你可以修改 FOR 循環以允許輸入文件等。
- 設置各種輸出文件夾
- 刪除超過 30 天的日誌
- 使用轉儲列印機日誌
DUMPEL
(確保您已安裝 Windows 資源工具包或獲取dumpel
並將其放置在某處並修改批處理文件的該行)- 備份目前日誌
- 處理日誌呼叫
processprinterlogs.vbs
ProcessPrinterLogs.vbs = 解析列印機日誌(格式化等)的腳本
然後,我使用 Excel 打開文件並根據需要進行自己的排序和操作。
程式碼:
審計列印機.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