Saturday, November 07, 2009

Reporting on Outlook Anywhere users from the IIS logs using Powershell

Logs files are great things but as with a lot of things the hidden value of these resources is often hard to see at there face value. I had a very simple problem this week where i needed to know which users where using Outlook Anywhere and what their IPAddress where. For this the IIS logs could more then provide an answer for this but these log files and get quite large and contain a mix of different information not just Outlook http/rpc traffic.

One of the main challenges you have when looking at IIS logs files is that depending on who enabled logging the Fields and the order they are being logged in may differ. So a parser/script you write to work against one set of logs might not work against another server. To solve this problem is quite simple when a log file is created at the top of the log file on line 4 is written the field format for the file. So if you first read this line parse it into a Hashtable and index it by the fieldname we then know what the index array value will be when you go to read each line of the log file for the field you want to extract.

To make the script easy to use I've added a front end GUI component to make the script present a file select box to select the log file to work with. It then reads the file using get-content and filters it based on OutlookAnywhere log entries using a like filter on “*MSRPC*”. The script groups the results by IPAddress and UserName and builds a exportable collection that produces a csv file or the results of the scan with a simple list of OutlookAnywhere users and what IP address they came from. The cool thing about the script is that it can be easily adapted to scan for anything in a IIS log file eg say you wanted a list of people using a Iphone and their IPaddress.

I've put a download of the script here the script itself looks like

[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")
$exFileName = new-object System.Windows.Forms.openFileDialog
$exFileName.ShowHelp = $true
$exFileName.ShowDialog()

$fname = $exFileName.FileName
$mbcombCollection = @()
$FldHash = @{}
$usHash = @{}
$fieldsline = (Get-Content $fname)[3]
$fldarray = $fieldsline.Split(" ")
$fnum = -1
foreach ($fld in $fldarray){
$FldHash.add($fld,$fnum)
$fnum++
}

get-content $fname | Where-Object -FilterScript { $_ -ilike “*MSRPC*” } | %{
$lnum ++
if ($lnum -eq $rnma){ Write-Progress -Activity "Read Lines" -Status $lnum
$rnma = $rnma + 1000
}
$linarr = $_.split(" ")
$uid = $linarr[$FldHash["cs-username"]] + $linarr[$FldHash["c-ip"]]
if ($linarr[$FldHash["cs-username"]].length -gt 2){
if ($usHash.Containskey($uid) -eq $false){
$usrobj = "" | select UserName,IpAddress
$usrobj.UserName = $linarr[$FldHash["cs-username"]]
$usrobj.IpAddress = $linarr[$FldHash["c-ip"]]
$usHash.add($uid,$usrobj)
$mbcombCollection += $usrobj

}
}
}

$mbcombCollection | export-csv –encoding "unicode" -noTypeInformation c:\oareport.csv

11 comments:

Jeremy said...

Great article! How could this be modified to perform similiar reporting on users using OWA? when I read through my IIS log from OWA I see alot of get and post commands but nothing that would seem to be user specific other than the source IP.

Glen said...

This is the string i used to do OWA reporting

$_ -ilike “*/owa/default.aspx*”

Cheers
Glen

bunty said...

Hi Glen,

I tried to change it to $_ -ilike “*/owa/default.aspx*”
but i was unable to get the results properly, also i need to find the browser version on of the client is trying to access owa from.

Darwin Observer said...

i see that it is looking for an input file (.txt) what format is it looking for. and what needs to be in it? just the server name? (fqdn?) can this be run remotely or does it have to be done locally.

Glen said...

This does a direct parse of the IIS log file. Where the IIS log files are using the default format (which escapes me at the moment) if your using one of the other formats the parser will fail. You can run the script from anywhere as long as you have a mapped drive or copy the IIS log file locally.

Cheers
Glen

Darwin Observer said...

ah. I read this article wrong. thank you.

so, i would have to run this script against each log file? How would one point at a top folder and have the script look at all the files below?

Glen said...

You would need to write something that wraps around this script that would enumerate the files in the directory something like http://www.computerperformance.co.uk/ezine/ezine133.htm could be used to feed the script.

Cheers
Glen

Praveen Balan said...

Great post, really helped me..

Anonymous said...

I use Outlook Anywhere but dont find MSRPC in my logs. Is there another way to identify these connections within IIS?

Nick said...

I'm in the same boat -- Is there different string in the IIS logs for Exchange 2010 Outlook anywhere ?

Anonymous said...

Should i run this script directly from powershell after navigating to the IIS logs folder?