After a recent upgrade of our print servers, I discovered that the Print Spooler service event logging had been enhanced, and changed enough that some PowerShell reporting scripts that worked just fine on Windows Server 2008 (32-bit) no longer worked on Server 2012 R2.
To get the reports working again, I had to enable the Microsoft-Windows-PrintService/Operational log. I also had to increase the log size from the default in order to retain more than one day’s events. The trickiest part was figuring out the XPath query syntax for retrieving events from a particular printer. The newer syntax makes more sense to me, but it took me a long time to arrive at it.
Following Don Jones‘ entreaty to build tools and controllers, I offer this tool script, which retrieves (simplified) print job events, and cares not a whit about formatting or saving.
<# .SYNOPSIS Gets successful print job events and returns simplified objects with relevant details. .DESCRIPTION Collects the successful print jobs from the PrintService Operational log, with optional query parameters including Printer name and start and end times. .PARAMETER PrinterName The share name of the printer for which events will be retrieved. .PARAMETER StartTime The beginning of the interval during which events will be retrieved. .PARAMETER EndTime The end of the interval during which events will be retrieved. .EXAMPLE C:\> Get-PrintJobs.ps1 Returns objects representing all the successful print jobs (events with id 307). .EXAMPLE C:\> Get-PrintJobs.ps1 -PrinterName 'Accounting HP LaserJet' Returns objects for all the jobs on the Accounting printer. .EXAMPLE C:\> Get-PrintJobs.ps1 -PrinterName 'Accounting HP LaserJet' -StartTime (Get-Date).AddHours(-12) Returns objects for all the jobs on the Accounting printer generated in the last twelve hours. .NOTES Script Name: Get-PrintJobs.ps1 Author : Geoff Duke <Geoffrey.Duke@uvm.edu> Edit 2014-10-08: Generalizing from dept printer report script, fixing XPath query syntax. Edit 2012-11-29: Job is run as SYSTEM, and computer object has been granted Modify rights to the destination directory. #> Param( [string] $PrinterName, [datetime] $StartTime, [datetime] $EndTime ) Set-StrictMode -version latest # Building XPath query to select the right events $filter_start = @' <QueryList> <Query Id="0" Path="Microsoft-Windows-PrintService/Operational"> <Select Path="Microsoft-Windows-PrintService/Operational"> '@ $filter_end = @' </Select> </Query> </QueryList> '@ $filter_match = '*[System[(EventID=307)' #need to add ']]' to close if ( $StartTime -or $EndTime) { $filter_match += ' and TimeCreated[' #need to add ']' to close $time_conds = @() if ( $StartTime ) { $time_conds += ( '@SystemTime>=' + "'{0:yyyy-MM-ddTHH:mm:ss.000Z}'" -f $StartTime.ToUniversalTime() ) } if ( $EndTime ) { $time_conds += ( '@SystemTime<=' + "'{0:yyyy-MM-ddTHH:mm:ss.000Z}'" -f $EndTime.ToUniversalTime() ) } $filter_match += ( $time_conds -join ' and ' ) + ' ]' # Closing TimeCreated[ } $filter_match += "]]`n" # Closing [System[ if ( $PrinterName ) { $filter_match += @" and *[UserData[DocumentPrinted[(Param5='$PrinterName')]]] "@ } write-debug "Using Filter:`n $filter_match" # The $filter variable below is cast as XML, that's getting munged # by WordPress or the SyntaxHighlighter as '1' $filter = ($filter_start + $filter_match + $filter_end) get-winevent -filterXML $filter | foreach { $Properties = @{ 'Time' = $_.TimeCreated; 'Printer' = $_.Properties[4].value; 'ClientIP' = $_.properties[3].value.SubString(2); 'User' = $_.properties[2].value; 'Pages' = [int] $_.properties[7].value; 'Size' = [int] $_.properties[6].value } New-Object PsObject -Property $Properties }
If you find this script useful, please let me know. If you find any bugs, definitely let me know!