Exchange Online: löschen von gelöschten gelöschten Elementen

Ein User hatte viele (>30GB!) Daten in seiner Mailbox gelöscht, und konnte nun keine weiteren Elemente mehr löschen. Das Verhalten war typisch: im Outlook Client wird die Mail einfach nicht gelöscht. D.h. ich markiere ein Element, drücke Shift-Delete, bestätige die Warnung – … und nix passiert. Kein Fehler, kein Löschen.

In OWA konnten die Mails gelöscht werden, erschienen dann aber eine Sekunde später wieder im selben Ordner.

Empfehlung: Für Manipulationen mit grossen Datenmengen in Outlook sollte unbedingt der «Online»-Modus verwendet werden!

Wichtig, für folgende Befehle muss mit ExchangeOnline sowie Security & Compliance hergestellt werden:

Connect-ExchangeOnline
Connect-IPPSSession

Dieser Befehl zeigt das Problem:

Get-MailboxFolderStatistics $User -FolderScope RecoverableItems | FL Name,FolderAndSubfolderSize,ItemsInFolderAndSubfolders
Name : Recoverable Items
FolderAndSubfolderSize : 30 GB (32,214,533,730 bytes)
ItemsInFolderAndSubfolders : 80220
Name : Audits
FolderAndSubfolderSize : 268.9 MB (282,008,901 bytes)
ItemsInFolderAndSubfolders : 47373
Name : Calendar Logging
FolderAndSubfolderSize : 0 B (0 bytes)
ItemsInFolderAndSubfolders : 0
Name : Deletions
FolderAndSubfolderSize : 95.98 MB (100,641,633 bytes)
ItemsInFolderAndSubfolders : 73
Name : Purges
FolderAndSubfolderSize : 29.65 GB (31,831,883,196 bytes)
ItemsInFolderAndSubfolders : 32774
Name : SubstrateHolds
FolderAndSubfolderSize : 0 B (0 bytes)
ItemsInFolderAndSubfolders : 0
Name : Versions
FolderAndSubfolderSize : 0 B (0 bytes)
ItemsInFolderAndSubfolders : 0

Im Ordner «Recoverable Items» («gelöschte Elemente») befanden sich die noch (definitiv) zu löschenden Elemente.

Im Ordner «Purges» befinden sich die Elemente, welche zwar bereits definitiv gelöscht wurden, aber durch Exchange Online noch zurückbehalten werden (falls es sich der Benutzer – trotz dreimaligem löschen – noch anders überlegt).

Ich habe hier absichtlich meine gesamte «Reise» dargestellt. Die Lösung gibt es ganz unten.

Zuerst habe ich die Anleitung von Microsoft befolgt:

Get-Mailbox $User | FL SingleItemRecoveryEnabled,RetainDeletedItemsFor
Get-CASMailbox $User | FL EwsEnabled,ActiveSyncEnabled,MAPIEnabled,OWAEnabled,ImapEnabled,PopEnabled
Get-Mailbox $User | FL LitigationHoldEnabled,InPlaceHolds
Get-OrganizationConfig | FL InPlaceHolds
Get-Mailbox $User | FL DelayHoldApplied,DelayReleaseHoldApplied
Get-MailboxFolderStatistics $User -FolderScope RecoverableItems | FL Name,FolderAndSubfolderSize,ItemsInFolderAndSubfolders
Get-Mailbox $User | FL RetainDeletedItemsFor,SingleItemRecoveryEnabled,ElcProcessingDisabled
Set-Mailbox $User -RetainDeletedItemsFor 30
Set-Mailbox $User -SingleItemRecoveryEnabled $false
Set-Mailbox $User -ElcProcessingDisabled $true
Get-Mailbox $User | FL DelayHoldApplied,DelayReleaseHoldApplied

Danach muss man übers GUI eine neue Suche erstellen, für den entsprechenden Ordner (bei mir war das /Purges folderid:0A4ABD8C1C5F934283D2D2ED83724B370000000001170000)

Nun kann ich die gefundenen Elemente löschen:

New-ComplianceSearchAction -SearchName "i4MWsearch2" -Purge -PurgeType HardDelete

Das geht ganz fix. Nur wenige Sekunden. Der Nachteil: pro Befehl-Ausführung (sagt man dem so?) werden ganze 10 (zehn!!) Elemente gelöscht.

Ich habe knapp 38’000!!!

38’000!

Und unter «Recoverable Items» sogar 80’000 Elemente!

Es kann doch nicht sein, dass ich hier ein extra Script schreiben muss, um eine Microsoft-Anleitung in einem Loop auszuführen (leider war das dann doch so, siehe unten).

Der Vollständigkeit halber, mit diesen Befehlen wird dies abgeschlossen:

Get-ComplianceSearchAction
Remove-ComplianceSearchAction "i4MWsearch2_purge"

Schlussendlich konnte ich den Ordner mit folgenden Befehlen leeren:

Zuerst die Mailbox vorbereiten:

Set-Mailbox $User -LitigationHoldEnabled $False
Set-Mailbox $User -RemoveDelayHoldApplied
Set-Mailbox $User -RetainDeletedItemsFor 0
Set-Mailbox $User -SingleItemRecoveryEnabled $false

60 Minuten warten

Start-ManagedFolderAssistant $User -HoldCleanup

Mit

Get-MailboxFolderStatistics $User -FolderScope RecoverableItems | FL Name,FolderAndSubfolderSize,ItemsInFolderAndSubfolders

kann dann wieder überprüft werden, ob’s geklappt hat.

Doch die Story geht weiter. Leider hat das nix gebracht. Ich habe dann die Retention-Policy geprüft:

Get-Mailbox $user | select *Retention*

Hier war die Default-Policy aktiv. Mittels folgendem Befehl kann die entfernt werden:

Set-Mailbox $user -RetentionPolicy $null

Leider passierte auch damit nichts. Ich habe mich entschlossen, wieder den Weg von Microsoft einzuschlagen, aber halt ein Script zu schreiben/finden, welches den Löschvorgang in einem Loop ausführt.

Hier gibt es ein ganzes Toolset, welches u.a. diese Funktion beinhaltet. Aber das war mir dann too much.

In diesem Spiceworks Thread habe ich dann meine Lösung gefunden: Das Script des Users jonesbones. Ich habe es leicht angepasst, um den Ordner noch als Variable zu setzen. Ausserdem habe ich den foreach-Teil angepasst, dass das Löschen schneller abläuft:

$ScriptStart = Get-Date
$SearchName = 'DeleteSearch1'
$Mailbox = 'user@domain.ch'
$Folder = '/Purges'

$FolderStatistics = Get-MailboxFolderStatistics -Identity $Mailbox

# Convert Inbox folder ID to ID that can be used in compliance search
# https://docs.microsoft.com/en-us/microsoft-365/compliance/use-content-search-for-targeted-collections
$InboxFolderId = ($FolderStatistics | Where-Object {$_.FolderPath -eq $Folder}).FolderId
$Encoding= [System.Text.Encoding]::GetEncoding("us-ascii")
$Nibbler= $Encoding.GetBytes("0123456789ABCDEF");
$FolderIdBytes = [Convert]::FromBase64String($InboxFolderId);
$IndexIdBytes = New-Object byte[] 48;
$IndexIdIdx=0
$FolderIdBytes | select -skip 23 -First 24 | %{$indexIdBytes[$indexIdIdx++]=$nibbler[$_ -shr 4];$indexIdBytes[$indexIdIdx++]=$nibbler[$_ -band 0xF]}
$FolderQuery = "folderid:$($encoding.GetString($indexIdBytes))"

$Items = ($FolderStatistics | Where-Object {$_.FolderId -eq $InboxFolderId}).ItemsInFolder

$Iterations = [math]::Ceiling($Items / 10)

Remove-ComplianceSearch $SearchName -Confirm:$false # wird benötigt, wenn Script zuvor abgebrochen wurde

    New-ComplianceSearch -Name $SearchName -ExchangeLocation $Mailbox -ContentMatchQuery $FolderQuery | Out-Null
    Start-ComplianceSearch -Identity $SearchName | Out-Null
    Do {
        Start-Sleep -Seconds 2 # Adding 2 sec wait in case of possible timeouts from MS end
        $ComplianceSearch = (Get-ComplianceSearch -Identity $SearchName)
        #Write-Host "-- CS $($ComplianceSearch.Status), $($ComplianceSearch.Items)"
    } While ($ComplianceSearch.Status -ne 'Completed')

foreach ($Iteration in @(1..$Iterations)) {
    Write-Progress -Activity "Purging $Folder" -Status "$($ComplianceSearch.Items) items left" -PercentComplete ($Iteration / $Iterations * 100)
    Write-Host "[$Iteration / $Iterations]" #$($ComplianceSearch.Items) items left"
    New-ComplianceSearchAction -SearchName $SearchName -Purge -PurgeType HardDelete -Confirm:$false | Out-Null
    Do {
        #Start-Sleep -Seconds 1
        $PurgeAction = Get-ComplianceSearchAction -Identity "$SearchName`_Purge"
        #Write-Host "-- PA $($PurgeAction.Status)"
    } While ($PurgeAction.Status -ne 'Completed')
    
}

Remove-ComplianceSearch $SearchName -Confirm:$false

$ScriptEnd = Get-Date
$ExecutionTime = $ScriptEnd - $ScriptStart
Write-Host "$ExecutionTime"

Das Script läuft dann einfach ne (lange, seeehr lange) Weile, weil extrem ineffizient – danke Microsoft :|.

Ich musste das Script x-male neu starten. Es hat gemäss Anzeige mehrere huntert, vermutlich tausend Elemente gelöscht. Passiert ist aber trotzdem nichts!

Ich entschied mich, eine neue Mailbox zu erstellen, die Daten zu migrieren, und die «volle» Mailbox zu löschen. Doch, nur noch ein Versuch:

Get-MailboxFolderStatistics $User -FolderScope RecoverableItems | FL Name,FolderAndSubfolderSize,ItemsInFolderAndSubfolders
Get-MailboxFolderStatistics $User -FolderScope RecoverableItems | ft Name,foldersize
Start-ManagedFolderAssistant $User -HoldCleanup
Start-ManagedFolderAssistant $User -AggMailboxCleanup -FullCrawl
Get-Mailbox $User | FL RetainDeletedItemsFor,SingleItemRecoveryEnabled,ElcProcessingDisabled
Set-Mailbox $User -ElcProcessingDisabled $false
Start-ManagedFolderAssistant $User -StopHoldCleanup
Start-ManagedFolderAssistant $User -HoldCleanup
Get-Mailbox $User | FL DelayHoldApplied,DelayReleaseHoldApplied
Set-Mailbox $User -RemoveDelayHoldApplied
Set-Mailbox $User -RemoveDelayReleaseHoldApplied
Start-ManagedFolderAssistant -Identity $User

Und 2-3 Stunden später zeigten die Befehle, dass doch etwas geht:

Get-MailboxFolderStatistics $User -FolderScope RecoverableItems | FL Name,FolderAndSubfolderSize,ItemsInFolderAndSubfolders
Get-MailboxFolderStatistics $User -FolderScope RecoverableItems | ft Name,foldersize

«DiscoveryHolds» war von ein paar MB auf knapp 27GB angewachsen!
«Purges» war leer!
«Recoverable Items» zeigte beim ersten Befehl weiterhin 27GB an; beim zweiten aber (schon früher) 0B!

Im Postfach waren die noch zu löschenden Elemente bereits (als ganzen Ordner) unter «Gelöschte Elemente»:

Ich habe dann begonnen, die Elemente Blockweise (jeweils ein paar hundert) mittels «Shift-Delete» zu löschen. Dabei füllte sich der Ordner «Deletions».

Anmerkung: ich vermute, dass «Recoverable Items» dem übergeordneten Ordner entspricht. Die Grösse dieses Ordners änderte sich nie, und entsprach ungefähr (ich hab’s nicht gezählt) dem Wert aller anderen Ordnergrössen.

Ich konnte alle Elemente löschen. Die Option «gelöschte Elemente wiederherstellen» war nicht aktiv (wohl weil ich im Online-Modus war und die Elemente mit «Shift-Delete» gelöscht hatte.

Nach dieser Lösch-Aktion waren die Ordner wie folgt: «Recoverable Items» (33.9GB), «Deletions» (6.7GB) «DiscoveryHolds» (26.9GB).

Start-ManagedFolderAssistant $User

Danach verringerte sich die Grösse von «Deletions», und die Grösse von «DiscoveryHolds» vergrösserte sich. Dies ging soweit, bis ich folgenden Status hatte: «Recoverable Items» (33.9GB), «Deletions» (0B) «DiscoveryHolds» (33.7GB).

Start-ManagedFolderAssistant $User -HoldCleanup
Start-ManagedFolderAssistant $User -AggMailboxCleanup -FullCrawl

Nach diesen Befehlen leert sich der Ordner «DiscoveryHolds» langsam. Es scheint, als ob immer 1000 Elemente zusammen gelöscht werden.

Am nächsten Morgen sahen die Werte schon viel besser aus: Einzig «Discovery Holds» war noch im GB-Bereich (18.33GB). «Deletions» beinhaltete ca. 4GB.

Ich musste die «DelayHold’s» nochmals entfernen:

Set-Mailbox $User -RemoveDelayHoldApplied
Set-Mailbox $User -RemoveDelayReleaseHoldApplied

und danach den FolderAssistant nochmals starten:

Start-ManagedFolderAssistant -Identity $User

Nun war «Deletions» leer, aber «DiscoveryHolds» noch auf 23.07GB. Dieser Ordner lässt sich mit folgenden Befehlen leeren:

Start-ManagedFolderAssistant $User -HoldCleanup
Start-ManagedFolderAssistant $User -AggMailboxCleanup -FullCrawl

Schlussendlich konnte die Mailbox doch noch bereinigt werden.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

This site uses Akismet to reduce spam. Learn how your comment data is processed.