Site icon Gioxx.org

PowerShell: analisi del traffico di posta (Office 365)

PowerShell Logo Gioxx.org

Tutto comincia da un Get-MailTrafficTopReport, per ottenere un più preciso dettaglio riguardo il traffico di maggiore impatto su Exchange Online. Trovate il documento che meglio spiega di cosa si tratta all’indirizzo technet.microsoft.com/en-us/library/jj200708%28v=exchg.160%29.aspx?f=255&MSPPError=-2147217396.

Lo scopo del gioco (e del perché ho messo mano all’argomento) è quello di portare a casa chi, tra tutti gli utenti registrati sul proprio tenant, genera un maggiore traffico Inbound / Outbound, per cercare di capire se quel traffico è lecito o dovuto a un utilizzo improprio del mezzo messo a disposizione, nel 99% dei casi imputabile al fatto di non conoscere soluzioni alternative per gestire -ad esempio- una newsletter. A tal proposito, uno script di Alan Byrne svolge già un buon lavoro che permette di ottenere risultati a video (e anche in CSV), è disponibile gratuitamente all’indirizzo gallery.technet.microsoft.com/scriptcenter/Office-365-Mail-Traffic-afa37da1.

Il mio unico ritocco ha riguardato un leggero cambio di rotta sullo scope analizzato tramite PowerShell. In pratica ho richiesto allo script di prendere in considerazione solo alcuni dei domini gestiti dal tenant, escludendone altri che sono certo non vadano a generare alto traffico in ricezione e invio. Questo il blocco di cui vi sto parlando:

$Domains = @()
$Domains += "domain1.tld"
$Domains += "domain2.tld"
$Domains += "domain3.tld"
$VerificaMailbox = {
  $test = $false
  foreach ($d in $Domains) { if ($_.PrimarySmtpAddress -like "*@$($d)") { $test = $true } }
  $test
}
# FILTRO I DOMINI
$Recipients = Get-Mailbox -ResultSize Unlimited | Where-Object $VerificaMailbox | select PrimarySMTPAddress
# NON FILTRO I DOMINI
#$Recipients = Get-Recipient * -ResultSize Unlimited | select PrimarySMTPAddress

Che va quindi a incastrarsi nella prima parte dello script. Sarà poi mia cura scegliere come popolare la variabile $Recipients utilizzata da Alan nel resto delle istruzioni del PS1, scegliendo se includere tutto (Get-Recipient * -ResultSize Unlimited ...) o esclusivamente i domini specificati nel mio array (Get-Mailbox -ResultSize Unlimited | Where-Object $VerificaMailbox ...), che può sempre crescere o rimpicciolirsi secondo vostre specifiche esigenze.

Il risultato completo sarà quindi:

$OutputFile = "DetailedMessageStats.csv" 
Write-Host "Collecting Recipients..." 
#Collect all recipients from Office 365
        $Domains = @()
        $Domains += "domain1.tld"
        $Domains += "domain2.tld"
        $Domains += "domain3.tld"
        $VerificaMailbox = {
            $test = $false
            foreach ($d in $Domains) { if ($_.PrimarySmtpAddress -like "*@$($d)") { $test = $true } }
            $test
        }
        # FILTRO I DOMINI
        #$Recipients = Get-Mailbox -ResultSize Unlimited | Where-Object $VerificaMailbox | select PrimarySMTPAddress
        # NON FILTRO I DOMINI
        $Recipients = Get-Recipient * -ResultSize Unlimited | select PrimarySMTPAddress
$MailTraffic = @{} 
foreach($Recipient in $Recipients) 
{ 
    $MailTraffic[$Recipient.PrimarySMTPAddress.ToLower()] = @{} 
} 
$Recipients = $null
#Collect Message Tracking Logs (These are broken into "pages" in Office 365 so we need to collect them all with a loop) 
$Messages = $null 
$Page = 1 
do 
{ 
    Write-Host "Collecting Message Tracking - Page $Page..." 
    $CurrMessages = Get-MessageTrace -PageSize 5000 -Page $Page | Select Received,SenderAddress,RecipientAddress,Size
    $Page++ 
    $Messages += $CurrMessages 
} 
until ($CurrMessages -eq $null) 
Write-Host "Crunching Results..." 
#Read each message tracking entry and add it to a hash table 
foreach($Message in $Messages) 
{ 
    if ($Message.SenderAddress -ne $null) 
    { 
        if ($MailTraffic.ContainsKey($Message.SenderAddress)) 
        { 
            $MessageDate = Get-Date -Date $Message.Received -Format yyyy-MM-dd 
             
            if ($MailTraffic[$Message.SenderAddress].ContainsKey($MessageDate)) 
            { 
                $MailTraffic[$Message.SenderAddress][$MessageDate]['Outbound']++ 
                $MailTraffic[$Message.SenderAddress][$MessageDate]['OutboundSize'] += $Message.Size
            } 
            else 
            { 
                $MailTraffic[$Message.SenderAddress][$MessageDate] = @{} 
                $MailTraffic[$Message.SenderAddress][$MessageDate]['Outbound'] = 1 
                $MailTraffic[$Message.SenderAddress][$MessageDate]['Inbound'] = 0 
                $MailTraffic[$Message.SenderAddress][$MessageDate]['InboundSize'] = 0
                $MailTraffic[$Message.SenderAddress][$MessageDate]['OutboundSize'] += $Message.Size
            }
        } 
    }
    if ($Message.RecipientAddress -ne $null) 
    { 
        if ($MailTraffic.ContainsKey($Message.RecipientAddress)) 
        { 
            $MessageDate = Get-Date -Date $Message.Received -Format yyyy-MM-dd 
             
            if ($MailTraffic[$Message.RecipientAddress].ContainsKey($MessageDate)) 
            { 
                $MailTraffic[$Message.RecipientAddress][$MessageDate]['Inbound']++ 
                $MailTraffic[$Message.RecipientAddress][$MessageDate]['InboundSize'] += $Message.Size
            } 
            else 
            { 
                $MailTraffic[$Message.RecipientAddress][$MessageDate] = @{} 
                $MailTraffic[$Message.RecipientAddress][$MessageDate]['Inbound'] = 1 
                $MailTraffic[$Message.RecipientAddress][$MessageDate]['Outbound'] = 0 
                $MailTraffic[$Message.RecipientAddress][$MessageDate]['OutboundSize'] = 0
                $MailTraffic[$Message.RecipientAddress][$MessageDate]['InboundSize'] += $Message.Size
            } 
        }     
    } 
} 
Write-Host "Formatting Results..." 
#Build a table to format the results 
$table = New-Object system.Data.DataTable "DetailedMessageStats" 
$col1 = New-Object system.Data.DataColumn Date,([datetime]) 
$table.columns.add($col1) 
$col2 = New-Object system.Data.DataColumn Recipient,([string]) 
$table.columns.add($col2) 
$col3 = New-Object system.Data.DataColumn Inbound,([int]) 
$table.columns.add($col3) 
$col4 = New-Object system.Data.DataColumn Outbound,([int]) 
$table.columns.add($col4)
$col5 = New-Object system.Data.DataColumn InboundSize,([int]) 
$table.columns.add($col5) 
$col6 = New-Object system.Data.DataColumn OutboundSize,([int]) 
$table.columns.add($col6)
#Transpose hashtable to datatable 
ForEach ($Recipient in $MailTraffic.keys) 
{ 
    $RecipientName = $Recipient
    foreach($Date in $MailTraffic[$RecipientName].keys) 
    { 
        $row = $table.NewRow() 
        $row.Date = $Date 
        $row.Recipient = $RecipientName 
        $row.Inbound = $MailTraffic[$RecipientName][$Date].Inbound 
        $row.Outbound = $MailTraffic[$RecipientName][$Date].Outbound 
        $row.InboundSize = $MailTraffic[$RecipientName][$Date].InboundSize
        $row.OutboundSize = $MailTraffic[$RecipientName][$Date].OutboundSize
        $table.Rows.Add($row)     
    }
}
#Export data to CSV and Screen 
$table | sort Date,Recipient,Inbound,Outbound, InboundSize, OutboundSize | Out-GridView -Title "Messages Sent By User"
$table | sort Date,Recipient,Inbound,Outbound, InboundSize, OutboundSize | export-csv $OutputFile 
Write-Host "Results saved to $OutputFile"
Invoke-Item $OutputFile

Una volta tanto non ho caricato lo script su Github perché vi basterà integrare il mio blocco all’ottimo lavoro già svolto da Alan. Una volta lanciato il PS1 tramite PowerShell, questo impiegherà molto tempo (tutto si basa sulla quantità di dati da analizzare) e presenterà un risultato a video (immediatamente consultabile e ordinabile in tabella) e un file CSV che verrà creato all’interno della directory dove si trova lo script. Sarà proprio questo il file (CSV) a poter essere plasmato in Excel secondo vostre specifiche, così da poter essere presentato a un responsabile o utilizzato per altri scopi, anche a livelli meramente statistici.

Cheers.

Correzioni, suggerimenti? Lascia un commento nell'apposita area qui di seguito o contattami privatamente.
Ti è piaciuto l'articolo? Offrimi un caffè! ☕ :-)

L'articolo potrebbe non essere aggiornato

Questo post è stato scritto più di 5 mesi fa, potrebbe non essere aggiornato. Per qualsiasi dubbio ti invito a lasciare un commento per chiedere ulteriori informazioni! :-)

Condividi l'articolo con i tuoi contatti:
Exit mobile version