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 = "[email protected]" #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