Wednesday, October 28, 2009

Microsoft Event Viewer meets Unix shell tools

Part of the core of Unix tool set philosophy is to use small single-purpose tools that both input and output text.These tools can then be chained together, massaging the text along the way.

Recently, I was tasked with retiring an aging Windows 2003 Server. As a part of that process, I wanted to find out what users were using the Printer shares on the machine.
Printer logging had been activated, and a typical printing event appeared in this format:
9/4/2009 9:26:03 AM Print Information None 10 DOMAIN\username SERVERNAME Document 56, Microsoft Word - Document10 owned by username was
printed on PRINTERNAME via port IP_192.1.3.212. Size in bytes: 108824; pages printed: 5

My goal was to output results like the following sorted by PRINTERNAME,username, and of course the Printing events were scattered among the other Windows events.

9/4/2009 9:26:03 Print DOMAIN\username PRINTERNAME

After exporting the log to text, copying it to a Linux machine, and researching, I came up with the following:

# Pull out references to printer events

grep Print.*Information $1 > temp.txt

# Chop off everything behind the printer name pull out desired fields with awk and then sort

while read line
do output=`expr "$line" : '\(.*printed on [a-zA-Z0-9_-]*\)'`
echo $output | awk '{print $1, $2, $4, $8, $NF }'
done < temp.txt | sort -k5,5 -k4,4

Well, it did the job, but I was later inspired to use 'sed' while reading "Classic Shell Scripting" by Arnold Robbins & Nelson H.F. Beebe .

grep Print.*Information $1 | sed s'/ via port.*//'g | awk '{print $1,$2,$4,$8,$NF}' | sort -k5,5-k4,4

Not surprisingly , execution time for the first script is :

real 0m5.531s
user 0m1.836s
sys 0m3.180s

Vs. the second:

real 0m1.271s
user 0m0.124s
sys 0m0.008s