Thursday, October 18, 2007

Exchange 2007 Content Agent Log Message Tracker Gui

One of the cool features from a logging perspective on Exchange 2007 is the ability to log the SCL of every message when you have the Content Filtering Agent enabled (and also logging enabled). There is a Exchange Management Shell powershell cmdlet for reading these logs called get-agentlog which gives a good cmdline experience but as these logs are something you might want to check on a regular basis and the information contained in them is a little unwieldy to display in a cmdline environment I decided to put together a little GUI to make my life a little easier. I based the GUI on my Exchange 2000/3 WMI message tracker and I was able to carry over a lot of the cool little aggregation functions of this utility using most of the same code with a few tweaks here and there.
What this script does is creates a Winform and adds a whole bunch of controls to that winform such as datapickers, textboxes, checkboxes,labels and buttons. Its then wires ups some functions to the button clicks so that when you click the search button in will run the get-agentlog cmdlet with parameters for the daterange you specified in the GUI. To make sure you only get the events in the log that relate to the content filter it use a filter $_.agent -eq "Content Filter Agent”
The data returned by get-agent log is then added to a ADO.NET data table which is then data bound to a datagridview to display back in the form. Clicking the export button will fire a save-file dialogue box and some code will then export the table results to a csv file.
There are textboxes to allows you to search based on the from and/or To address.
There is a drop down list to allow you to select a SCL level to look at so you can choose to filter by only messages that have been assigned a specific SCL value.
The Extra sections has the aggregate options currently it has four aggregate option is can aggregate
By SCL this shows you by SCL Value how many messages where received between the dates specified
By Receiver will show you grouped by receiver how many messages have been received for each SCL value
By Sender will show you grouped by Sender(P1) how many messages have been received for each SCL value
By Date will show you by Date how many messages have been received for each SCL value.
Currently the script is only designed to be run locally on the Exchange box where the agent logs files are located. The Get-agentlog cmdlet doesn’t have a server parameter although it does have a log file location parameter so this maybe an option if you did want to run this script from a machine other then the Local Exchange server. To run the script is basically straight forward when you run it the script will build the winform and should then present this as an active window. Select the date you want to scan and the click the search button.
This is really only kind of scratching the surface of what you could do with the agent logs im working on a geolcation version so I can show the country origins of SCL values and also a version that will integrated the message tracking logs so I can include subject information in with the SCL. Also there is a lot more then just the content filtering information stored in the agent logs other things such as RBL use and effectiveness can be reported and other Transport agents that log to these files.
I’ve put a download of the code here It’s a bit to large to past verbaitem in the blog the main get-aglog section looks like
$filter = "$_.agent -eq ""Content Filter Agent"""
$dtQueryDT = New-Object System.DateTime $dpTimeFrom.value.year,$dpTimeFrom.value.month,$dpTimeFrom.value.day,$dpTimeFrom2.value.hour,$dpTimeFrom2.value.minute,$dpTimeFrom2.value.second
$dtQueryDTf = New-Object System.DateTime $dpTimeFrom1.value.year,$dpTimeFrom1.value.month,$dpTimeFrom1.value.day,$dpTimeFrom3.value.hour,$dpTimeFrom3.value.minute,$dpTimeFrom3.value.second
if ($extrasettings -eq 0){
get-agentlog -StartDate $dtQueryDT -EndDate $dtQueryDTf | where {$filter} | ForEach-Object {
$exclude = 0
if ($sclFilterboxCheck.Checked -eq $true -band $_.ReasonData -ne $sclFilterboxDrop.SelectedItem){$exclude = 1}
$repstring = ""
$incRec = $false
$p2string = [string]::join(" , ", $_.P2FromAddresses)
$repstring = [string]::join(" , ",$_.Recipients)
if ($snSenderAddressTextBox.text -ne ""){
if ($snSenderAddressTextBox.text.ToString().ToLower() -eq $_.P1FromAddress.ToString().ToLower()){
$incRec = $true
}
}
else {
if ($snRecipientAddressTextBox.text.ToString().ToLower() -ne ""){
if ($repstring -match $snRecipientAddressTextBox.text.ToString().ToLower()){
$incRec = $true
}
}
else{$incRec = $true}
}
if ($incRec -eq $true -band $exclude -eq 0){$ssTable.Rows.Add($_.Timestamp,$_.P1FromAddress,$p2string,$repstring,$_.Action,$_.Reason,$_.ReasonData)}
}
$dgDataGrid.DataSource = $ssTable}
else{
get-agentlog -StartDate $dtQueryDT -EndDate $dtQueryDTf | where {$filter} | ForEach-Object {
if ($GroupbySCL.Checked -eq $true){
[String]$sclival = "SCL " + $_.ReasonData
if ($sclhash.ContainsKey($sclival)){
$tsize = [int]$sclhash[$sclival] + 1
$sclhash[$sclival] = $tsize
}
else{
$sclhash.add($sclival,1)
}

}
if ($GroupByReciever.Checked -eq $true){
foreach($recp in $_.Recipients){
$sclagkey = $recp.ToString().replace("|","-") + "|" + $_.ReasonData
AggResults($sclagkey)
}

}
if ($GroupBySender.Checked -eq $true){
$sclagkey = $_.P1FromAddress.ToString().replace("|","-") + "|" + $_.ReasonData
AggResults($sclagkey)
}
if ($GroupByDate.Checked -eq $true){
$sclagkey = $_.Timestamp.toshortdatestring().replace("|","-") + "|" + $_.ReasonData
AggResults($sclagkey)
}

}

foreach($sclval in $sclhash.keys){
$sclTable.rows.add("",$sclval,$sclhash[$sclval])
}
foreach($adr in $gbhash1.keys){
$daDatarray = $adr.split("|")
$sclTable.rows.add($daDatarray[0],$daDatarray[1],$gbhash1[$adr])
}
$dgDataGrid.DataSource = $sclTable


}
}

34 comments:

Jon said...

I know nothing about PowerShell. Trying to use this script, PowerShell spits this error when I click Search:

The term 'get-agentlog' is not recognized as a cmdlet, funciton, operable program, or script file. Verify the term and try again. At C:\cagentTracker.ps1:43 char: 14

Glen said...

Get-agentlog is a Exchange Management Shell cmdlet so this script needs to be run from within the Exchange Management shell on the Exchange Server where you have logging enabled. (That error sounds like you just trying to run it from Powershell which wont work)

cheers
Glen

Anonymous said...

Awesome tool.

One thing, the export button doesn't bring out all the columns such as "Reason"

Glen said...

Thanks that should now be fixed

Cheers
Glen

Chris Mace said...

What command are you guys typing to get the desired outcome. When I type in the get-agentlog command it doesnt populate a gui, it just executes a ton of entries from the agent log file.

THanks
Chris Mace

Glen said...

This is a script that uses Get-Agentlog logs to produce a GUI. Get-agentlog itself will just show you the output of the Log file which while usefull is much help hence i built a GUI to show this information in a filter format. You need to download and run the script if you want to see the information in this way.

cheers
Glen

JJB said...

Thanks Thanks Thanks!!!!
I'm sure you spent allot of time on this. I don't understand why Microsoft didn't build somthing like this in. This is most helpfull script I have found.

Federico said...

Great Script Glenn.

Thank you very much,
Federico

Anonymous said...

***** What a great Script, Glen ****
Thanks a lot
Bertrand

Anonymous said...

WOW a script that really kicks some serious tail!

Very nice, KUDO's!!

Anonymous said...

Excellent stuff, thank you!

FatManRunning said...

Pardon my ignorance, but I'm running into a problem trying to use your script. After downloading it and dropping it into my Scripts folder, I get an error when trying to execute it: "...cagentTracker.ps1 is not digitally signed..." What can I do to either sign it, or to force my server to let it run?

Glen said...

Have a read of http://www.windowsecurity.com/articles/PowerShell-Security.html which explains the security setting of powershell and you can either decide to change you execution policy or sign the script yourself.

Cheers
Glen

Sigi said...

Does this script work on Exchange 2010 servers as well or is there an update needed?

Glen said...

The cmdlets are the same so it should work okay but have tested it myself.

Cheers
Glen

Anonymous said...

Glenn,

I am having the same issue where it tells me that the script is not digitally signed. I'm running Exchange 2010. Can you please help??

I placed the script in:
C:\Program Files\Microsoft\Exchange Server\V14\Scripts

Then I ran the script from EMS and that's where it barked at me.

Glen said...

Right click the script select properties and click unblock see http://www.hanselman.com/blog/RemovingSecurityFromDownloadedPowerShellScriptsWithAlternativeDataStreams.aspx.

Cheers
Glen

jaustin1 said...

Definitely a great idea!

I'm also running the script in Exchange 2010, and it seems to run fine (after Unblocking; thanks for that tip) but regardless of what addresses/dates/options I use, there are no results. Get-agentlog still returns results from the command line as expected, but I can't get this script to return anything.

Glen said...

I haven't yet tried this on 2010 is the filter working okay eg

$filter = "$_.agent -eq ""Content Filter Agent"

If you run the cmdlet from the cmd prompt what filters are you using ?

Cheers
Glen

jaustin1 said...

Glen, thanks so much for your response and your continued support of this helpful script.

I ran the script again just now, and it returned the expected results.

*shrug*

Thanks again!

Anonymous said...

Unbelievable. M$ should be paying you to make their product usable. Forget this 20 year old CLI crap. We want GUIs!

Jon said...

Wow! Awesome. I cant believe that MS is going back to CLIs. Seems A$$ backwards to me!

Atleast SOMEONE gets it!

Great tool. Thanks Glen!

Dave said...

Great script... Thanks!
I'm running this on Exchange 2007 and get the expected results. One thing that's having a problem is after I click the Export button, nothing happens and the program eventually freezes up (Not responding)... No entries in the log files either. Any ideas?

Glen said...

find the line

$exFileName.ShowDialog()

and add this

$exFileName.ShowHelp = $true
$exFileName.ShowDialog()

cheers
Glen

Dave said...

That did the trick... Thanks!

Anonymous said...

I seem to be missing a scroll bar for long lists of results. Is there something I am doing wrong?

Thanks,
Jerry

Tony Richards said...

I need to modify it to search exchange tracking logs in a folder on a standalone PC (offline). Any suggestions?

Anonymous said...

I use this powershell to Exchange 2010, but when I filter time less than 1hr(startdata, enddata), will show "doesn't contain any logs for the specified time range", and get nothing...but it had log in agentlog file, the powershell seem can't run, if filter time less tahn 1hr, can fix it??

33 said...

Thanks for the effort on this. Very helpful! Kudos!

Anonymous said...

Amazing Script, untill now we have been on the dark regarding SCL tagging!
This is a funcionality that exch2007 sould have in the first place!
Thank you very very much

Anonymous said...

Hi
is it possible to get a live link for this script?
Thank you

Glen Scales said...

see https://github.com/gscales/Powershell-Scripts/blob/master/ScriptArchive/cagentTracker.zip

Anonymous said...

you are a champion, very nice script

Paul Scott said...

Can you please provide an example of how to run this script? After downloading and unzipping, I right click on it, and select the "Run With PowerShell.." option, and a blank DOS screen appears for a minute, then disappears. How is this script run exactly?