This Powershell script allows you to easily generate the past one month email traffic report that consists of the following information:
- User
- Total Sent
- Total Sent (MB)
- Total Received
- Total Received (MB)
- Sent Internal
- Sent Internal (MB)
- Sent External
- Sent External (MB)
- Received Internal
- Received Internal (MB)
- Received External
- Received External (MB)
- Total Sent Unique
- Total Sent Unique (MB)
- Sent Internal Unique
- Sent Internal Unique (MB)
- Sent External Unique
- Sent External Unique (MB)
The report is in CSV format and it is stored in C drive.
$today = get-date
$rundate = $($today.adddays(-30)).toshortdatestring()
$outfile_date = ([datetime]$rundate).tostring("yyyy_MM")
$outfile = "Email_traffic_" + $outfile_date + ".csv"
$dl_stat_file = "DL_stats.csv"
$accepted_domains = Get-AcceptedDomain |% {$_.domainname.domain}
[regex]$dom_rgx = "`(?i)(?:" + (($accepted_domains |% {"@" + [regex]::escape($_)}) -join "|") + ")$"
$mbx_servers = Get-ExchangeServer |? {$_.serverrole -match "Mailbox"}|% {$_.fqdn}
[regex]$mbx_rgx = "`(?i)(?:" + (($mbx_servers |% {"@" + [regex]::escape($_)}) -join "|") + ")\>$"
$msgid_rgx = "^\<.+@.+\..+\>$"
$hts = get-exchangeserver |? {$_.serverrole -match "hubtransport"} |% {$_.name}
$exch_addrs = @{}
$msgrec = @{}
$bytesrec = @{}
$msgrec_exch = @{}
$bytesrec_exch = @{}
$msgrec_smtpext = @{}
$bytesrec_smtpext = @{}
$total_msgsent = @{}
$total_bytessent = @{}
$unique_msgsent = @{}
$unique_bytessent = @{}
$total_msgsent_exch = @{}
$total_bytessent_exch = @{}
$unique_msgsent_exch = @{}
$unique_bytessent_exch = @{}
$total_msgsent_smtpext = @{}
$total_bytessent_smtpext = @{}
$unique_msgsent_smtpext=@{}
$unique_bytessent_smtpext = @{}
$dl = @{}
$obj_table = {
@"
User = $($address.split("@")[0])
Total Sent = $(0 + $total_msgsent[$address])
Total Sent (MB) = $("{0:F2}" -f $($total_bytessent[$address]/1mb))
Total Received = $(0 + $msgrec[$address])
Total Received (MB) = $("{0:F2}" -f $($bytesrec[$address]/1mb))
Sent Internal = $(0 + $total_msgsent_exch[$address])
Sent Internal (MB) = $("{0:F2}" -f $($total_bytessent_exch[$address]/1mb))
Sent External = $(0 + $total_msgsent_smtpext[$address])
Sent External (MB) = $("{0:F2}" -f $($total_bytessent_smtpext[$address]/1mb))
Received Internal = $(0 + $msgrec_exch[$address])
Received Internal (MB) = $("{0:F2}" -f $($bytesrec_exch[$address]/1mb))
Received External = $(0 + $msgrec_smtpext[$address])
Received External (MB) = $("{0:F2}" -f $($bytesrec_smtpext[$address]/1mb))
Total Sent Unique = $(0 + $unique_msgsent[$address])
Total Sent Unique (MB) = $("{0:F2}" -f $($unique_bytessent[$address]/1mb))
Sent Internal Unique = $(0 + $unique_msgsent_exch[$address])
Sent Internal Unique (MB) = $("{0:F2}" -f $($unique_bytessent_exch[$address]/1mb))
Sent External Unique = $(0 + $unique_msgsent_smtpext[$address])
Sent External Unique (MB) = $("{0:F2}" -f $($unique_bytessent_smtpext[$address]/1mb))
"@
}
$props = $obj_table.ToString().Split("`n")|% {if ($_ -match "(.+)="){$matches[1].trim()}}
$stat_recs = @()
function time_pipeline {
param ($increment = 1000)
begin{$i=0;$timer = [diagnostics.stopwatch]::startnew()}
process {
$i++
if (!($i % $increment)){Write-host “`rProcessed $i in $($timer.elapsed.totalseconds) seconds?-nonewline}
$_
}
end {
write-host “`rProcessed $i log records in $($timer.elapsed.totalseconds) seconds?
Write-Host " Average rate: $([int]($i/$timer.elapsed.totalseconds)) log recs/sec."
}
}
foreach ($ht in $hts){
Write-Host "`nStarted processing $ht"
get-messagetrackinglog -Server $ht -Start "$rundate" -End "$today" -resultsize unlimited |
time_pipeline |%{
if ($_.eventid -eq "DELIVER" -and $_.source -eq "STOREDRIVER"){
if ($_.messageid -match $mbx_rgx -and $_.sender -match $dom_rgx) {
$total_msgsent[$_.sender] += $_.recipientcount
$total_bytessent[$_.sender] += ($_.recipientcount * $_.totalbytes)
$total_msgsent_exch[$_.sender] += $_.recipientcount
$total_bytessent_exch[$_.sender] += ($_.totalbytes * $_.recipientcount)
foreach ($rcpt in $_.recipients){
$exch_addrs[$rcpt] ++
$msgrec[$rcpt] ++
$bytesrec[$rcpt] += $_.totalbytes
$msgrec_exch[$rcpt] ++
$bytesrec_exch[$rcpt] += $_.totalbytes
}
}
else {
if ($_messageid -match $messageid_rgx){
foreach ($rcpt in $_.recipients){
$msgrec[$rcpt] ++
$bytesrec[$rcpt] += $_.totalbytes
$msgrec_smtpext[$rcpt] ++
$bytesrec_smtpext[$rcpt] += $_.totalbytes
}
}
}
}
if ($_.eventid -eq "RECEIVE" -and $_.source -eq "STOREDRIVER"){
$exch_addrs[$_.sender] ++
$unique_msgsent[$_.sender] ++
$unique_bytessent[$_.sender] += $_.totalbytes
if ($_.recipients -match $dom_rgx){
$unique_msgsent_exch[$_.sender] ++
$unique_bytessent_exch[$_.sender] += $_.totalbytes
}
if ($_.recipients -notmatch $dom_rgx){
$ext_count = ($_.recipients -notmatch $dom_rgx).count
$unique_msgsent_smtpext[$_.sender] ++
$unique_bytessent_smtpext[$_.sender] += $_.totalbytes
$total_msgsent[$_.sender] += $ext_count
$total_bytessent[$_.sender] += ($ext_count * $_.totalbytes)
$total_msgsent_smtpext[$_.sender] += $ext_count
$total_bytessent_smtpext[$_.sender] += ($ext_count * $_.totalbytes)
}
}
if ($_.eventid -eq "expand"){
$dl[$_.relatedrecipientaddress] ++
}
}
}
foreach ($address in $exch_addrs.keys){
$stat_rec = (new-object psobject -property (ConvertFrom-StringData (&$obj_table)))
$stat_recs += $stat_rec | select $props
}
$stat_recs | export-csv C:\$outfile -notype
if (Test-Path $dl_stat_file){
$DL_stats = Import-Csv $dl_stat_file
$dl_list = $dl_stats |% {$_.address}
}
else {
$dl_list = @()
$DL_stats = @()
}
$DL_stats |% {
if ($dl[$_.address]){
if ([datetime]$_.lastused -le [datetime]$rundate){
$_.used = [int]$_.used + [int]$dl[$_.address]
$_.lastused = $rundate
}
}
}
$dl.keys |% {
if ($dl_list -notcontains $_){
$new_rec = "" | select Address,Used,Since,LastUsed
$new_rec.address = $_
$new_rec.used = $dl[$_]
$new_rec.Since = $rundate
$new_rec.lastused = $rundate
$dl_stats += @($new_rec)
}
}
Write-Host "`nRun time was $(((get-date) - $today).totalseconds) seconds."
Write-Host "Email stats file is $outfile"
Got this when I tried to run the script:
ReplyDelete[PS] D:\lou>./EmailTrafficReporting.ps1
The string starting:
At D:\lou\EmailTrafficReporting.ps1:49 char:2
+ <<<< @"
is missing the terminator: "@.
At D:\lou\EmailTrafficReporting.ps1:204 char:1
+ <<<<
+ CategoryInfo : ParserError: ( User = $($addr...$outfile`"
:String) [], ParseException
+ FullyQualifiedErrorId : TerminatorExpectedAtEndOfString
How did you run the script? Did you modify the script according to your environment?
DeleteWhich values do I need to modify? I didn't set the environment either. Please help!
ReplyDeleteWhere did you run the codes?
DeleteExchange 2010 powershell
ReplyDeleteI think the problem is because of the spacing and paragraph problem. Please try to copy the code to MS Word or Notepad and eliminate the extra spacing and paragraph. I think it should work.
DeleteHi Andres,
ReplyDeleteCould you provide the script in the form of PS1 file as a downloadable link? That would help us to run it smooth.
Hi Kishore,
DeleteI prefer you generate the PS1 yourself because you may need to customize the code based on your environment.
Thanks for sharing helpful script, it allows to easily generate the email traffic report, but I already tried this exchange reporter tool ( http://www.lepide.com/exchange-reporter/general-reports.html ) which assists to generate the email flow reports in both graphical and tabular format and export the collected data in different files formats like html, csv, xls, mht and rtf.
ReplyDelete