PowerShell: Audit Printer Event Logs

Color toner costs recently came under scrutiny by management at my company. In order to address the rising cost, Management requested a report of Color Printer use showing who, what, when, and how much is printed. This requires two steps on our Windows Server 2008 R2 servers:

1) Print Events Logging must be enabled. It is disabled by default.

2) A Powershell Script to parse out the data requested.

3) .Net Framework 3.5.1 Features installed on the Print Server – Thanks to Simon for pointing this out in the comments section below.

Enable Print Event Logging

1) Open the Event Viewer on the Print Server. (Start=>Run, eventvwr.msc)

2) Expand out Application and Services Logs => Microsoft => Windows => PrintService.

3) Right Click on the Operational log.

4) Select Properties from the pop-up menu.

5) Check the box to Enable Logging

Powershell Script to Parse Logs

Fortunately, I had the foresight to enable Print Logging when we began using this server as a Print Server. Otherwise, you will need to wait till history is built up to use the powershell script I wrote below.

Make sure you replace my generic printer names for ones you wish to report on.

$dte = Get-Date

$m = $dte.month

$cmonth = Get-Date -UFormat %m

$d = $dte.day

$cday = Get-Date -UFormat %d

$cyear = $dte.year

$filename = "ColorPrinterLog_" + $cyear + "_" +$cmonth + ".csv"

$startdatefull = ($dte).AddDays(-30)

$startdate = ($startdatefull).ToShortDateString()

$enddate = ($dte).ToShortDateString()

"Job Name: Monthly Color Printer Log"

"Start Date: " + $startdate

"End Date: " + $enddate

Write-Host " " | Out-File "C:\$filename"

Write-Host "Scanning Archived Printer Event Logs..."

Write-Host

Get-ChildItem -include Archive-Microsoft-Windows-PrintService%4Operational-$cyear-$cmonth*.evtx -Path C:\Windows\System32\winevt\Logs -recurse |

ForEach-Object {

"Parsing $($_.fullname)`r`n"

Try

{ $events = get-winevent -FilterHashTable @{Path=$_.fullname; ID=307; StartTime=$startdate; EndTime=$enddate ;} |

where {($_.Message -like "*printer1*") -or ($_.Message -like "*printer2*") -or ($_.Message -like "*printer3*") -or ($_.Message -like "*printer4*") -or ($_.Message -like "*printer5*") -or ($_.Message -like "*printer6*") } |

select timecreated,message |

Export-Csv "C:\Temp.csv" -Encoding ASCII -notype

[System.IO.File]::ReadAllText("C:\Temp.csv") | Out-File -Append "C:\$filename"

}

Catch [System.Exception] {"No results in current log"}

}

Write-Host

Write-Host "Scanning Complete!"

Write-Host

Now, this is just a simple script so you will need to use a text editor to find/replace phrases with commas in order to filter and sort into a usable report.

Download My Script (Right Click and choose Save Link As…)

Advertisements
This entry was posted in PowerShell, Windows Server and tagged , , , , , , , . Bookmark the permalink.

21 Responses to PowerShell: Audit Printer Event Logs

  1. Jason Farmer says:

    I love this, and I think this is exactly what I need, however, I do have questions.

    For starters, I can’t seem to get it to work. I see print jobs with ID 307 in the logs, but my excel file keeps returning “ÿþ” in cell A1.

    Any suggestions?

    • Brian says:

      I was also getting that same message. I believe this is caused by me Exporting the CSV using Unicode Encoding. I switched it to ASCII and it seems to work now. I updated my script, so download it again to resolve the issue.

      If you leave it as Unicode, it is all in the way you open the CSV file. Open Excel first, then go File, Open…

      You will the go through a wizard that allows you to select how the file is delimited. Let me know if that helps.

      • Jason Farmer says:

        Still not working for me. The only changes I made were adding my printer names to the script and changing the save to path. Do i need the asterisks around the printer names? Also, my log file is not listed as Archive-Microsoft-Windows-PrintService%4Operational in the folder, but as Microsoft-Windows-PrintService%4Operational, with no Archive-. Here is my copy of the script:

        $dte = Get-Date
        $m = $dte.month
        $cmonth = Get-Date -UFormat %m
        $d = $dte.day
        $cday = Get-Date -UFormat %d
        $cyear = $dte.year
        $filename = “ColorPrinterLog_” + $cyear + “_” +$cmonth + “.csv”
        $startdatefull = ($dte).AddDays(-30)
        $startdate = ($startdatefull).ToShortDateString()
        $enddate = ($dte).ToShortDateString()
        “Job Name: Monthly Color Printer Log”
        “Start Date: ” + $startdate
        “End Date: ” + $enddate
        Write-Host ” ” | Out-File “U:\Printer Logs\$filename”
        Write-Host “Scanning Archived Printer Event Logs…”
        Write-Host
        Get-ChildItem -include Archive-Microsoft-Windows-PrintService%4Operational-$cyear-$cmonth*.evtx -Path C:\Windows\System32\winevt\Logs -recurse |
        ForEach-Object {
        “Parsing $($_.fullname)`r`n”
        Try
        { $events = get-winevent -FilterHashTable @{Path=$_.fullname; ID=307; StartTime=$startdate; EndTime=$enddate ;} |
        where {($_.Message -like “Xerox WorkCentre 7435 Main BW PCL6”) -or ($_.Message -like “Xerox WorkCentre 7435 Main Color PCL6”) -or ($_.Message -like “Xerox Phaser 6280DT PCL 6 – BW”) -or ($_.Message -like “Xerox Phaser 6280DT PCL 6 – Color”) } |
        select timecreated,message |
        Export-Csv “U:\Printer Logs\Temp.csv” -Encoding ASCII -notype
        [System.IO.File]::ReadAllText(“U:\Printer Logs\Temp.csv”) | Out-File -Append “U:\Printer Logs\$filename”
        }
        Catch [System.Exception] {“No results in current log”}
        }
        Write-Host
        Write-Host “Scanning Complete!”
        Write-Host

      • Brian says:

        The Archive files are created from the Operational Log, I believe once the Operational Log becomes full.

        1) Is the script running on the print server?
        2) Has Print Logging been enabled long enough on the print server for the Archive files to be created? Look in C:\Windows\System32\winevt\Logs to make sure the Archive files exist.

  2. Simon says:

    Hi Guys,

    I have been having a play around with the script and had similar results to Jason.

    Once thing that threw me and gave me the same “ÿþ” result was that .net 3.5 wasn’t installed. I think due to the try catch section of the script the error was not being output. Anyway I installed .net 3.5 through server features and the script worked as expected!

    Cheers

    Simon

  3. Jan Bonne says:

    Hello Brian,
    Thanks for this script, but I’m getting no results in my csv files, while the eventlog is available. I’m getting the mesage No results in current log. Can you point to me what I might be doing wrong?

    • Brian says:

      Are you seeing events in the PrinService Operational log? If not, you still need to enable logging.

      If you just enabled logging, my script only views archived logs and not the Operational log directly. Printing is so frequent in my environment that the operational log is archived a couple times a day. If your environment is not printing much then the Archive logs may not exist yet and you should modify my script to look directly at the Operational Log.

      Hope this helps.

    • Jan Bonne says:

      Forget above.. .NET3.5 wasn’t installed… But now I’ve got my output I wonder how to get it tight up so I can make calculations. For example total numbers of pages printed by a certain user in that month. I’m not a script guru but is it possible to use the xml-data from the Windows print eventlog?

      • Brian says:

        I always forget about that .Net requirement. Glad you figured that out.

        As far as calculations go, I have yet to figure out how to break down the output. I still am modifying the CSV files manually so I can have more manageable output. I too am not an expert by any means. If you ever come across a solution, please share it with me.

  4. Duncan says:

    Great script, thanks for sharing with the world!
    I’ve enabled .Net 3.5.1 on the server and even rebooted but still getting the “ÿþ” in cell A1. Has everyone else managed to get this working following enabling .Net 3.5?

    • Brian says:

      Try adding the switch “-Encoding ASCII” to the end of each of the Out-File lines. Let me know if it works or not.

      • Duncan says:

        Thanks Brian, that’s sorted it. I’m now working out the best way of using SSIS and SSRS to report on the contents.

      • Brian says:

        Hmm, SSIS and SSRS. I never thought to use that, but now that you mention it, I see lots of potential. I will have to work on that. Let me know what you come up with too.

  5. qamrul says:

    hi i have use PowerShell: Audit Printer Event Logs by B. Bickett.
    i want to log with print job owner name, date and time, computer/ip name, print job doc name etc.
    can any help me how i edit script and put to powershell. my email is: qamrul2001@yahoo.com

    • Brian says:

      I was not able to extract that data directly using Powershell. I ended up exporting the data to CSV then using Notepad++, format the output with the content I needed. It was a tedious process, but I got the results you were looking for.

  6. Vasil says:

    Hi Brian,
    I was searching for good ideas about auditing the printer log and here you are….
    Thanks a lot for your help

    You can add this to your scripts to make the formatting of the csv more easy.
    —————————————————————————
    $Import = ‘C:\’ + $filename
    $destination_file = ‘C:\PrintReports\’ + $filename
    (Get-Content $Import) | Foreach-Object {

    $_ -replace ‘\. No user action is required\.’, ‘,’ `
    -replace ‘\. Pages printed: ‘, ‘,’ `
    -replace ‘\. Size in bytes: ‘, ‘,’ `
    -replace ‘ through port ‘, ‘,’ `
    -replace ‘ was printed on ‘, ‘,’ `
    -replace ‘ on ‘, ‘,’`
    -replace ‘ owned by ‘, ‘,’

    } | Set-Content $destination_file

    • sisilia says:

      Would you please tell me where in the script I should append these lines? thanks

      • Anonymous says:

        One line before this one – Write-Host “Scanning Complete!” – will be good enough.

        But nevertheless, you will need to format the column “Description” in csv file with the text-to-columns function of excel, using the comma delimiter.

  7. Julio Sitges says:

    Hello. It is an old thread, but still. I think it would really help me. I can only say I have tried modifiying your script with no luck so far. I do not get any results. I run the file, and then look under C:/ but the csv file is not there. I am not running the printer on a server but on a local machine. So I need to modify the file to look into the local operational log rather than the server´s. I have not been abe to do that so far, so I am asking for help. Is there someone that is willing to help me out. I would appreciate it.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s