Site icon Microsoft 365 for IT Pros

How to Use JSON Batching to Permanently Remove Mailbox Items

JSON batching and mailbox item removal.
Advertisements

Increase Performance by Batching Graph Requests to Delete Mailbox Items

A previous article describes how to use JSON batching to increase the performance of Graph-based automation for large Microsoft 365 tenants. In that article, I show how to use batching to update the properties of Entra ID accounts with PATCH requests. JSON batching isn’t confined to Entra ID accounts and isn’t limited to updating properties. To prove the point, I upgraded a script to remove notification messages from mailboxes to use JSON batching. Let’s discuss the changes to the script.

The basic setup remains the same. The script sets out to delete notification messages and defines a set of 12 SMTP addresses that send the messages. You can choose whatever SMTP addresses you want. The script will delete all messages from the selected addresses.

Because the script processes all user mailboxes, it uses app-only authentication through a registered Entra ID application. You can download the full script from the Microsoft 365 for IT Pros GitHub repository.

Find Mailboxes to Process

The first step is to find user accounts with an enabled Exchange Online service plan (plan 1 or plan 2). Shared mailboxes with an Exchange Online license will be found. The Entra ID accounts created for shared mailboxes are disabled, so to exclude these mailboxes, the filter used with the Get-MgUser cmdlet includes a check for enabled accounts to make sure that it only processes user mailboxes. To include shared mailboxes, modify the filter to remove the check for enabled accounts.

Finding and Permanently Deleting Notification Messages

Each mailbox is checked with the Get-MgUserMessage cmdlet to find matching messages. Checking is against the sender, and no other metadata is examined. If required, a more complex search against searchable email properties can be used to find items, like the one described in this article.

If Get-MgUserMessage finds some matching notification messages, the code divides the items into batches of 20 (the maximum number of items in a batch supported by JSON batching) using the same approach as described in the primer. As explained in the primer, JSON batches are built using Graph API requests rather than Microsoft Graph PowerShell SDK cmdlets.

Three notable differences in the API request created for each item are:

ForEach ($Message in $CurrentBatch) {
   $Counter++
   $Uri = "/users/{0}/Messages/{1}/permanentDelete" -f $User.Id, $Message.Id
   $BatchRequest = [PSCustomObject][Ordered]
       id      = "$counter"
       method  = "POST"
       url     = $Uri
       headers = @{ "Content-Type" = "application/json" }
   }
  $BatchRequests.Add($BatchRequest)
}

Permanent deletion means that Exchange moves the items into the Purges sub-folder in the Recoverable Items folder. Outlook clients cannot recover items from Purges, and the items remain there until they are removed by the Managed Folder Assistant. Items required for retention remain in Purges until the retention period lapses.

If you want items to be recoverable, the value for the $Uri variable is “/users/{0}/Messages/{1}” and the method is DELETE. In this case, Exchange moves the items into the Deletions sub-folder. Outlook’s Recover Deleted Items feature can restore items from this folder. Administrators can list recoverable items with the Get-RecoverableItems cmdlet and recover items with the Restore-RecoverableItems cmdlet.

Obviously, submitting many message deletion requests in a short period runs the risk of throttling. The script includes a short delay after each mailbox to avoid Exchange Online throttling processing. You might need to make the delay longer when processing more than a few hundred mailboxes or if the script finds large numbers of messages to remove.

After all mailboxes are processed, the script sends email to each user who had some messages removed to tell them what happened. It also generates a report file as an Excel worksheet (if the ImportExcel module is available – Figure 1) or CSV file listing all the deleted messages.

Figure 1: Reporting messages deleted by the script

Deleting items from user mailboxes is always a sensitive operation, even if you are thoughtful enough to send the users email to explain what was done. Protect sensitive mailboxes with RBAC for Applications and make sure that full approval is granted before launching any batches to find and remove items.

Faster Performance for a Little Extra Work

Microsoft cannot guarantee that a script will process data x times faster if you use JSON batching. Performance is improved by eliminating network round trips. Anecdotal reports suggest that scripts might run up to five times faster, but many dependencies exist before such a gain is achieved.

Filtering must be efficient, throttling should be minimized, and the code must be reasonably optimized. If that’s the case, you might benefit as follows:

JSON batching helps less for queries that already retrieve information efficiently because processing is dominated by the Graph fetching objects rather than sending those objects across the network. In other words, you won’t know what the exact gain is until you put JSON batching to work.


Need help to write and manage PowerShell scripts for Microsoft 365, including Azure Automation runbooks? Get a copy of the Automating Microsoft 365 with PowerShell eBook, available standalone or as part of the Microsoft 365 for IT Pros eBook bundle.

Exit mobile version