다음을 통해 공유


A PaperCut Print Logger Replacement

Since I originally posted this article my print logging has changed quite a bit. In the version that I talked about originally I wasn't getting an accurate accounting of pages printed. This was only recently revealed to me. To be honest, the fact that I missed it originally is upsetting but the fact that amount of printing done historically was so monumental and that I perhaps missed on actual number by a large precentage is rather depressing! I'll give you an example of how much we print a little later.

I want to start out saying that I really like the free PaperCut print loging software, it works really well and I've had no complaints. But we recently migrated from multiple print servers, to a print cluster, the process went smoothly and I have a few scripts that I used that I need to publish on the Gallery. The only loss was the logging capability we had via PaperCut.

I did some research and the most I found was an article from PaperCut that talked about how to set up the paid software to work within a clustered environment. There was an indication on the FAQ for the free software that while unsupported you might be able to use the same set of instructions to get it to go, but sadly I did not have the requiste mojo to make that happen.

So I remembered I had found that print logging had been moved to a separate log that is disabled be default. So I enabled those logs on my cluster, and began banging away at PowerShell to get a solution put together. There are several events associated with a given print job at least 4 to be precise:

  • 800 - This is the job spooling on the server
  • 801 - This is the job being sent to the printer
  • 805 - This is the job actually printing (I think)
  • 307 - A summary of the job

Event ID 307 is what I was after, it had all the pertinent information I needed to build my log with:

  • Size (bytes)
  • Time
  • User
  • Job #
  • Client
  • Port
  • Printer
  • Pages
  • Document

What I didn't realize originally is that Event ID 805 contains the number of copies for a given Job ID. Why this isn't included in Event ID 307 I'm not entirely sure but oh well. In order to get the proper accounting I needed a script that would write out to a file the Job Id and the number of copies. Then the print logging script would read it in, and write the count out with the rest of the data.

Originally this script was tied to an event and when that event occurred it would attempt to get the most recent (ie the one that triggered it). I found a wonderful article on TechNet about how to pass the EventRecord to a script. This allows me to parse the actual event that occurred. Since you have to modify the task I included two XML files that you can import into your Event Tasks that are already configured.

To get things up and running there are a few steps that need to be gone through first and then you can get started. Once everything is setup the script will start working on it's own. The nice thing about it is, if the log file doesn't exist it will create it for you. Since the filenames are based on the date, this means it should roll over for you every 24 hours.

  1. Enable the Microsoft-Windows-PrintService/Operational log
  2. Create a folder to hold scipts and log output
  3. Copy the zip file to your print server and extract it

Setup an Event Triggered Task Or import the XML files

  1. Make sure the task runs when a user is NOT logged in
  2. For a PowerShell script the command is Powershell and the argument is the path to the script

About 6mo ago I decided that I wanted to start writing this information out to a SQL database, so the script now writes data out to a csv, as well as logs it to your sql server. To setup a SQL database is a bit beyond this particular article, but what I did was create a database on the default SQL instance. Within that database I created a table, and populated it with the following fields

Column Name  Data Type
Time Datetime
UserName varchar(50)
Pages int
DocumentName ntext
Client varchar(50)
Size bigint
Printer varchar(50)
Port varchar(50)
Job int
Copies int

Finally I created a sql user, assigned a password and created a login for it in the database. That user only has the ability to insert into the table and only has access to that particular table. I left in the code to write to csv as I think that's handy and a nice builtin backup. Feel free to comment out the parts you don't want, I'm thinking I may update this slightly so if you don't pass in any SQL information it doesn't write anything out to SQL.

That's pretty much it, I do in fact use this in production, I think this particular version works much better than in the past. I have a script that is included in the download page on the TechNet Gallery that shows how to query the table for yesterday's print jobs. Here is a sample of the output I receive from that script each morning.

DateSubmitted : 5/1/2012
PrintJobs     : 2067
PagesPrinted  : 9544
UsersPrinting : 414
MaxJob        : 211
ReamsUsed     : 19.088
BoxesUsed     : 1.9088