Recovering deleted emails from Microsoft Exchange can vary depending on the circumstances, but the Recoverable Items folder is often the key to retrieving emails affected by a retention policy. This folder holds items that have been deleted or moved from the Deleted Items folder, and is used for compliance, eDiscovery, and retention purposes. Although every recovery situation is unique, we’ll outline common tools and commands to help you effectively restore and recover items deleted by retention policies in Exchange Online.
Cmdlets Reference
Get-Mailbox
Get-RecoverableItems
Get-RetentionPolicy
Get-RetentionCompliancePolicy
Get-PolicyTags
Restore-RecoverableItems
Identify who and what is affected
First and foremost we need to understand what we're trying to recover. Based on the situation you're in, this is going to vary. Since in this topic we're specifically covering retention policies, either gone rogue or misconfigured, we're going to focus on identifying E-mails affected by that. But the idea and commands are the same. For this piece, you need to at least have one target mailbox you know that was affected. We're going to collect information from this mailbox to determine how to apply it broadly.
Collect information from the target mailbox
We're going to use Powershell to connect to ExchangeOnline to use the Get-RecoverableItems cmdlet on a target affected mailbox to collect information on the deleted items. What we're looking for specifically here is to identify the policy to lead to the item being deleted. If you're still having E-mails deleted and don't know why, this will double your fun by finding the policy that is wreaking havoc.
$targetMailbox = "user@techbarnone.com"
$recoverableItems = Get-RecoverableItems -Identity $targetMailbox -ResultSize Unlimited |
We want to use "-ResultSize Unlimited" to make sure our response can be over 10,000 items. With recovery, we want to make sure we're seeing everything. |
Now all of the recoverable items are stored in the $recoverableItems variable. Let's look through this array and see if we can identify common traits of the items that wound up here. Let's just look through the first 10.
$recoverableItems[0..9] |
This will print objects 0-9 from our array and list the properties. |
Lets look at an example of the returned data (but just one set). This is only an example and is not real Output so yours may differ slightly but this will give the idea. The important thing is to compare this with other returned data, and determine the similarities. Here we're going to focus on the PolicyTag property. This identifies which policy tagged the item for the action taken, in this case we're looking at, it usually lead to the delete action.
LastParentPath : /Inbox/Important
LastParentFolderID : AAMkADQ1NTgwNmRmLTQ0ZTYtNDNkZi1iYmZhLWY5
OriginalFolderExists : True
Identity : b29230af-35b2-4d1a-a4ed-78de07aeb330
MailboxIdentity : user@techbarnone.com
ItemClass : IPM.Note
Subject : Project Update
PolicyTag : 4c8f254b-cee1-30df-835b-c93cfdeff312
If you're here specifically for items deleted by a policy, then take note! The PolicyTag has the GUID of the policy that lead to the file deletion. This can be a literal policy tag, a policy itself, a Purview DLP policy, or an assortment of other things that are able to trigger the ManagedFolderAssistant to take action. I can't specifically cover each, but with that GUID you should be able to match it to a policy, policy tag, DLP policy, or a retention policy. Purview can get tricky and the nested policies have their own tag, so you may need to dig deep to identify the policy, but if you can at least draw the correlation between incorrectly deleted items, and the policy GUID, then we have suitable parameters for a broad restoration.
Let's review what this means before we take our next actions
At this point, if you're here for retention deletions, we (you) should be able to identify the unique PolicyTag that is applied to the mistakenly deleted items (if you know of another user that is experiencing the issue, you can repeat the steps above and check if the PolicyTag matches the value of your first targetMailbox's results). This is how we're going to specifically target items deleted by the retention policy, and not restore spam/junk/intentionally deleted items.
If you're just here to recover ALL the deleted items, you don't need to worry about the PolicyTag and I'll note this specifically for you later in the process as well.
At this point, we're now ready to execute a broad recovery across the environment. We know the specific PolicyTag we're targeting (or we're targetting everying) and that's enough to crawl and rectify. But let's just think on it a moment...
The corners we cut
We have all the information we need to restore, but we don't have our targets. Realistically in this situation, if we target EVERYONE and SOMEONE doesn't have the issue, there won't be a problem, there simply won't be any items to recover. But we should consider the waste of processing, or if you're in a huge enterprise environment, wasting time on users that don't have the issue could make the process take 5, 10, 50, 100 times as long. So let's just take a peek at how we can collect additional information faster than we can throw spaghetti at it. From experience, I know for a fact that the Restore-RecoverableItems cmdlet is a much more time consuming action than the Get-RecoverableItems cmdlet. We can use Get-RecoverableItems with the -PolicyTag <GUID identified earlier> parameter (or without if you're looking to recover all items in the RecoverableItems folder), to search all mailboxes to see if they contain any of the E-mails mistakenly deleted by the policy. This will highlight exactly who we need to target for recovery as well. Consider the following: Restore-RecoverableItems takes 1 second to process (wishful thinking).
Get-RecoverableItems takes 0.2 seconds to process, but doesn't accomplish the task.
Instead of running Restore-RecoverableItems on 500 targets at a costly 1 second per target, we can first employ Get-RecoverableItems to isolate only those that truly need items to be recovered. Get-RecoverableItems, with its efficient 0.2-second processing per target, will help us target only what’s necessary. If, for instance, Get-RecoverableItems reveals that only 200 of the 500 targets require Restore-RecoverableItems, we avoid 300 redundant restore operations. This approach shifts our processing time from 500 seconds for all targets to just 200 seconds for Restore-RecoverableItems, and 100 seconds for Get-RecoverableItems, saving 200 seconds in total in this example. Mileage will vary.
Get affected mailboxes
We're going to use Get-Mailbox to select all of the mailboxes in our tenant, and use the -ResultSize Unlimited parameter to make sure our returned array is not truncated. After that, we search each mailbox for any recoverable items that match the PolicyTag from above. If any matching items are found, the mailbox is added to the $affectedMailboxes array, which is what will become our targets.
$allMailboxes = Get-Mailbox -Filter * -ResultSize Unlimited
$affectedMailboxes = foreach ($mb in $allMailboxes) {
$recoverableItems = Get-RecoverableItems $mb.alias -PolicyTag <PolicyTagGUIDfromAbove>
if ($recoverableItems) {
Write-Host "This mailbox contains a target recoverable item and is impacted: ($mb.alias) $($mb.UserPrincipalName)"
$mb
} else {
Write-Host "No target recoverable items were found in the mailbox: $($mb.alias) $($mb.UserPrincipalName)"
}
} |
This will output responses as we move through the array of mailboxes, but will also store any mailboxes that were affected directly into the $affectedMailboxes array for us to reference for recovery. |
Recover target items from affected mailboxes
Now that we have our list of affected mailboxes stored in $affectedMailboxes, we can iterate against this list to save time when using Restore-RecoverableItems.
foreach ($mb in $affectedMailboxes) {
Write-Host "Restoring items for $($mb.alias) $($mb.UserPrincipalName)"
Restore-RecoverableItems -Identity $mb.Alias -PolicyTag <PolicyTagGUIDfromAbove> -ResultSize Unlimited |
This will loop through each $affectedMailbox item and use Restore-RecoverableItems on the mailbox, with the matching policy tag. If you're just here to restore ALL deleted items (keep in mind this will restore items intentionally deleted by the mailbox owner), then you can leave off the PolicyTag parameter in the scripts above. Restore-RecoverableItems -Identity $mb.Alias -PolicyTag <PolicyTagGUIDfromAbove> -ResultSize |
At this point deleted items should start being restored
The above command may timeout on mailboxes that have over 100,000 recoverable items. If this occurs, simply rerun the same loop. Mailboxes that were already fully recovered will quickly pass by, and mailboxes that had issues will get to continue pushing forward. Run the command until you get no error output. If you're doing this over a massive number of mailboxes, you may want to add a Try Catch into the script for error handling to repeat the action on the Microsoft.Powershell.Commands.WriteErrorException,Write-ErrorMessage shown below.
Write-ErrorMessage : A server side error has occurred because of which the operation could not be completed. Please try again after some time. If the problem still persists, please reach out to MS support.
At C:\Users\username\AppData\Local\Temp\tmpEXO_xxxx.urn\tmpEXO_xxxx.urn.psm1
+ Write-ErrorMessage $ErrorObject
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorID : Microsoft.PowerShell.Commands.WriteErrorException,Write-ErrorMessage
Do your diligence and check recovered mailboxes
Make sure you check some of your target mailboxes to confirm items have been restored as expected. In some cases, you may find drafts or old meeting invites having also been restored with the recovery operation. You may want to make your users aware that it may be expected for them to have to dismiss many long overdue meeting notices. If you haven't identified the rogue policy or the reason items are being deleted, then you will need to continue repeating the above operations until you can ensure no further items are being deleted. In the case of catastrophic recovery events, it is worth it to solicit Microsoft for support, as a veteran engineer aware of the meaning of what you're looking at, can be very effective at constructing a full recovery plan.
Comentarios