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…
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:
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
------------
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.
I came across this thread when looking for a way to ingest my Windows Server print logs into Graylog and figured I would post what it took to get this working for me in case it helps anyone else who comes across this thread in the future… A little bit of modification was required to make the OP’s configuration work for my setup which is sidecar version 1.5.0.1 which includes winlogbeat v8. Based on my research trying to get this to work I believe the OP’s config was written for sidecar 1.4 or older which uses winlogbeat v7.
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("Windows Servers");
end
Also, like @cdshow I had to remove the appending winlogbeats from the input and adjust the route_to_stream line to match up with a Stream in my environment.