Script to generate print job accounting reports by print job and by user

This is a PowerShell script designed to be run on a scheduled basis to extract print job accounting reports from the Windows Event log. It creates two reports in .CSV format, one listing individual print jobs and the other providing a total number of pages printed by each user.

4.8 Star
Add to favorites
E-mail Twitter Digg Facebook
  • for Cyrillic letters, after change format to ASCII in text file I see many '?' instead normal text
    1 Posts | Last post March 12, 2020
    • Changed script for working with Russian language env.,
  • possible to point this to an archived evtx??
    2 Posts | Last post February 12, 2019
    • Hello. I would like to know if it is possible to point this script to a folder containing an evtx rather than hostname. I have been trying to do this but I am a powershell n00b. (still trying to figure it out)
      Basically, instead of a hostname, specify x:\folder\print-operatinal.evtx and a date range. Then run this script against that evtx file and produce results as if I had specified a hostname.
      I think this might be possible I just need help to find the correct code to do this.
    • Hi ivanris, yes, that should be possible. The Get-WinEvent commands at the centre of this script can take a -Path parameter pointing to a evtx file and get events from that file instead of the active event log.
  • Get File Name
    2 Posts | Last post February 12, 2019
    • Hi Tim.
      Do you know if it's possible retrieve the file name that was printed?
    • Hi Rodrigo, this information is not recorded in the server print queue event log messages so I don't think so. This may (or may not) be logged on the client-side print event log messages.
  • Only Report for Specific Users
    2 Posts | Last post February 12, 2019
    • Tim, hello & thank you for this script. Was wondering how to limit output of the script for only specific users (User1, User2, & User3)?
    • Hi SprocketSlim, I would think you would add some code just after the section where the $UserName value is set (e.g. "$UserName = $entry.Event.UserData.DocumentPrinted.Param3") to check if the username found is one you wish to track and if it is, just proceed on. If it isn't, use the PowerShell continue statement to break out and proceed to the next for loop iteration.
  • Error on Execution - W2K8R2 SP1
    2 Posts | Last post February 12, 2019
    • PS C:\PowerShell> .\printerjobs.ps1 localhost PreviousDay
      Unexpected token '{' in expression or statement.
      At C:\Powershell\printerjobs.ps1:89 char:34
      +     {($_ -eq 2) -or ($_ -eq 3)} { <<<<
          + Category Info         : ParserError: ({:String) [], ParseException
          + FullyQualifiedErrorId : UnexpectedToken
      The script works great on W2K16
      I would greatly appreciate any assistance you could give on this issue.
    • Hi Lorand, this script has worked on 2008R2 (I'm not currently using that OS any longer). Have you confirmed you have installed .NET Framework 3.5 or later on the 2008R2 system? That was the needed framework version.
  • Empty Message Solved
    3 Posts | Last post February 12, 2019
    • I had problems with printers not returning number of copies so it defaulted to 1 all the time. The problem started on rows 220 and 222 where Get-WinEvent fails to return data:
      Get-WinEvent -ErrorAction SilentlyContinue -ComputerName localhost -FilterHashTable @{ProviderName="Microsoft-Windows-PrintService"; StartTime=2015-11-15; EndTime=2015-11-15; ID=307}
         ProviderName: Microsoft-Windows-PrintService
      TimeCreated		Id LevelDisplayName Message
      -----------		-- ---------------- -------
      2015-11-17 10:01:01	307
      2015-11-17 09:59:56	307
      It turns out this can be fixed with a function that I copied from Jeffrey P Snover of the PowerShell Team:
      I simply add this at the top:
      Function Using-Culture (
      [System.Globalization.CultureInfo]$culture = (throw "USAGE: Using-Culture -Culture culture -Script {scriptblock}"),
      [ScriptBlock]$script= (throw "USAGE: Using-Culture -Culture culture -Script {scriptblock}"))
          $OldCulture = [System.Threading.Thread]::CurrentThread.CurrentCulture
              [System.Threading.Thread]::CurrentThread.CurrentCulture = $OldCulture
          [System.Threading.Thread]::CurrentThread.CurrentCulture = $culture
          Invoke-Command $script
          [System.Threading.Thread]::CurrentThread.CurrentCulture = $OldCulture
      And then I wrap the Get-WinEvent rows with the Using-Culture function:
      $PrintEntries = Using-Culture -culture:'en-US' -script:{ Get-WinEvent -ErrorAction SilentlyContinue -ComputerName $PrintServerName -FilterHashTable @{ProviderName="Microsoft-Windows-PrintService"; StartTime=$StartDate; EndTime=$EndDate; ID=307} }
      $PrintEntriesNumberofCopies = Using-Culture -culture:'en-US' -script:{ Get-WinEvent -ErrorAction SilentlyContinue -ComputerName $PrintServerName -FilterHashTable @{ProviderName="Microsoft-Windows-PrintService"; StartTime=$StartDate; EndTime=$EndDate; ID=805} }
      And now the script works for me.
    • Ops. Just noticed that the rows affected will be on 189 and 191, I had changed a few things in the script which had pushed the rows down.
    • Hi anlun, thanks for this localization improvement. I've added it to the script.
  • Issues with Office
    4 Posts | Last post February 12, 2019
    • Hi. First, for spanish users, you have to customize line 225 like this:
      #Spanish search string: Presentando trabajo $PrintJobId
      Then, an issue I have found. The script is not working properly with Office documents (2013), because every tiem I print several copies of a single document, the event 805 just records 1 copy. It works fine, for example, printing from Chrome.
      Can anybody help with this?
      Thanks anyway, it´s a great work!
    • Edit: I have found it only occurs in certain office apps, like Word. Excel and Power Point tracks copies fine.
    • Hi all,
      Tim thank you so much for the script.
      I want to contribute with the line in Portuguese-BR that is: "Processando Trabalho $PrintJobId".
      And I am having the same problem as gutillo. The document applications like Word and Notepad does not track the number of copies, just the number of pages. So did you found a way to workaround it?
      Thank you again for the script it helps a lot.
    • Hi gutillo, thanks for the translation. I've added that to the script.
      Hi Jullian, thanks for the translation. I've added that to the script.
      Regarding event 805 recording 1 copy when actually more copies were requested by the user, I have found this is more of a print driver issue usually, not a Microsoft Word issue.
      Here is one fix I found:
      - Case of a HP LaserJet Pro 400 color printer model M451dn (CE957A) using the HP Universal Printing driver PCL 6 (v5.0.3), the HP Universal Printing PCL 5 (v5.2) driver and the HP Universal Printing PS driver (v.5.0.3):
          In all cases, this printer reports 1 copy of all jobs in Event ID 805, even when the user prints more than 1 copy of the job. 
          The fix was to clear the printer properties setting "Sharing > Render print jobs on client computers" (which is _enabled_ by default). 
          With this change, the number of copies per job was reported accurately in the Windows event log.
  • Error on Execution on W2K8R2 SP1
    5 Posts | Last post February 12, 2019
    • Hey Tim,
      very nice script - that's what we've looked for.
      But i get an error.
      - - -  snip - - 
      Print server hostname to query: localhost
      Collecting event logs found in the specified time range from 10/25/2012 00:00:00 to 10/25/2012 23:59:59.
        Number of print job event ID 307 entries found: 273
        Number of print job event ID 805 entries found: 273
      Parsing event log entries and writing data to the by-print job .CSV output file
      "D:\PrintAccounting\Print job accounting report by print job for print server host localhost - 2012-10-25 to 2012-10-25.csv"...
      There were no print job event ID 805 entries found in the specified timerange from 10/25/2012 00:00:00 to 10/25/2012 23:59:59 that matched print job id 14.
      A matching record should always be present. Exiting script.
      - - -  snip - - 
      It says that there ist no print job event id805 for job id X. But if I look into the eventlog I see the eventID805 with job id X
      Why doesn’t it work
      Thanks in advance
      Greetings dennis
    • i got the solution.
      If you havent an english os you have to customize line 225
      For the english server:
      - - s n i p - -
      "Rendering job $PrintJobId."
      - - s n i p - -
      For the german server:
      - - s n i p - -
      "Der Auftrag $PrintJobId wird gerendert."
      - - s n i p - -
    • Hi Dennis, thanks for posting the German version of the needed event log search string. I added it to a comment in ver. 2014-09-26-01 of the script.
    • For the french version :
      {$_.Message -eq "Rendu du travail $PrintJobId."
    • Hi Nicodonald, thanks for the translation. I've added that to the script.
  • Error Retrieving Full Name
    1 Posts | Last post May 25, 2017
    • Everything appears to work properly for me with the exception of the script pulling the full name of the user which comes back blank in the CSV. When I run the script, I see the following error:
      Property 'Path' cannot be found on this object. Make sure it exists. 
      At E:\Scripts\GeneratePrintJobAccountingReports.ps1:249 char:30
      + $DirectorySearcher.FindOne(). <<<< Path
       +CategoryInfo :InvalidOperation: (.:OperatorToken) [], RuntimeException
       +FullyQualifiedErrorId : PropertyNotFoundStrict
      Can someone point me in the right direction to resolve this error?
  • how can I do a per Printer report
    1 Posts | Last post February 21, 2017
    • I tried to add and modify the Per User file to a per Printer one but it just wasn't liking the way I modified it.
      Otherwise this is a fantastic script
1 - 10 of 16 Items