All Exchange admins have been there. You have moved all your mailboxes and want to decommission the server but before you uninstall, you check the SMTP logfile (for Exchange 2010, that is \Program Files\Microsoft\Exchange Server\V14\TransportRoles\Logs\ProtocolLog\SmtpReceive) and you see thousands of servers still using it as an SMTP Relay. You need to get a list…

Surely, you could manually merge all the files, use some Excel magic and eventually get the list. But you need to redo this every week or so until the logfile is empty. There must be a better way. PowerShell of course! Below might not be the quickest way but at least it gets the job done and for me, it’s a good example on learning PowerShell.

I usually start with merging the files together and filtering out the rows you are interested in since these are the rows that actually contain the information I need and cuts the amount of data to crunch, often by 99%.

Get-Content .\RECV*.log | where { $_ -match “MAIL FROM” -or $_ -match “RCPT TO” } | Add-Content .\SMTP.csv

Import the CSV. I also add the headers to make it easier to work with and just select the interesting columns.

$SMTP = Import-Csv -Header datetime,connectorid,sessionid,sequencenumber,localendpoint,remoteendpoint,event,data,context SMTP.csv | Select-Object remoteendpoint,data

Lets say you want the list of IP-addresses still sending e-mail via this Exchange server. Just filter out the remoteendpoint column, remove the port number in the IP-address and sort it on unique records:

$SMTP | ForEach-Object {$_.remoteendpoint.split(‘:’)[0]} | Sort-Object -Unique

Maybe you just want to MAIL FROM or RCPT TO addresses?

$SMTP | Where-Object{$_.data -like “MAIL FROM:*”} | ForEach-Object {$_.data.TrimStart(‘MAIL FROM:<‘).TrimEnd(‘>’)} | Sort-Object -Unique
$SMTP | Where-Object{$_.data -like “RCPT TO:*”} | ForEach-Object {$_.data.TrimStart(‘MAIL FROM:<‘).TrimEnd(‘>’)} | Sort-Object -Unique

An alternative with Hashtable…

I then found an alternative way of doing it using Hashtable, the idea I got from here.

Get-Content .\RECV*.log | where { $_ -match “MAIL FROM” } | Add-Content .\SMTP.csv

$uniqueIPs = @{}
$logFileContents = Get-Content .\SMTP.CSV
$columnNum = 5

foreach ($line in $logFileContents)
{
$lineFields = $line.Split(“,”);
$interestingValue = $lineFields[ $columnNum ];
$interestingValue = $interestingValue.Split(“:”)[0];
if ($uniqueIPs[ $interestingValue ] -eq $null)
{
$uniqueIPs[ $interestingValue ] = 1;
}
else
{
$uniqueIPs[ $interestingValue ]++;
}
}

$uniqueIPs

Hope this gives you some ideas how to quickly filter SMTP logs.