Tracking Print Jobs

While tooling around on the internets I came across some logging information on Windows Print jobs. Our current setup shoots all of the company print jobs through a couple of Windows print servers and it turns out it is easy to turn on logging and track who is printing what, when, where and how many. First on the windows server you can enable tracking for print jobs (off by default) here: Event viewer->Applications and services Logs->Microsoft->Windows->PrintService Right click on Operational and choose enable log. There are a couple of events that show up but we are interested in Event ID 307 which will give us logs such as the following:

Document 90, Print Document owned by EmployeeOne on Workstation-10 was printed on BIG_COLOUR_PRINTER through port 10.77.1.211.  Size in bytes: 58920. Pages printed: 7. No user action is required.

Assuming you are picking it up via Winlogbeats, here is a Sidecar configuration that would make sure the print job is snagged - note how I am dropping eventID 801,805, and 842 since they aren’t’ relevant to this and I don’t want to fill my Graylog with anything uninteresting…

# Needed for Graylog
fields_under_root: true
fields.collector_node_id: ${sidecar.nodeName}
fields.gl2_source_collector: ${sidecar.nodeId}

output.logstash:
   hosts: ["${user.BeatsInput}"]
path:
  data: C:\Program Files\Graylog\sidecar\cache\winlogbeat\data
  logs: C:\Program Files\Graylog\sidecar\logs
tags:
 - windows
logging.metrics.enabled: false
winlogbeat:
  event_logs:
   - name: Application
   - name: System
   - name: Security
   - name: Microsoft-Windows-PrintService/Operational
     processors:
       - drop_event.when:
           or:
             - equals.winlog.event_id: "800"
             - equals.winlog.event_id: "801"
             - equals.winlog.event_id: "805"
             - equals.winlog.event_id: "842"

Beats does a good job of picking things out but doesn’t give them pretty fieldnames so I have a pipeline rule these logs pass through as follows:

rule "Printer_Tracking"
when
    // Function converts generic fields names to useful ones
    // then removes the unhelpful fieldnames because we don't want them
    to_string($message.winlog_event_id) == "307"
then
    // change fields to something that makes sense.

    set_field("print_user",              $message.winlog_user_data_Param3);
    set_field("printed_from",            $message.winlog_user_data_Param4);
    set_field("printer_name",            $message.winlog_user_data_Param5);
    set_field("printed_from_ip",         $message.winlog_user_data_Param6);
    set_field("page_count",      to_long($message.winlog_user_data_Param8));
    remove_field("winlog_user_data_Param1"); // document number
    remove_field("winlog_user_data_Param2"); // action i.e.  "Print Document"
    remove_field("winlog_user_data_Param3");
    remove_field("winlog_user_data_Param4");
    remove_field("winlog_user_data_Param5");
    remove_field("winlog_user_data_Param6");
    remove_field("winlog_user_data_Param7");  //size in bytes
    remove_field("winlog_user_data_Param8"); 
    remove_field("winlog_process_thread_id"); // who cares about the thread id? Not me. 
    remove_field("winlog_process_pid");       // who cares about the pid?       Also Not me. 
    remove_field("winlog_opcode"); //  
    // Pull out for reporting
    route_to_stream("Printing_reports_stream");      

end

SIDE NOTE: You could manage renaming the fields in the collector if you want - follow instructions here

And you can end up with something like this barely redacted page:

2 Likes

I have tried everything to get this pipeline to work and I can’t seem to get the rename/set field portion of this to work. The routing portion works but the setting field names doesn’t I have tried every combination I can think of, I had to change the $message.winlog_event_id to $message.winlogbeat_event_id but I can’t figure out how to make it work with the Paramaters, I have 2 different options I have tried in here for Param 3 & 8 and neither one work. I feel like I’ve almost gotten it but I can’t find any documentation about using the variable $message with specific fields.

----------

rule "Printer_Tracking"
when
    // Function converts generic fields names to useful ones
    // then removes the unhelpful fieldnames because we don't want them
    to_string($message.winlogbeat_event_id) == "307"
then
    // change fields to something that makes sense.
    set_field("print_user",              $message.winlogbeat_winlog_user_data_Param3);
    set_field("printed_from",            $message._winlog_user_data_Param4);
    set_field("printer_name",            $message._winlog_user_data_Param5);
    set_field("printed_from_ip",         $message._winlog_user_data_Param6);
    set_field("page_count",      to_long($message.user_data_Param8));
    remove_field("winlogbeat_winlog_user_data_Param1"); // document number
    remove_field("winlog_user_data_Param2"); // action i.e.  "Print Document"
    remove_field("winlog_user_data_Param3");
    remove_field("winlog_user_data_Param4");
    remove_field("winlog_user_data_Param5");
    remove_field("winlog_user_data_Param6");
    remove_field("winlog_user_data_Param7");  //size in bytes
    remove_field("winlog_user_data_Param8"); 
    remove_field("winlog_process_thread_id"); // who cares about the thread id? Not me. 
    remove_field("winlog_process_pid");       // who cares about the pid?       Also Not me. 
    remove_field("winlog_opcode"); //  
    // Pull out for reporting
    route_to_stream("Printing_reports_stream");      

end
------------

Any thoughts/advice?

Moved to a dedicated thread.
Printer tracking pipeline - $message_ field names not working for set or rename - Templates and Rules Exchange / Pipeline Rules - Graylog Community

Long story short we had 2 problems, 1 we needed to remove the appending of winlogbeats from the input & 2 we had miss-named the stream Printer_reports_stream rather than Printing_reports_stream. Just for anyone else that attempts this dashboard.