Icewolf.EXO.SpamAnalyze.psm1
############################################################################## # Invoke-SpamAnalyze.ps1 # Get SPAM Detail Info for Specific MessageTraceID in MessageTrace # V2.0 04.05.2021 - Andres Bohren / Initial Version # #$MT = Get-MessageTrace -StartDate (get-date).AddDays(-10) -EndDate (get-date) -SenderAddress andres.bohren@gmail.com #$MT | Format-Table Received, SenderAddress, RecipientAddress, Subject, Status, MessageTraceID #NoSpam #$MTD = Get-MessageTraceDetail -MessageTraceId 5d40e9c4-c0e9-4c31-e94c-08d90a15b65c -RecipientAddress a.bohren@icewolf.ch -StartDate (get-date).AddDays(-10) -EndDate (get-date) #Quarantine #$MTD = Get-MessageTraceDetail -MessageTraceId 5b018c12-df4a-4300-df60-08d90bca587d -RecipientAddress a.bohren@icewolf.ch -StartDate (get-date).AddDays(-10) -EndDate (get-date) #$MTD #$Spam = $MTD | where {$_.Event -eq "Spam"} #[xml]$xmlS = $Spam.Data #$xmls.root.MEP | fl #[xml]$xml1 = $MTD[0].data #$xml1.root.MEP | fl #[xml]$xml3 = $MTD[3].data #$xml3.root.MEP | fl #[xml]$xml4 = $MTD[4].data #$xml4.root.MEP | fl ############################################################################## #Requires -Modules ExchangeOnlineManagement Function Invoke-SpamAnalyze { <# .SYNOPSIS .DESCRIPTION Get SPAM Detail Info for Specific MessageTraceID in MessageTrace .PARAMETER Recipientaddress The mailbox on whicht the permission will be set .PARAMETER SenderAddress The mailbox on whicht the permission will be set .EXAMPLE .\SpamAnalyze.ps1 -SenderAddress SenderAddress@domain.tld -RecipientAddress RecipientAddress@domain.tld .LINK #> Param( [parameter(Mandatory=$false)][String]$RecipientAddress = $null, [parameter(Mandatory=$false)][String]$SenderAddress = $null ) Begin { ############################################################################## # Connect to Exchange Online ############################################################################## Function Connect-EXO { If ($Null -eq (Get-PsSession | Where-Object {$_.ComputerName -eq "outlook.office365.com"})) { Write-Host "Connect to Exchange Online..." -f Gray Connect-ExchangeOnline -ShowBanner:$false If ($Null -eq (Get-PsSession | Where-Object {$_.ComputerName -like "*compliance.protection.outlook.com"})) { Write-Host "Connect to Security and Compliance..." -f Gray Connect-IPPSSession -WarningAction Silentlycontinue } else { Write-Host "Connection to Security and Compliance already exists" -ForegroundColor Green } } Else { Write-Host "Connection to Exchange Online already exists" -ForegroundColor Green If ($Null -eq (Get-PsSession | Where-Object {$_.ComputerName -like "*compliance.protection.outlook.com"})) { Write-Host "Connect to Security and Compliance..." -f Gray Connect-IPPSSession -WarningAction Silentlycontinue } else { Write-Host "Connection to Security and Compliance already exists" -ForegroundColor Green } } } ############################################################################## # Disconnect from Exchange Online ############################################################################## Function Disconnect-EXO { Write-Host "Disconnect from Exchange Online" -f Gray #fWrite-Log -fLogtext "Disconnect from Exchange Online" Get-PSSession | Where-Object {($_.ComputerName -eq "outlook.office365.com") -AND ($_.ConfigurationName -eq "Microsoft.Exchange")} | Remove-PSSession Get-PSSession | Where-Object {($_.ComputerName -like "compliance.protection.outlook.com") -AND ($_.ConfigurationName -eq "Microsoft.Exchange")} | Remove-PSSession } ############################################################################## # Check MessageTraceDetail ############################################################################## Function Get-SPAMinfo { Param( [parameter(Mandatory=$false)][String]$RecipientAddress, [parameter(Mandatory=$false)][String]$SenderAddress, [parameter(Mandatory=$true)][String]$MessageTraceId ) $Start = (Get-Date).AddDays(-10) $End = (Get-Date) Write-Host "Message events:" -ForegroundColor Magenta $MTDetail = Get-MessageTraceDetail -MessageTraceId $MessageTraceId -RecipientAddress $RecipientAddress -SenderAddress $SenderAddress -StartDate $Start -EndDate $End | Sort-Object Date $MTEventFail = $MTDetail | Where-Object {$_.event -eq "Failed"} If ($Null -ne $MTEventFail) { Write-Host "Failed-Event: " -ForegroundColor Magenta Write-Host (" Action: " +$MTEventFail.action ) Write-Host } $MTEventMal = $MTDetail | Where-Object {$_.event -eq "Malware"} If ($Null -ne $MTEventMal) { Write-Host "Malware-Event: " -ForegroundColor Magenta Write-Host (" Action: " +$MTEventMal.action ) Write-Host } $MTEventSPM = $MTDetail | Where-Object {$_.event -eq "Spam"} | Select-Object -uniq # SPAM Detail If ($Null -ne $MTEventSPM) { Write-Host "SPAM-Event: " -ForegroundColor Magenta Write-Host (" Action: " +$MTEventSPM.action ) Write-Host Write-Host "SPAM-Event Details:" -ForegroundColor Magenta Write-Host "Anti-spam message headers: https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/anti-spam-message-headers" -f Cyan Write-Host "Spam confidence levels: https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/spam-confidence-levels" -f Cyan [xml]$xmlS = $MTEventSPM.Data $RcptCount = ($xmlS.root.MEP | Where-Object {$_.Name -eq "RcptCount"}) $DI = ($xmlS.root.MEP | Where-Object {$_.Name -eq "DI"}) $SCL = ($xmlS.root.MEP | Where-Object {$_.Name -eq "SCL"}) $Score = ($xmlS.root.MEP | Where-Object {$_.Name -eq "Score"}) $SFV = ($xmlS.root.MEP | Where-Object {$_.Name -eq "SFV"}) $ClientIP = ($xmlS.root.MEP | Where-Object {$_.Name -eq "CIP"}) $Country = ($xmlS.root.MEP | Where-Object {$_.Name -eq "Ctry"}) $HeloString = ($xmlS.root.MEP | Where-Object {$_.Name -eq "H"}) $ReturnPath = ($xmlS.root.MEP | Where-Object {$_.Name -eq "ReturnPath"}) $Language = ($xmlS.root.MEP | Where-Object {$_.Name -eq "Language"}) Write-Host (" RecipientCount: " +$RcptCount.Integer) switch ($DI.String) { "SB" { $DI = "(SB) The sender of the message was blocked" } "SQ" { $DI = "(SQ) The message was quarantined" } "SD" { $DI = "(SD) The message was deleted" } "SJ" { $DI = "(SJ) The message was sent to the recipient's Junk Email folder" } "SN" { $DI = "(SN) The message was routed through the higher risk delivery pool" } "SO" { $DI = "(SO) The message was routed through the normal outbound delivery pool" } } Write-Host (" DI: " +$DI) # Color for SCL switch ($SCL.Integer) { -1 { $cSCL = "Green"; $Folder = "Inbox" } 0 { $cSCL = "Green"; $Folder = "Inbox" } 1 { $cSCL = "Green"; $Folder = "Inbox" } 2 { $cSCL = "Green"; $Folder = "Inbox" } 3 { $cSCL = "Green"; $Folder = "Inbox" } 4 { $cSCL = "Green"; $Folder = "Inbox" } 5 { $cSCL = "Yellow"; $Folder = "Junk-E-Mail" } 6 { $cSCL = "Yellow"; $Folder = "Junk-E-Mail" } 7 { $cSCL = "Red"; $Folder = "Quarantaine" } 8 { $cSCL = "Red"; $Folder = "Quarantaine" } 9 { $cSCL = "Red"; $Folder = "Quarantaine" } } Write-Host (" SpamConfidenceLevel (SCL): "+$SCL.Integer +" Deliver to: " +$Folder +")") -f $cSCL Write-Host (" SpamScoreLevel (Score): "+$Score.Integer ) switch ($SFV.String) { "BLK" { $SFV = "(BLK) Filtering was skipped and the message was blocked because it originated from a blocked sender" } "NSPM" { $SFV = "(NSPM) The message was marked as non-spam and was sent to the intended recipients" } "SFE" { $SFV = "(SFE) Filtering was skipped and the message was allowed because it was sent from an address in a user's Safe Senders list"} "SKA" { $SFV = "(SKA) The message skipped spam filtering and was delivered to the Inbox because the sender was in the allowed senders list or allowed domains list in an anti-spam policy"} "SKB" { $SFV = "(SKB) The message skipped spam filtering and was delivered to the Inbox because the sender was in the allowed senders list or allowed domains list in an anti-spam policy"} "SKI" { $SFV = "(SKI) Similar to SFV:SKN, the message skipped spam filtering for another reason (for example, an intra-organizational email within a tenant)"} "SKN" { $SFV = "(SKN) The message was marked as non-spam prior to being processed by spam filtering. For example, the message was marked as SCL -1 or Bypass spam filtering by a mail flow rule"} "SKQ" { $SFV = "(SKQ) The message was released from the quarantine and was sent to the intended recipients"} "SKS" { $SFV = "(SKS) The message was marked as spam prior to being processed by the content filter" } "SPM" { $SFV = "(SPM) The message was marked as spam by spam filtering" } } Write-Host (" SpamFilterVerdikt (SFV): " +$SFV) Write-Host (" SenderClientIP (CIP): " +$ClientIP.String) Write-Host (" Country (CTRY): " +$Country.String) Write-Host (" HeloString (H): " +$HeloString.String) Write-Host (" ReturnPath: " +$ReturnPath.String) Write-Host (" Language: " +$Language.String) Write-Host } Else { Write-Host "SPAM-Event: " -ForegroundColor Magenta Write-Host (" INFO: This mail contains no 'Spam' event ") -f Cyan Write-Host } } } Process { #Call Function to Connect to Exchange Online Connect-EXO #Set Start- and Enddate for Messagetrace $Start = ((Get-Date).AddDays(-10)) $End = Get-Date #Messagetrace depending on Parameters If ($SenderAddress -ne $Null) { If ($RecipientAddress -ne $Null) { $MT = Get-MessageTrace -StartDate (get-date).AddDays(-10) -EndDate (get-date) -SenderAddress $SenderAddress -RecipientAddress $RecipientAddress } else { $MT = Get-MessageTrace -StartDate (get-date).AddDays(-10) -EndDate (get-date) -SenderAddress $SenderAddress } } else { #SenderAddress = $Null / RecipientAddress populated $MT = Get-MessageTrace -StartDate (get-date).AddDays(-10) -EndDate (get-date) -RecipientAddress $RecipientAddress } $MT | Format-Table Received, SenderAddress, RecipientAddress, Subject, Status, MessageTraceID #Input MessageTraceID $readhost = Read-Host "MessageTraceID?" If ($readhost -eq "") { Write-Host "Not a MessageTraceID... Stopping Script" } else { Write-Host "DEBUG: Readhost: $readhost" Foreach ($Line in $MT) { If ($readhost -eq $Line.MessageTraceId) { #Write-Host "DEBUG: MessageTraceID: $($Line.MessageTraceId)" #Write-Host "DEBUG: Sender: $($Line.Senderaddress)" #Write-Host "DEBUG: Recipient: $($Line.RecipientAddress)" $MessageTraceId = $Line.MessageTraceId $MTSenderAddress = $Line.Senderaddress $MTRecipientAddress = $Line.RecipientAddress $MTStatus = $Line.Status $MTSubject = $Line.Subject $MTReceived = $Line.Received $MTMessageID = $Line.MessageID #Infos from Message Trace Write-Host Write-Host "E-Mail Detail:" -ForegroundColor Magenta Write-Host " Message ID: $MTMessageID" Write-Host " Received: $MTReceived" Write-Host " Sender: $MTSenderAddress" Write-Host " Recipient: $MTRecipientAddress" Write-Host " Subject: $MTSubject" Write-Host " Status: $MTStatus" Write-Host #Check Recipient $ExoRecipient = Get-Recipient -Identity $MTRecipientAddress #$ExoRecipient $RecipientTypeDetails = $ExoRecipient.RecipientTypeDetails Write-Host "Recipient Details" -ForegroundColor Magenta Write-Host " RecipientTypeDetails: $RecipientTypeDetails" Write-Host #JunkMailConfiguration of Mailbox $SenderDomain = ($SenderAddress.Split("@")[1]) If ($RecipientTypeDetails -eq "UserMailbox") { $JMC = Get-MailboxJunkEmailConfiguration -Identity $MTRecipientAddress If ($NULL -ne $JMC) { Write-Host "Recipient JunkMailConfiguration" -ForegroundColor Magenta Write-Host " TrustedListsOnly: $($JMC.TrustedListsOnly)" Write-Host " ContactsTrusted: $($JMC.ContactsTrusted)" Write-Host Write-Host "Check if $MTSenderAddress exists in $MTRecipientAddress Trusted-/BlockedSenders list: " -ForegroundColor Magenta If ($JMC.TrustedSendersAndDomains -contains $MTSenderAddress) { Write-Host " USER Junk-E-Mail Config: Found in 'TrustedSendersAndDomains'" -f Green } Else { Write-Host " USER Junk-E-Mail Config: Not found in 'TrustedSendersAndDomains'" -f White } If ($JMC.BlockedSendersAndDomains -contains $MTSenderAddress) { Write-Host " USER Junk-E-Mail Config: Found in 'BlockedSendersAndDomains'" -f Red } Else { Write-Host " USER Junk-E-Mail Config: Not found in 'BlockedSendersAndDomains'" -f White } Write-Host Write-Host "Check if $SenderDomain exists in $Recipient Trusted-/BlockedSenders list: " -ForegroundColor Magenta If ($JMC.TrustedSendersAndDomains -contains $SenderDomain) { Write-Host " USER Junk-E-Mail Config: Found in 'TrustedSendersAndDomains'" -f Green } Else { Write-Host " USER Junk-E-Mail Config: Not found in 'TrustedSendersAndDomains'" -f White } If ($JMC.BlockedSendersAndDomains -contains $SenderDomain) { Write-Host " USER Junk-E-Mail Config: Found in 'BlockedSendersAndDomains'" -f Red } Else { Write-Host " USER Junk-E-Mail Config: Not found in 'BlockedSendersAndDomains'" -f White } Write-Host } } #GLOBALConfig Write-Host "Check if $MTSenderAddress found in GLOBAL Trusted-/BlockedSender list: " -ForegroundColor Magenta $GLOBALJunkConfig = Get-HostedContentFilterPolicy #Allowed Senders If ($GLOBALJunkConfig.AllowedSenders -match $MTSenderAddress) { Write-Host " GLOBAL EAC SpamFilter: Found in 'AllowedSenders'" -f Green } Else { Write-Host " GLOBAL EAC SpamFilter: Not found in 'AllowedSenders'" -f White } #Blocked Senders If ($GLOBALJunkConfig.BlockedSenders -match $MTSenderAddress) { Write-Host " GLOBAL EAC SpamFilter: Found in 'BlockedSenders'" -f Red } Else { Write-Host " GLOBAL EAC SpamFilter: Not found in 'BlockedSenders'" -f White } Write-Host Write-Host "Check if $SenderDomain found in GLOBAL Allowed-/BlockedSenderDomain list: " -ForegroundColor Magenta #Allowed Domains If ($GLOBALJunkConfig.AllowedSenderDomains.Domain -contains $SenderDomain) { Write-Host " GLOBAL EAC SpamFilter: Found in 'AllowedSenderDomains'" -f Green } Else { Write-Host " GLOBAL EAC SpamFilter: Not found in 'AllowedSenderDomains'" -f White } #Allowed Senders If ($GLOBALJunkConfig.BlockedSenderDomains.Domain -contains $SenderDomain) { Write-Host " GLOBAL EAC SpamFilter: Found in 'BlockedSenderDomains'" -f Red } Else { Write-Host " GLOBAL EAC SpamFilter: Not found in 'BlockedSenderDomains'" -f White } Write-Host Get-SPAMinfo -RecipientAddress $MTRecipientAddress -SenderAddress $MTSenderAddress -MessageTraceId $MessageTraceId #DNS Records Write-Host "DNS Records of $SenderDomain" -ForegroundColor Magenta #NS Write-Host "NS" -ForegroundColor Magenta $json = Invoke-RestMethod -URI "https://cloudflare-dns.com/dns-query?ct=application/dns-json&name=$SenderDomain&type=NS" [string]$NS = $json.Answer.data $NS #MX Write-Host "MX" -ForegroundColor Magenta $json = Invoke-RestMethod -URI "https://cloudflare-dns.com/dns-query?ct=application/dns-json&name=$SenderDomain&type=MX" [string]$MX = $json.Answer.data $MX #SPF Write-Host "SPF" -ForegroundColor Magenta $json = Invoke-RestMethod -URI "https://cloudflare-dns.com/dns-query?ct=application/dns-json&name=$SenderDomain&type=TXT" $TXT = $json.Answer.data $TXT = $TXT | where {$_ -match "v=spf1"} $SPF = $TXT $SPF #DKIM Write-Host "DKIM" -ForegroundColor Magenta $json = Invoke-RestMethod -URI "https://cloudflare-dns.com/dns-query?ct=application/dns-json&name=Selector1._domainkey.$SenderDomain&type=CNAME" $DKIM1 = $json.Answer.data $json = Invoke-RestMethod -URI "https://cloudflare-dns.com/dns-query?ct=application/dns-json&name=Selector2._domainkey.$SenderDomain&type=CNAME" $DKIM2 = $json.Answer.data [string]$DKIM = "$DKIM1 $DKIM2" $DKIM #DMARC Write-Host "DMARC" -ForegroundColor Magenta $json = Invoke-RestMethod -URI "https://cloudflare-dns.com/dns-query?ct=application/dns-json&name=_dmarc.$SenderDomain&type=TXT" $DMARC = $json.Answer.data $DMARC } } } break Get-SPAMinfo -RecipientAddress $RecipientAddress -SenderAddress $SenderAddress -MessageTraceId $MessageTraceId } End { #Disconnect from Exchange Online and #Disconnect-EXO } } |