Create Bulk Office 365 Compliance Searches with PowerShell
Recently I wanted to find a way to get PowerShell to create compliance searches that followed keyword queries and search conditions. This means I could have multiple values in one search query. For example, “TO brad wyatt AND FROM [email protected]”. This query would search for e-mails sent to Brad which only from [email protected]. To get PowerShell to do this I decided to create a Hash Table that would have the queries listed in the table.
After it would create each compliance search it would then wait for the search to gather all of the results and then export the amount of items it found to a csv file. Each Compliance Search would append its results to the same file so in the end I would have a CSV file containing all of the Compliance Searches and the objects it found for each one.
To keep from having the Compliance Search having names with invalid characters I made it so the name of the Compliance Search would start with “Case 1” and increment by 1 for each new search.
The results CSV will show you the case name, the query and the total amount of items that were found that matched the query.
With each Compliance Search I set the following parameters to True: AllowNotFoundExchangeLocationsEnabled and I set the following parameters to All: ExchangeLocation
The AllowNotFoundExchangeLocationsEnabled parameter specifies whether to allow inactive mailboxes in the compliance search. An inactive mailbox is a mailbox that’s placed on Litigation Hold or In-Place Hold before it’s soft-deleted. Valid values are:
$true
The search doesn’t try to validate the existence of the mailbox before proceeding. This value is required if you want to include inactive mailboxes in the search, because inactive mailboxes don’t resolve as regular mailboxes.$false
The search tries to validate the existence of the mailbox before proceeding. If you specify an inactive mailbox or a mailbox that otherwise can’t be found, the search will fail. This is the default value.
The ExchangeLocation parameter specifies the mailboxes to include. Valid values are:
- A mailbox
- A distribution group or mail-enabled security group (all mailboxes that are currently members of the group).
- The value
All
for all mailboxes. You can only use this value by itself.
Script
$ResultsCSV = "C:\ComplianceCase_Results.csv" $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 $Terms = @("Brad Wyatt", '"Microsoft" AND "Sales"', '"Microsoft" AND "Commissions"', '"Microsoft" AND "Orders"', '"Microsoft" AND "Shipments"', '"MSFT" AND "Sales"', '"Mcdonalds" AND "resume"', '"Apple" AND "schematics"', '"Microsoft" AND "infringement"', '"Apple" AND "leaving!"', '"Reddit" AND "sample!"', "store", "Fresh sales today", "group admin", "groupadmin", '"bwyatt" AND "Sale order commission shipment" AND "Microsoft"', '"Brad Wyatt" AND "Sale order commission shipment" AND "Microsoft"', 'To: "[email protected]" AND From: "[email protected]"', 'To: "[email protected]" AND From: "HR@microsoftcom"', 'From: "[email protected]" AND To: "[email protected]"', 'From: "[email protected]" AND To: "[email protected]"', 'From: "Brad" AND To: "[email protected]"', 'From: "Admin" AND To: "[email protected]"', 'To: "John" AND From: "[email protected]"', 'Subect:"poaching brad"', "Letter of resignation", "PowerShell", ' (sent=01-01-2011..12-31-2018) AND (CC: "Brad Wyatt") ', ' (received=01-01-2011..12-31-2018) AND (From: "Brad Wyatt") ', ' (sent=01-01-2011..12-31-2018) AND (From: "Brad Wyatt") ', ' (sent=01-01-2011..12-31-2018) AND (Bcc: "Brad Wyatt") ' ) $Count = 1 Foreach ($Term in $Terms) { Write-Host "Creating case to search for $Term.." -ForegroundColor Yellow $CaseName = "Case" + $count++ Write-Host "Case Name: $CaseName" New-ComplianceSearch -Name $CaseName -ExchangeLocation All -AllowNotFoundExchangeLocationsEnabled $true -ContentMatchQuery $Term Write-Host "Starting case.. $CaseName" Start-ComplianceSearch $CaseName Start-Sleep -Seconds 5 Do { Write-Host "Waiting until $CaseName is finished running..." $Status = Get-ComplianceSearch $CaseName | Select-Object -ExpandProperty Status } Until ($Status -eq "Completed") Write-Host "Gathering item count for $CaseName..." Get-ComplianceSearch $CaseName | Select-Object Name, ContentMatchQuery, Items | Export-Csv -NoTypeInformation $ResultsCSV -Append }
My name is Bradley Wyatt; I am a 5x Microsoft Most Valuable Professional (MVP) in Microsoft Azure and Microsoft 365. I have given talks at many different conferences, user groups, and companies throughout the United States, ranging from PowerShell to DevOps Security best practices, and I am the 2022 North American Outstanding Contribution to the Microsoft Community winner.