I hope you can help as this is driving me wild and I think I must be the only person on planet earth wanting to do this....
I want to delete emails, from a specific folder...
Errors
"The search is completed 0 item(s) (0.00 B) 3,120 unindexed items, 3.61 GB 4 mailbox(es) 2 errors"
and
"The search on the following locations failed: [mailbox]:Transient error occurred while trying to search the mailbox. Please make sure the mailboxes you're searching still exist and then run the search again. (CS007)"
The code I am using;
Get-PSSession | Remove-PSSession
Disconnect-ExchangeOnline -Confirm:$false
cls
$user= Get-Content "user.txt"
$passplain= Get-Content "O365Pass.txt"
$pass = ConvertTo-SecureString -String $passplain -AsPlainText -Force
$cred=New-Object System.Management.Automation.PSCredential ($user, $pass)
#$user = "mysupersecretemailadminaddress"
#pass = 'my super secret super admin password'
[Security.Principal.WindowsIdentity]::GetCurrent()
write-host $user
write-host $pass
# The section below creates a remote PowerShell connection to Office 365
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12;
Function GetFolderID {
Param (
[parameter(Mandatory = $true)]
[String]
$Mailbox,
[parameter(Mandatory = $true)]
[String]
$FolderName
)
$TargetMailFolders = Get-MailboxFolderStatistics -Identity $Mailbox | Select FolderID, Name
Try {
foreach ($TargetMailFolder in $TargetMailFolders) {
$TargetMailFolderID = $TargetMailFolder.FolderID
$TargetMailFolderName = $TargetMailFolder.Name
Write-Host "TargetEmailFolderID is $($TargetMailFolderID)"
If ($TargetMailFolderID)
{
if ($TargetMailFolderName -eq $FolderName)
{
Write-Host "TargetEmailFolderID is $($TargetMailFolderID)"
Write-Host "TargetEmailFolderID is $($TargetMailFolderName)"
Return $TargetMailFolderID
}
}
Else
{
Write-Host "Target Email Folder does not exist"
}
}
}
catch {
throw "There was an error getting email folders"
break
}
}
function CleanupMailbox {
Param(
[parameter(Mandatory = $true)]
[String]
$Mailbox,
#$mailboxes = @("mailbox1@example.net", "mailbox2@example.net")
[parameter(Mandatory = $true)]
[String]
$DaysToKeep,
#$DaysToKeep = 3
[parameter(Mandatory = $true)]
[String]
$SearchName,
[parameter(Mandatory = $true)]
[String]
$SearchQuery
)
# Clean-up any old searches from failed runs of this script
if (Get-ComplianceSearch -Identity $searchName) {
Write-Host "Cleaning up any old searches from failed runs of this script"
try {
Remove-ComplianceSearch -Identity $searchName -Confirm:$false | Out-Null
}
catch {
Write-Host "Clean-up of old script runs failed!" -ForegroundColor Red
break
}
}
Write-Host "Creating new search for emails older than $($DateSearch)"
New-ComplianceSearch -Name $searchName -ExchangeLocation $Mailbox -ContentMatchQuery $SearchQuery -AllowNotFoundExchangeLocationsEnabled $true | Out-Null
Start-ComplianceSearch -Identity $searchName | Out-Null
Write-Host "Searching..." -NoNewline
while ((Get-ComplianceSearch -Identity $searchName).Status -ne "Completed") {
Write-Host "." -NoNewline
Start-Sleep -Seconds 2
}
$items = (Get-ComplianceSearch -Identity $searchName).Items
if ($items -gt 0) {
$searchStatistics = Get-ComplianceSearch -Identity $searchName | Select-Object -Expand SearchStatistics | Convertfrom-JSON
$sources = $searchStatistics.ExchangeBinding.Sources | Where-Object { $_.ContentItems -gt 0 }
Write-Host ""
Write-Host "Total Items found matching query:" $items
Write-Host ""
Write-Host "Items found in the following mailboxes"
Write-Host "--------------------------------------"
foreach ($source in $sources) {
Write-Host $source.Name "has" $source.ContentItems "items of size" $source.ContentSize
}
Write-Host ""
$iterations = 0;
$itemsProcessed = 0
while ($itemsProcessed -lt $items) {
$iterations++
Write-Host "Deleting items iteration $($iterations)"
#########################the below line does the delete
New-ComplianceSearchAction -SearchName $searchName -Purge -PurgeType SoftDelete -Confirm:$false | Out-Null
while ((Get-ComplianceSearchAction -Identity "$($searchName)_Purge").Status -ne "Completed") {
Start-Sleep -Seconds 2
}
$itemsProcessed = $itemsProcessed + 10
# Remove the search action so we can recreate it
Remove-ComplianceSearchAction -Identity "$($searchName)_Purge" -Confirm:$false
}
} else {
Write-Host "No items found"
}
Write-Host ""
Write-Host "COMPLETED!"
}
Import-Module ExchangeOnlineManagement
Connect-ExchangeOnline -Credential $cred
Connect-IPPSSession -Credential $cred
Write-Host "$(Get-Date -Format u) Cleanup $($Mailbox) Started"
$Mailbox = "emailaddresshere"
$FolderName = "foldernamehere"
$FolderID=GetFolderID -Mailbox $Mailbox -FolderName $FolderName
write-host "Returned Folder ID is: $($FolderID)"
$SearchName = "Cleanup$($Mailbox)$($Foldername)"
$DaysToKeep = 90
$DateSearch=(Get-Date).AddDays(-$($DaysToKeep)).ToString("yyyy-MM-dd") #ToString("MM/dd/yyyy")
write-host "$(Get-Date -Format u) DateSearch is $DateSearch"
$SearchQuery = "(subject:'subjectstringhere') AND (folderid:$($FolderID))"
write-host "Search query is <$($SearchQuery)>"
CleanupMailbox -Mailbox $Mailbox -DaysToKeep $DaysToKeep -SearchName $SearchName -SearchQuery $SearchQuery
Write-Host "$(Get-Date -Format u) Cleanup $($Mailbox) Finished"
Get-PSSession | Remove-PSSession
Write-Host "Cleanup complete"
So my script gets the folderid of the folder (it's correct) and runs.
I then get nothing happening.
When I check compliance on the web portal, my search is sitting there with the errors above.
I am only working on one single mailbox.... not 4.
If I edit and run the search without the folderid, it works.
If I construct the search using the query builder it doesn't offer me "folderid" from the dropdown despite the documentation but does "errorcheck" folderid properly.
It doesn't matter which inbox I use, which folder I use.
If I omit the folderid, it runs, if I include it fails with the messages below regardless of mailbox or folder.
I have tried every combo of " or ', = or :.
So is the documentation rubbish or am I missing something obvious?
Am I using the wrong cmdlet?