In 365, you can use Compliance Searches to search and/or remove emails across all of your user’s mailboxes. Compliance searches have replaced the Search-Mailbox cmdlet, which has been deprecated as of April 2020.
Pre-Requisites
You must be a member of the Discovery Management role group or be assigned the Compliance Search management role. Here’s how you can add a user to the Discovery Management group and confirm membership
#Connect to Security and Compliance Center $UserCredential = Get-Credential $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.compliance.protection.outlook.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection Import-PSSession $Session -DisableNameChecking #Add User to Discovery Management Group (Replace John Doe with your user) Add-RoleGroupMember -Identity "Discovery Management" -Member "John Doe" #Confirm Membership Get-RoleGroupMember -Identity "Discovery Management" #Disconnect Session Remove-PSSession $Session
Function to Search & Remove Spam/Phishing Emails From All Mailboxes
Modify the Search Variables below to suite your needs
Function RemoveMaliciousEmails()
{
#MODIFY THE BELOW VARIABLES - YOU MUST USE THEM ALL AND OPTIONALLY LEAVE SUBJECT BLANK!!!
$compSearchName = "MaliciousEmail_$(Get-Date -Format "MMddyyyy_HHmm")"
$compStartDate = "2020-02-24" #YYYY-MM-DD
$compEndDate = "2020-02-25" #Must be different than Start Date, if searching "today" make this date tomorrow
$compFrom = "hacker@phishing.com" #You can use just the domain for a wildcard sender BUT USE WITH CAUTION
$compSubject = "Phishing Test" #Use backtick ` to escape special characters in the subject such as a quote ex: Dave shared `"New File`" with you
#
#DO NOT MODIFY ANYTHING BELOW HERE
$UserCredential = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.compliance.protection.outlook.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
Import-PSSession $Session -DisableNameChecking
Write-Host "NAME: $($compSearchName)"
Write-Host "START: $($compStartDate)"
Write-Host "END: $($compEndDate)"
Write-Host "FROM: $($compFrom)"
Write-Host "SUBJECT: $($compSubject)"
If ($compSubject.Trim() -eq "")
{
$ncs = New-ComplianceSearch -Name $compSearchName -ExchangeLocation all -ContentMatchQuery "(c:c)(received=$compStartDate..$compEndDate)(from=$compFrom)"
}
Else
{
$ncs = New-ComplianceSearch -Name $compSearchName -ExchangeLocation all -ContentMatchQuery "(c:c)(received=$compStartDate..$compEndDate)(from=$compFrom)(subject=`"$compSubject`")"
}
Write-Host "[$(Get-Date -Format G)] Start Compliance Search: $($compSearchName)"
Write-Host -NoNewLine "[$(Get-Date -Format G)] Searching"
Start-ComplianceSearch -Identity $compSearchName
$resultSearch = Get-ComplianceSearch -Identity $compSearchName
While ($resultSearch.Status -ne "Completed")
{
$resultSearch = Get-ComplianceSearch -Identity $compSearchName
Write-Host -NoNewLine "."
Start-Sleep -s 5
}
If (($resultSearch.Items -le 0) -OR ([string]::IsNullOrWhiteSpace($resultSearch.SuccessResults)))
{
Write-Host "`n[$(Get-Date -Format G)] Search completed with 0 successful results, Invalid Search Quitting!" -ForegroundColor Red
Remove-PSSession $Session
Return
}
Elseif ($resultSearch.Items -ge 500)
{
Write-Host "`n[$(Get-Date -Format G)] Search Completed with $($resultSearch.Items) successful results, you will need to run mulitple times!" -ForegroundColor Yellow
}
Else
{
Write-Host "`n[$(Get-Date -Format G)] Search Completed with $($resultSearch.Items) successful results"
}
Write-Host "[$(Get-Date -Format G)] Create Preview and Export of Results"
Write-Host -NoNewLine "[$(Get-Date -Format G)] Processing"
$ncsa = New-ComplianceSearchAction -SearchName $compSearchName -Preview
$resultPreview = Get-ComplianceSearchAction -Identity "$($compSearchName)_Preview"
$ncsa = New-ComplianceSearchAction -SearchName $compSearchName -Export -ExchangeArchiveFormat SinglePst -Format FxStream
$resultExport = Get-ComplianceSearchAction -Identity "$($compSearchName)_Export"
While ($resultPreview.Status -ne "Completed" -AND $resultExport.Status -ne "Completed")
{
$resultPreview = Get-ComplianceSearchAction -Identity "$($compSearchName)_Preview"
$resultExport = Get-ComplianceSearchAction -Identity "$($compSearchName)_Export"
#Write-Host "[$(Get-Date -Format G)] Processing..."
Write-Host -NoNewLine "."
Start-Sleep -s 5
}
Write-Host "`n[$(Get-Date -Format G)] Preview and Export successfully created"
Write-Host "[$(Get-Date -Format G)] View Results at https://protection.office.com/"
Write-Host "[$(Get-Date -Format G)] Preview: Search -> Content Search -> Searches tab -> $($compSearchName)"
Write-Host "[$(Get-Date -Format G)] Export: Search -> Content Search -> Exports tab -> $($compSearchName)_Export"
Write-Host "[$(Get-Date -Format G)] Start Purging emails"
Write-Host -NoNewLine "[$(Get-Date -Format G)] Purging"
$ncsa = New-ComplianceSearchAction -SearchName $compSearchName -Purge -PurgeType HardDelete -Confirm:$False
$resultPurge = Get-ComplianceSearchAction -Identity "$($compSearchName)_Purge"
While ($resultPurge.Status -ne "Completed")
{
$resultPurge = Get-ComplianceSearchAction -Identity "$($compSearchName)_Purge"
Write-Host -NoNewLine "."
Start-Sleep -s 5
}
Write-Host "`n[$(Get-Date -Format G)] Purge complete"
$confirmDelete = Read-Host "Delete Compliance Search, Preview, Export, and Purge? [Y/N]"
If ($confirmDelete -eq 'Y')
{
Write-Host "[$(Get-Date -Format G)] Deleting Compliance Search, Preview, Export, and Purge..."
Remove-ComplianceSearchAction -Identity "$($compSearchName)_Preview" -Confirm:$False
Remove-ComplianceSearchAction -Identity "$($compSearchName)_Export" -Confirm:$False
Remove-ComplianceSearchAction -Identity "$($compSearchName)_Purge" -Confirm:$False
Remove-ComplianceSearch -Identity $compSearchName -Confirm:$False
}
Write-Host "[$(Get-Date -Format G)] Removing Powershell Session..."
Remove-PSSession $Session
}
RemoveMaliciousEmails