2021-05-22 15:59:41 +05:30
<#
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
2023-10-06 18:07:00 +05:30
Name : Export Office 365 Spam , Malware and phish Report using PowerShell
Description : This script exports Office 365 spam , malware and phish report to CSV
Version : 2.0
2021-05-22 15:59:41 +05:30
Website : o365reports . com
2023-10-06 18:07:00 +05:30
Script Highlights :
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
1 . Generates 9 different email protection reports .
2 . Automatically installs the Exchange Online PowerShell module upon your confirmation when it is not available in the system .
3 . Supports both MFA and Non-MFA accounts .
4 . Specify date ranges to generate reports for custom periods .
5 . Supports filter s to retrieve sent and received spams .
6 . Allows you to filter sent and received malwares .
7 . Tracks sent and received phishing emails .
8 . Facilitates the separation of internal spam , malware , and phishing emails .
9 . Exports the report to CSV .
10 . Scheduler-friendly . You can automate the report generation upon passing credentials as parameters .
For detailed script execution : https : / / o365reports . com / 2021 / 05 / 18 / export-office - 365 -spam -and -malware -report -using -powershell
2021-05-22 15:59:41 +05:30
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
#>
2023-10-06 18:07:00 +05:30
2021-05-18 18:16:28 +05:30
param (
[ string ] $UserName = $null ,
[ string ] $Password = $null ,
[ Switch ] $SpamEmailsSent ,
[ Switch ] $SpamEmailsReceived ,
[ Switch ] $MalwareEmailsSent ,
[ Switch ] $MalwareEmailsReceived ,
2023-10-06 18:07:00 +05:30
[ Switch ] $PhishEmailsSent ,
[ Switch ] $PhishEmailsReceived ,
[ Switch ] $IntraorgSpamMails ,
[ Switch ] $IntraorgMalwareMails ,
[ Switch ] $IntraorgPhishMails ,
2021-05-18 18:16:28 +05:30
[ Nullable[DateTime] ] $StartDate ,
[ Nullable[DateTime] ] $EndDate
)
Function DateAndSwitchesValidation {
2023-10-06 18:07:00 +05:30
$global:MaxStartDate = ( ( Get-Date ) . Date ) . AddDays ( -30 )
2021-05-18 18:16:28 +05:30
if ( ( $StartDate -eq $Null ) -and ( $EndDate -eq $Null ) ) {
$StartDate = $global:MaxStartDate
$EndDate = ( Get-date ) . Date
}
elseif ( ( $StartDate -eq $null ) -or ( $EndDate -eq $null ) ) {
Write-Host " Exiting. `n Note: Both start and end date values are mandatory. Please try again. " -ForegroundColor Red
Exit
}
elseif ( $StartDate -lt $global:MaxStartDate ) {
Write-Host " Exiting. `n Note: You can retrieve data from $global:MaxStartDate onwards. Please try again. " -ForegroundColor Red
Exit
}
else {
$StartDate = [ DateTime ] $StartDate
$EndDate = [ DateTime ] $EndDate
}
2023-10-06 18:07:00 +05:30
if ( -Not ( ( $SpamEmailsSent . IsPresent ) -or ( $SpamEmailsReceived . IsPresent ) -or ( $MalwareEmailsSent . IsPresent ) -or ( $MalwareEmailsReceived . IsPresent ) -or ( $PhishEmailsSent . IsPresent ) -or ( $PhishEmailsReceived . IsPresent ) -or ( $IntraorgSpamMails . IsPresent ) -or ( $IntraorgMalwareMails . IsPresent ) -or ( $IntraorgPhishMails . IsPresent ) ) ) {
2021-05-18 18:16:28 +05:30
Write-Host " Exiting. `n Note: Choose one report to generate. Please try again " -ForegroundColor Red
Exit
}
2023-10-06 18:07:00 +05:30
GetSpamMalwarePhishData -StartDate $StartDate -EndDate $EndDate
2021-05-18 18:16:28 +05:30
}
2023-10-06 18:07:00 +05:30
Function GetSpamMalwarePhishData {
2021-05-18 18:16:28 +05:30
param (
[ DateTime ] $StartDate ,
[ DateTime ] $EndDate
)
$EndDate = Get-Date $EndDate -Hour 23 -Minute 59 -Second 59
ConnectToExchange
$global:ExportedEmails = 0
$global:Domain = " Recipient Domain "
2023-10-06 18:07:00 +05:30
$SpamEventTypes = " URL malicious reputation " , " Advanced filter " , " General filter " , " Mixed analysis detection " , " Fingerprint matching " , " Domain reputation " , " Bulk " , " IP reputation "
$PhishEventTypes = " URL malicious reputation " , " Advanced filter " , " General filter " , " Spoof intra-org " , " Spoof external domain " , " Spoof DMARC " , " Impersonation brand " , " Mixed analysis detection " , " File reputation " , " Fingerprint matching " , " URL detonation reputation " , " URL detonation " , " Impersonation user " , " Impersonation domain " , " Mailbox intelligence impersonation " , " File detonation " , " File detonation reputation " , " Campaign "
$MalwareEventTypes = " File detonation " , " File detonation reputation " , " File reputation " , " Anti-malware engine " , " URL malicious reputation " , " URL detonation " , " URL detonation reputation " , " Campaign "
2021-05-18 18:16:28 +05:30
if ( $SpamEmailsReceived . IsPresent ) {
$global:ExportCSVFileName = " .\SpamEmailsReceivedReport- " + ( ( Get-Date -format " MMM-dd hh-mm-ss tt " ) . ToString ( ) ) + " .csv "
2023-10-06 18:07:00 +05:30
Write-Host " Retrieving spam emails received from $StartDate to $EndDate ... " ` n
Get-MailDetailATPReport -StartDate $StartDate -EndDate $EndDate -Direction Inbound -PageSize 5000 -EventType $SpamEventTypes | Where-Object { $_ . VerdictSource -like " Spam " } | ForEach-Object {
2021-05-18 18:16:28 +05:30
$global:Domain = " Sender Domain "
$CurrRecord = $_
RetrieveEmailInfo
2023-10-06 18:07:00 +05:30
}
OpenOutputFile
2021-05-18 18:16:28 +05:30
}
2023-10-06 18:07:00 +05:30
if ( $MalwareEmailsReceived . IsPresent ) {
2021-05-18 18:16:28 +05:30
$global:ExportCSVFileName = " .\MalwareEmailsReceivedReport- " + ( ( Get-Date -format " MMM-dd hh-mm-ss tt " ) . ToString ( ) ) + " .csv "
2023-10-06 18:07:00 +05:30
Write-Host " Retrieving malware emails received from $StartDate to $EndDate ... " ` n
Get-MailDetailATPReport -StartDate $StartDate -EndDate $EndDate -Direction Inbound -PageSize 5000 -EventType $MalwareEventTypes | Where-Object { $_ . VerdictSource -like " Malware " } | ForEach-Object {
2021-05-18 18:16:28 +05:30
$global:Domain = " Sender Domain "
$CurrRecord = $_
RetrieveEmailInfo
2023-10-06 18:07:00 +05:30
}
OpenOutputFile
2021-05-18 18:16:28 +05:30
}
2023-10-06 18:07:00 +05:30
if ( $SpamEmailsSent . IsPresent ) {
2021-05-18 18:16:28 +05:30
$global:ExportCSVFileName = " .\SpamEmailsSentReport- " + ( ( Get-Date -format " MMM-dd hh-mm-ss tt " ) . ToString ( ) ) + " .csv "
2023-10-06 18:07:00 +05:30
Write-Host " Retrieving spam emails sent from $StartDate to $EndDate ... " ` n
Get-MailDetailATPReport -StartDate $StartDate -EndDate $EndDate -Direction Outbound -PageSize 5000 -EventType $SpamEventTypes | Where-Object { $_ . VerdictSource -like " Spam " } | ForEach-Object {
2021-05-18 18:16:28 +05:30
$CurrRecord = $_
RetrieveEmailInfo
2023-10-06 18:07:00 +05:30
}
OpenOutputFile
2021-05-18 18:16:28 +05:30
}
2023-10-06 18:07:00 +05:30
if ( $MalwareEmailsSent . IsPresent ) {
2021-05-18 18:16:28 +05:30
$global:ExportCSVFileName = " .\MalwareEmailsSentReport- " + ( ( Get-Date -format " MMM-dd hh-mm-ss tt " ) . ToString ( ) ) + " .csv "
2023-10-06 18:07:00 +05:30
Write-Host " Retrieving malware emails sent from $StartDate to $EndDate ... " ` n
Get-MailDetailATPReport -StartDate $StartDate -EndDate $EndDate -Direction Outbound -PageSize 5000 -EventType $MalwareEventTypes | Where-Object { $_ . VerdictSource -like " Malware " } | ForEach-Object {
2023-10-06 17:23:22 +05:30
$CurrRecord = $_
RetrieveEmailInfo
2023-10-06 18:07:00 +05:30
}
OpenOutputFile
}
if ( $PhishEmailsReceived . IsPresent ) {
$global:ExportCSVFileName = " .\PhishEmailsReceivedReport- " + ( ( Get-Date -format " MMM-dd hh-mm-ss tt " ) . ToString ( ) ) + " .csv "
Write-Host " Retrieving phish emails received from $StartDate to $EndDate ... " ` n
Get-MailDetailATPReport -StartDate $StartDate -EndDate $EndDate -Direction Inbound -PageSize 5000 -EventType $PhishEventTypes | Where-Object { $_ . VerdictSource -like " Phish " } | ForEach-Object {
$global:Domain = " Sender Domain "
$CurrRecord = $_
RetrieveEmailInfo
}
OpenOutputFile
}
if ( $PhishEmailsSent . IsPresent ) {
$global:ExportCSVFileName = " .\PhishEmailsSentReport- " + ( ( Get-Date -format " MMM-dd hh-mm-ss tt " ) . ToString ( ) ) + " .csv "
Write-Host " Retrieving phish emails sent from $StartDate to $EndDate ... " ` n
Get-MailDetailATPReport -StartDate $StartDate -EndDate $EndDate -Direction Outbound -PageSize 5000 -EventType $PhishEventTypes | Where-Object { $_ . VerdictSource -like " Phish " } | ForEach-Object {
$CurrRecord = $_
RetrieveEmailInfo
}
OpenOutputFile
}
if ( $IntraorgSpamMails . IsPresent ) {
$global:ExportCSVFileName = " .\IntraorgSpamMailsReport- " + ( ( Get-Date -format " MMM-dd hh-mm-ss tt " ) . ToString ( ) ) + " .csv "
Write-Host " Retrieving internal spam emails from $StartDate to $EndDate ... " ` n
Get-MailDetailATPReport -StartDate $StartDate -EndDate $EndDate -Direction IntraOrg -PageSize 5000 -EventType $SpamEventTypes | Where-Object { $_ . VerdictSource -like " Spam " } | ForEach-Object {
$CurrRecord = $_
RetrieveEmailInfo
}
OpenOutputFile
}
if ( $IntraorgMalwareMails . IsPresent ) {
$global:ExportCSVFileName = " .\IntraorgMalwareMailsReport- " + ( ( Get-Date -format " MMM-dd hh-mm-ss tt " ) . ToString ( ) ) + " .csv "
Write-Host " Retrieving internal malware emails from $StartDate to $EndDate ... " ` n
Get-MailDetailATPReport -StartDate $StartDate -EndDate $EndDate -Direction IntraOrg -PageSize 5000 -EventType $MalwareEventTypes | Where-Object { $_ . VerdictSource -like " Malware " } | ForEach-Object {
$CurrRecord = $_
RetrieveEmailInfo
}
OpenOutputFile
}
if ( $IntraorgPhishMails . IsPresent ) {
$global:ExportCSVFileName = " .\IntraorgPhishMailsReport- " + ( ( Get-Date -format " MMM-dd hh-mm-ss tt " ) . ToString ( ) ) + " .csv "
Write-Host " Retrieving internal phish emails from $StartDate to $EndDate ... " ` n
Get-MailDetailATPReport -StartDate $StartDate -EndDate $EndDate -Direction IntraOrg -PageSize 5000 -EventType $PhishEventTypes | Where-Object { $_ . VerdictSource -like " Phish " } | ForEach-Object {
$CurrRecord = $_
RetrieveEmailInfo
}
OpenOutputFile
}
2021-05-18 18:16:28 +05:30
}
Function ConnectToExchange {
$Exchange = ( get-module ExchangeOnlineManagement -ListAvailable ) . Name
if ( $Exchange -eq $null ) {
Write-host " Important: ExchangeOnline PowerShell module is unavailable. It is mandatory to have this module installed in the system to run the script successfully. "
$confirm = Read-Host Are you sure you want to install module ? [ Y] Yes [N ] No
if ( $confirm -match " [yY] " ) {
Write-host " Installing ExchangeOnlineManagement "
Install-Module ExchangeOnlineManagement -Repository PSGallery -AllowClobber -Force
Write-host " ExchangeOnline PowerShell module is installed in the machine successfully. "
}
elseif ( $confirm -cnotmatch " [yY] " ) {
Write-host " Exiting. `n Note: ExchangeOnline PowerShell module must be available in your system to run the script. "
Exit
}
}
#Storing credential in script for scheduling purpose/Passing credential as parameter
if ( ( $UserName -ne " " ) -and ( $Password -ne " " ) ) {
$SecuredPassword = ConvertTo-SecureString -AsPlainText $Password -Force
$Credential = New-Object System . Management . Automation . PSCredential $UserName , $SecuredPassword
Connect-ExchangeOnline -Credential $Credential -ShowProgress $false | Out-Null
}
else {
Connect-ExchangeOnline | Out-Null
}
2023-10-06 18:07:00 +05:30
Write-Host " ExchangeOnline PowerShell module is connected successfully " ` n
2021-05-18 18:16:28 +05:30
#End of Connecting Exchange Online
}
Function RetrieveEmailInfo {
$Date = $CurrRecord . Date . ToShortDateString ( )
$DateTime = $CurrRecord . Date
Write-Progress -Activity " Retrieving mail data for $Date "
$SenderAddress = $CurrRecord . SenderAddress
$RecipientAddress = $CurrRecord . RecipientAddress
$Subject = $CurrRecord . Subject
$EventType = $CurrRecord . EventType
if ( $CurrRecord . Direction -eq 'Inbound' ) {
$Domain = $SenderAddress . split ( " @ " ) | Select-object -Index 1
}
2023-10-06 18:07:00 +05:30
elseif ( $CurrRecord . Direction -eq 'Outbound' ) {
2021-05-18 18:16:28 +05:30
$Domain = $RecipientAddress . split ( " @ " ) | Select-object -Index 1
}
ExportResults
}
Function ExportResults {
$global:ExportedEmails = $global:ExportedEmails + 1
$ExportResult = @ { 'Date' = $DateTime ; 'Sender Address' = $SenderAddress ; 'Recipient Address' = $RecipientAddress ; 'Subject' = $Subject ; 'Event Type' = $EventType ; $global:Domain = $Domain }
$ExportResults = New-Object PSObject -Property $ExportResult
2023-10-06 18:07:00 +05:30
if ( ( $CurrRecord . Direction -eq 'Inbound' ) -or ( $CurrRecord . Direction -eq 'Outbound' ) ) {
$ExportResults | Select-Object 'Date' , 'Sender Address' , 'Recipient Address' , 'Subject' , 'Event Type' , $global:Domain | Export-csv -path $global:ExportCSVFileName -NoType -Append -Force
}
else {
$ExportResults | Select-Object 'Date' , 'Sender Address' , 'Recipient Address' , 'Subject' , 'Event Type' | Export-csv -path $global:ExportCSVFileName -NoType -Append -Force
}
}
#Open output file after execution
Function OpenOutputFile {
if ( ( Test-Path -Path $global:ExportCSVFileName ) -eq " True " ) {
Write-Host " The Output file available in: " -NoNewline -ForegroundColor Yellow ; Write-Host $global:ExportCSVFileName
Write-Host ` n " The exported report has $global:ExportedEmails email details "
$prompt = New-Object -ComObject wscript . shell
$userInput = $prompt . popup ( " Do you want to open output file? " , 0 , " Open Output File " , 4 )
If ( $userInput -eq 6 ) {
Invoke-Item " $global:ExportCSVFileName "
}
}
else {
Write-Host " No data found with the specified criteria "
}
2021-05-18 18:16:28 +05:30
}
DateAndSwitchesValidation
Disconnect-ExchangeOnline -Confirm: $false -InformationAction Ignore -ErrorAction SilentlyContinue
2023-10-06 18:07:00 +05:30
Write-Host ` n " Disconnected active ExchangeOnline session "
Write-Host ` n ~ ~ Script prepared by AdminDroid Community ~ ~ ` n -ForegroundColor Green
Write-Host " ~~ Check out " -NoNewline -ForegroundColor Green ; Write-Host " admindroid.com " -ForegroundColor Yellow -NoNewline ; Write-Host " to get access to 1800+ Microsoft 365 reports. ~~ " -ForegroundColor Green ` n ` n