Exchange 2010 statystyka wysyłanych emaili – messagetrackinglog

This post is also available in: angielski

emailOstatnio pisaliśmy o tym jak znaleźć wszystkich odbiorców danego emaila:

Exchange MessageTrackingLogs wyszukanie wszystkich odbiorców emaila

 

Teraz przedstawimy skrypt który pomoże nam wygenerować statystykę wysyłanych emaili.

Niemniej jednak nie interesuje nas ilość wszystkich wysyłanych emaili, ich rozmiar, tylko skupimy się na emailach wysyłanych poza naszą organizację Exchange i uzyskamy informację o tym z jakich adresów zostały wysłane, z jakim tematem, ile było tych emaili i do ilu odbiorców zostały przesłane.

Skrypt ten umożliwia uzyskanie informacji o adresach email które wysyłają najwięcej wiadomości na zewnątrz.
Jego działanie oparte jest na sprawdzeniu logów transportowych (TransportLogs) umieszczonych na serwerach Exchange z rolami Hub Transport.

Po otrzymaniu wyników skryptu możemy skorzystać ze skryptu z poprzedniego posta i dowiedzieć się do kogo została wysłana wiadomość.

 

Poniżej przedstawiamy kolejne fragmenty skryptu z opisem działania:

Pierwszy fragment zawiera:

  • definicje obiektów wynikowych z raportami
  • ścieżek do plików przechowujących wszystkie otrzymane wyniki
  • ustawienia do wysłania raportu emailem
  • $MAX_Recipients – liczba odbiorców powyżej której wygenerowany zostanie email z raportem

 

Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
Set-AdServerSettings -ViewEntireForest $True

Function New-Array {,$args}

$Report = New-Array
$Report_SMTP = New-Array
$Rep_sum = New-Array
$Rep_SMTP_sum = New-Array

$data = $($((get-date).adddays(-1)).ToString('yyyy.MM.dd'))

#paths to output files
$Out_Rep_file = "d:\Scripts\Logs\Stats\msg_stat_out_$data.csv"
$Out_Rep_sum_file = "d:\Scripts\Logs\Stats\msg_stat_out_sum_$data.csv"

#files with emails with smtp traffic
$Out_Rep_SMTP_file = "d:\Scripts\Logs\Stats\msg_stat_smtp_out_$data.csv"
$Out_Rep_SMTP_sum_file = "d:\Scripts\Logs\Stats\msg_stat_smtp_out_sum_$data.csv"
#file with report attached to email (emails recipients grater than $MAX_Recipients)
$Email_HTML_File = "d:\Scripts\Logs\Stats\Report_outgoing_emails_$data.htm"

#settings for email with report
$mail_from = "exchangereport@domain.com"
$mail_to = "admin@domain.com"
$mail_smtp_host = "smtpserver.domain.local"
$mail_subject = "Report outgoing emails $data"

#variable that defines the threshold for recipients to write to email report
$MAX_Recipients = 100

 

Pliki wynikowe podzielone sa na:

  • out_$data.csv – plik zawierajacy wszystkie emaile wysylane na zewnatrz
  • out_sum_$data.csv – plik zawierający emaile wysylane na zewnątrz pogrupowane po temacie i adresie nadawcy

 

Dodatkowo pliki zawierają w nazwie wpis SMTP co oznacza, że zawarte są w nich również emaile „przechodzące” przez nasze serwery HT przekazywane do internetu.
Ma to zastosowanie w przypadku rozbudowanej organizacji Exchange oraz systemow, skryptow automatycznie wysyłających emaile.

 

W kolejnej części pobieramy domeny obsługiwane przez nasze serwery Exchange, a następnie przeszukujemy logi TransactionLogs z ostatnich 24h pobierając tylko te emaile które:

  • source wynosi SMTP oraz eventid wynosi Receive – emaile otrzymane do przesłania
  • source wynosi STOREDRIVER oraz eventid wynosi Receive – są to emaile które zostały wysłane ze skrzynek znajdujących się na naszych serwerach.

 

$accepted_domains = Get-AcceptedDomain |% {$_.domainname.domain} 
[regex]$dom_rgx = "`(?i)(?:" + (($accepted_domains |% {"@" + [regex]::escape($_)}) -join "|") + ")$"

Get-TransportServer | Get-MessageTrackingLog -resultsize unlimited -start (get-date).addhours(-24) -end (get-date) -EventId Receive | ? {$_.source -eq "SMTP" -or $_.source -eq "STOREDRIVER"} | % {

 #get emails with evnetid Receive and source SMTP
 if ($_.eventid -eq "RECEIVE" -and $_.source -eq "SMTP"){ 
  if ($_.recipients -notmatch $dom_rgx){ 
 $timestamp = ''
 $ext_count = ''
 $subject = ''
 $sender = ''
 $server = ''
 $msgID = ''

 $timestamp = $_.timestamp
 $ext_count = ($_.recipients -notmatch $dom_rgx).count 
 $subject = $_.messagesubject
 $sender = $_.sender
 $server = $_.serverhostname
 $msgID = $_.MessageId 

 $tmp = New-Object System.Object
 $tmp | Add-Member -type NoteProperty -name Timestamp -value $timestamp
 $tmp | Add-Member -type NoteProperty -name Sender -value $sender  $tmp | Add-Member -type NoteProperty -name Subject -value $Subject
 $tmp | Add-Member -type NoteProperty -name Recipients -value $ext_count
 $tmp | Add-Member -type NoteProperty -name Server -value $server  $tmp | Add-Member -type NoteProperty -name MsgID -value $msgID

 $Report_SMTP += $tmp
 } 
}
 #get emails with evnetid Receive and source StoreDriver
 if ($_.eventid -eq "RECEIVE" -and $_.source -eq "STOREDRIVER"){ 
 if ($_.recipients -notmatch $dom_rgx){ 
 $timestamp = ''
 $ext_count = ''
 $subject = ''
 $sender = ''
 $server = ''
 $msgID = ''

 $timestamp = $_.timestamp
 $ext_count = ($_.recipients -notmatch $dom_rgx).count 
 $subject = $_.messagesubject
 $sender = $_.sender
 $server = $_.serverhostname
 $msgID = $_.MessageId

 $tmp = New-Object System.Object
 $tmp | Add-Member -type NoteProperty -name Timestamp -value $timestamp
 $tmp | Add-Member -type NoteProperty -name Sender -value $sender
 $tmp | Add-Member -type NoteProperty -name Subject -value $Subject
 $tmp | Add-Member -type NoteProperty -name Recipients -value $ext_count
 $tmp | Add-Member -type NoteProperty -name Server -value $server
 $tmp | Add-Member -type NoteProperty -name MsgID -value $msgID

 $Report += $tmp

 } 
 }
}

 

Kolejnym krokiem jest pogrupowanie otrzymanych wyników według adresu nadawcy, a następnie według tematu wiadomości:

 

#group sender to get unique senders smtp addresses
$emails = $Report | Group-Object sender | sort name
$emails_smtp = $Report_SMTP | Group-Object sender | sort name
foreach ($sender in $emails){
 $Report | ? {$_.sender -like $($sender.name)} | Group-Object subject | %{ 
 $Rep_sum += New-Object psobject -property @{
 Sender = $($sender.name)
 Subject = $_.Name
 Recipients_count = ($_.group | Measure-Object Recipients -Sum).sum
 Emails = $_.count
 }
 } 
}
foreach ($sender in $emails_smtp){
 $Report_SMTP | ? {$_.sender -like $($sender.name)} | Group-Object subject | %{ 
 $Rep_SMTP_sum += New-Object psobject -property @{
 Sender = $($sender.name)
 Subject = $_.Name
 Recipients_count = ($_.group | Measure-Object Recipients -Sum).sum
 Emails = $_.count
 }
 } 
}

 

Teraz pozostaje nam utworzenie plików .csv z raportami oraz wygenerowanie pliku raportu dla alertu wysyłanego emailem jeżeli liczba odbiorców przekroczy wartość $MAX_Recipients

 

#save all emails as reports
$Report | Export-Csv $Out_Rep_file
$Report_SMTP | Export-Csv $Out_Rep_SMTP_file
#save grouped emailes to files
$Rep_sum | Export-Csv $Out_Rep_sum_file
$Rep_SMTP_sum |Export-Csv $Out_Rep_SMTP_sum_file
#create report for email alert where recipients_count greater than $MAX_Recipients
$E_body = $Rep_sum | ? {$_.Recipients_count -gt $MAX_Recipients} | sort Recipients_count -Descending
$E_body_smtp = $Rep_smtp_sum | ? {$_.Recipients_count -gt $MAX_Recipients} | sort Recipients_count -Descending

 

i na koniec wygenerowanie pliku raportu przesyłanego emailem zawierającego wpisy z emailami gdzie liczba odbiorców przekroczy $MAX_Recipients

 

#Create HTML report to send by email
Function writeHtmlHeader 
{ 
 param($fileName) 
 Add-Content $fileName "<html>" 
 Add-Content $fileName "<head>" 
 Add-Content $fileName "<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>" 
 Add-Content $fileName '<title>Outgoing emails Report</title>' 
 Add-Content $fileName '<STYLE TYPE="text/css">' 
 Add-Content $fileName "<!--" 
 Add-Content $fileName "td {" 
 Add-Content $fileName "font-family: Tahoma;" 
 Add-Content $fileName "font-size: 13px;" 
 Add-Content $fileName "border-top: 1px solid #999999;" 
 Add-Content $fileName "border-right: 1px solid #999999;" 
 Add-Content $fileName "border-bottom: 1px solid #999999;" 
 Add-Content $fileName "border-left: 1px solid #999999;" 
 Add-Content $fileName "padding-top: 0px;" 
 Add-Content $fileName "padding-right: 0px;" 
 Add-Content $fileName "padding-bottom: 0px;" 
 Add-Content $fileName "padding-left: 0px;" 
 Add-Content $fileName "}" 
 Add-Content $fileName "body {" 
 Add-Content $fileName "margin-left: 5px;" 
 Add-Content $fileName "margin-top: 5px;" 
 Add-Content $fileName "margin-right: 0px;" 
 Add-Content $fileName "margin-bottom: 10px;" 
 Add-Content $fileName "" 
 Add-Content $fileName "table {" 
 Add-Content $fileName "border: thin solid #000000;" 
 Add-Content $fileName "}" 
 Add-Content $fileName "-->" 
 Add-Content $fileName "</style>" 
 Add-Content $fileName "</head>" 
 Add-Content $fileName "<body>" 
 Add-Content $fileName "<table width='100%'>" 
 Add-Content $fileName "<tr bgcolor='#CCCCCC'>" 
 Add-Content $fileName "<td height='25' align='center'>" 
 Add-Content $fileName "<font face='tahoma' color='#003399' size='4'><strong>Raport wyslanych emaili - $data</strong></font>" 
 Add-Content $fileName "</td>" 
 Add-Content $fileName "</tr>" 
 Add-Content $fileName "</table><BR>" 
 Add-Content $fileName "<table width='100%'>" 
}
Function writeHtmlFooter 
{ 
 param($fileName) 
 Add-Content $fileName "</table>" 
 Add-Content $fileName "</body>" 
 Add-Content $fileName "</html>" 
}
Function sendEmail 
{ param($from,$to,$subject,$smtphost,$htmlFileName) 
 $body = Get-Content $htmlFileName 
 $smtp= New-Object System.Net.Mail.SmtpClient $smtphost 
 $msg = New-Object System.Net.Mail.MailMessage $from, $to, $subject, $body 
 $msg.cc.Add("secondadmin@domain.com")
 $Attachment = New-Object Net.Mail.Attachment($htmlFileName)
 $msg.Attachments.Add($Attachment)
 $msg.isBodyhtml = $true 
 $smtp.send($msg) 
}
if ($E_body_smtp -or $E_body){
 writehtmlheader $Email_HTML_File 
 if($E_body){
 Add-Content $Email_HTML_File "<tr><td align='left' colspan=4> <BR></td></tr>" 
 Add-Content $Email_HTML_File "<tr bgcolor=#CCCCCC><td width='10%' align='center' colspan=4><font face='tahoma' size='3'><strong>Outgoing Emails</strong></td></tr>" 
 Add-Content $Email_HTML_File "<tr><td width='10%' align='center' size='2'><strong>Recipients_count</strong></td><td width='50%' align='center' size='2'><strong>Subject</strong></td><td width='30%' align='center' size='2'><strong>Sender</strong></td><td width='10%' align='center' size='2'><strong>Emails</strong></td></tr>" 
 foreach ($e in $E_body){
 Add-Content $Email_HTML_File "<tr><td align='center'>$($e.Recipients_count)</td><td align='center'> $($e.subject)</td><td align='center'>$($e.sender)</td><td align='center'>$($e.Emails)</td></tr>" 
 } 
 }
 if($E_body_smtp){
 Add-Content $Email_HTML_File "<tr><td align='left' colspan=4> <BR></td></tr>" 
 Add-Content $Email_HTML_File "<tr bgcolor=#CCCCCC><td width='10%' align='center' colspan=4><font face='tahoma' size='3'><strong>SMTP Outgoing Emails</strong></td></tr>" 
 Add-Content $Email_HTML_File "<tr><td width='10%' align='center' size='2'><strong>Recipients_count</strong></td><td width='50%' align='center' size='2'><strong>Subject</strong></td><td width='30%' align='center' size='2'><strong>Sender</strong></td><td width='10%' align='center' size='2'><strong>Emails</strong></td></tr>" 
 foreach ($e in $E_body_smtp){
 Add-Content $Email_HTML_File "<tr><td align='center'>$($e.Recipients_count)</td><td align='center'> $($e.subject)</td><td align='center'>$($e.sender)</td><td align='center'>$($e.Emails)</td></tr>" 
 } 
 }
writehtmlfooter $Email_HTML_File
 sendEmail $mail_from $mail_to $mail_subject $mail_smtp_host $Email_HTML_File 
}

 

Wynikiem działania skryptu jest powstanie czterech plików .csv:

  • msg_stat_out_$data.csv – wszystkie wyszukane widomości dla zapytania eventid = Receive i source = StoreDriver
  • msg_stat_smtp_out_$data.csv – wszystkie wyszukane widomości dla zapytania eventid = SMTP i source = StoreDriver
  • msg_stat_out_sum_$data – widomości dla zapytania eventid = Receive i source = StoreDriver pogrupowane po nadawcy i temacie
  • msg_stat_smtp_out_sum_$data.csv – widomości dla zapytania eventid = SMTP i source = StoreDriver pogrupowane po nadawcy i temacie

 

Dodatkowo w przypadku gdy dla któregokolwiek nadawcy pogrupowane wiadomości będą miały więcej niż 100 odbiorców, zostanie utworzony dodatkowy plik $Report_outgoing_emails_$data.htm który zostanie wysłany emailem.

 

Cały skrypt możecie pobrać tutaj:

emails_sent_outside.zip

 

 

Print Friendly
Otagowany , , , , , .Dodaj do zakładek permalink.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

Możesz użyć następujących tagów oraz atrybutów HTML-a: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>