Audit

簡單的列印機審核腳本

  • October 9, 2013

我正在使用 Windows Server 2008 R2,我想創建一個簡單的腳本來審核公司中進行的列印。

我希望在共享的文本文件中審核這些詳細資訊,並希望在有人發送要列印的內容後執行腳本:

“使用者名、電腦名、文件名和路徑、頁數、列印機名、日期、時間”

任何建議將不勝感激。

謝謝你。

伙計們,這是我在前世使用的腳本。這是在 2003 年的列印伺服器上,但我認為它們在 2008 年也可以正常工作。我從某人的部落格文章中獲得了大部分線上資訊,但我不記得在哪裡……那是幾年前的事了。

這個怎麼運作:

auditprinters.bat = 執行以下操作的批處理文件(每天安排):

  1. 通過列印伺服器的 FOR 循環解析輸入。就我而言,我只有一個列印伺服器,但如果你有額外的,你可以修改 FOR 循環以允許輸入文件等。
  2. 設置各種輸出文件夾
  3. 刪除超過 30 天的日誌
  4. 使用轉儲列印機日誌DUMPEL(確保您已安裝 Windows 資源工具包或獲取dumpel並將其放置在某處並修改批處理文件的該行)
  5. 備份目前日誌
  6. 處理日誌呼叫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

引用自:https://serverfault.com/questions/544448