The greatest challenge to any thinker is stating the problem in a way that will allow a solution

Bertrand Russell

By

On 28 Jun 2013

PowerShell

Tags:


It is, from time to time, useful to be able to see what is being printed via your print server.  Be it to identify busy printers, heavy users, or in order to keep an eye on what kind of documents are being printed.

This is relatively easy to achieve, but you do need to enable the appropriate logging on your server, as the info isn’t recorded by default.  To display the information in a easy to digest format, requires a few lines of PowerShell as well.Before you do anything else, enable logging on your print server…

  1. Open up Server Manager on your print server
  2. Find Diagnostics, and then drill down into Event Viewer, Applications and Service Logs, Microsoft, Windows, Print Service, to find Operational
  3. Right-click over Operational and select Enable Log

…once that’s done your server will start recording day to day activity on your printers.

Create a PowerShell script using the code below and save as something like Print-Activity.ps1

$PrintServer = "Print-Svr-A"                   # Put the hostname/IP of your (main/default) print server here
 
$MaxEvents = 1000                              # Max no of events to pull from print server
 
if (!$args[0]) {
    } else {
    $PrintServer = $args[0]
}
Write-Host "Getting printer events from $PrintServer"
 
$events = Get-WinEvent -ComputerName $PrintServer -FilterHashtable @{ LogName = "Microsoft-Windows-PrintService/Operational"; ID = 307} -MaxEvents $MaxEvents
 
$PrintEvents = @()
 
foreach ($log in $events) {
    $pEvent = "" | Select ID, Created, User, Printer, SizeKB, Pages, Doc
    $pEvent.ID = $log.Properties.Value[0]
    $pEvent.Created = $log.TimeCreated
    $pEvent.User = $log.Properties.Value[2]
    $pEvent.Printer = $log.Properties.Value[4]
    $pEvent.SizeKB = [math]::Round($log.Properties.Value[6]/1024)
    $pEvent.Pages = $log.Properties.Value[7]
    $pEvent.Doc = $log.Properties.Value[1]
    $PrintEvents += $pEvent
}
 
$PrintEvents | Out-GridView -Title "Printer events from $PrintServer"

You can either just run the script, or with a command line argument in order to specify the server to run against (useful of you’ve more than one print server), for example…


PS C:\Users\Simon\Scripts> .\Print-Activity..ps1
Getting printer events from Print-Svr-A
PS C:\Users\Simon\Scripts> .\Print-Activity..ps1 Print-Svr-B
Getting printer events from Print-Svr-B

Either way you should get a output similar to this that you can filter, sort etc to suit your needs…

Grid view output from script (sortable and filterable).

Grid view output from script (sortable and filterable).

Resolve Usernames

If you’d also like to be able to convert usernames into full names, then the following will try to use Active Directory to convert login names to display names…

$PrintServer = "Print-Svr-A"
 
$GetNamesFromAD = $true                     # Resolve user ID's to names
$MaxEvents = 1000                           # Max no of events to pull from print server
 
if (!$args[0]) {
} else {
$PrintServer = $args[0]
}
Write-Host "Getting printer events from $PrintServer"
 
$events = Get-WinEvent -ComputerName $PrintServer -FilterHashtable @{ LogName = "Microsoft-Windows-PrintService/Operational"; ID = 307} -MaxEvents $MaxEvents
 
Write-Host "Processing printer events"
 
$PrintEvents = @()                # Initialise array for printer logs
$users = @{}                      # Initialise hastable for user lookup
 
foreach ($log in $events) {
    if ($GetNamesFromAD) {
        $pEvent = "" | Select ID, Created, User, Name, Printer, SizeKB, Pages, Doc
    } else {
        $pEvent = "" | Select ID, Created, User, Printer, SizeKB, Pages, Doc
    }
    $pEvent.ID = $log.Properties.Value[0]
    $pEvent.Created = $log.TimeCreated
    $pEvent.User = $log.Properties.Value[2]
    $pEvent.Printer = $log.Properties.Value[4]
    $pEvent.SizeKB = [math]::Round($log.Properties.Value[6]/1024)
    $pEvent.Pages = $log.Properties.Value[7]
    $pEvent.Doc = $log.Properties.Value[1]
 
    if ($GetNamesFromAD) {
        if (!$users.ContainsKey($pEvent.User)) {
            $user = $pEvent.User
            $display = (Get-ADUser -Filter {SamAccountName -eq $user} -Property DisplayName).DisplayName
            $users.Add($pEvent.User, $display)
        }
        $pEvent.Name = $users.Get_Item($pEvent.User)
    }
 
    $PrintEvents += $pEvent
}
 
$PrintEvents | Out-GridView -Title "Printer events from $PrintServer"

3 Comments to “Who’s Printing What?”

  1. Simon Strutt says:

    Updated to specify max number of events gathered from server, and to only get relevant events.

    Additionally added extra example showing how to resolve login names to display names.

  2. dukot says:

    When I ran it on my print server, I get a list of the dates of the print jobs, but none of the other columns have any information. The power shell command line window shows the following:

    Cannot index into a null array.
    At C:\utils\print-activity-orl03.ps1:17 char:40
    + $pEvent.ID = $log.Properties.Value[ <<<< 0]
    + CategoryInfo : InvalidOperation: (0:Int32) [], RuntimeException
    + FullyQualifiedErrorId : NullArray

    Cannot index into a null array.
    At C:\utils\print-activity-orl03.ps1:19 char:42
    + $pEvent.User = $log.Properties.Value[ <<<< 2]
    + CategoryInfo : InvalidOperation: (2:Int32) [], RuntimeException
    + FullyQualifiedErrorId : NullArray

    Cannot index into a null array.
    At C:\utils\print-activity-orl03.ps1:20 char:45
    + $pEvent.Printer = $log.Properties.Value[ <<<< 4]
    + CategoryInfo : InvalidOperation: (4:Int32) [], RuntimeException
    + FullyQualifiedErrorId : NullArray

    Cannot index into a null array.
    At C:\utils\print-activity-orl03.ps1:21 char:58
    + $pEvent.SizeKB = [math]::Round($log.Properties.Value[ <<<< 6]/1024)
    + CategoryInfo : InvalidOperation: (6:Int32) [], RuntimeException
    + FullyQualifiedErrorId : NullArray

    Cannot index into a null array.
    At C:\utils\print-activity-orl03.ps1:22 char:43
    + $pEvent.Pages = $log.Properties.Value[ <<<< 7]
    + CategoryInfo : InvalidOperation: (7:Int32) [], RuntimeException
    + FullyQualifiedErrorId : NullArray

    Cannot index into a null array.
    At C:\utils\print-activity-orl03.ps1:23 char:41
    + $pEvent.Doc = $log.Properties.Value[ <<<< 1]
    + CategoryInfo : InvalidOperation: (1:Int32) [], RuntimeException
    + FullyQualifiedErrorId : NullArray

    Cannot index into a null array.
    At C:\utils\print-activity-orl03.ps1:17 char:40
    + $pEvent.ID = $log.Properties.Value[ <<<< 0]
    + CategoryInfo : InvalidOperation: (0:Int32) [], RuntimeException
    + FullyQualifiedErrorId : NullArray

    Cannot index into a null array.
    At C:\utils\print-activity-orl03.ps1:19 char:42
    + $pEvent.User = $log.Properties.Value[ <<<< 2]
    + CategoryInfo : InvalidOperation: (2:Int32) [], RuntimeException
    + FullyQualifiedErrorId : NullArray

    .
    .
    .

    • Simon Strutt says:

      Hi,

      This seems to suggest that there’s no content in your events!? Probably worth making sure you can see events with detail showing who printed what in the Print Service Operation log on the print server.

      What do you get if you run the following command from a PowerShell command prompt (make sure you change the print server ComputerName)…?

      Get-WinEvent -ComputerName Print-Svr-A -FilterHashtable @{ LogName = "Microsoft-Windows-PrintService/Operational"; ID = 307} -MaxEvents 1 | format-list *

Leave a Reply

XHTML: You can use these tags if you know what they are: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

ERROR: si-captcha.php plugin says GD image support not detected in PHP!

Contact your web host and ask them why GD image support is not enabled for PHP.

ERROR: si-captcha.php plugin says imagepng function not detected in PHP!

Contact your web host and ask them why imagepng function is not enabled for PHP.