How to Permanently Remove Mailbox Items with the Graph API
Permanent Deletion for Message and Other Types of Items from User Mailboxes
On April 1, 2025, Microsoft announced the availability of APIs to permanently delete mailbox items. This news might well have passed you by because the post appeared in the developer blog rather than anything a Microsoft 365 tenant administrator might see.
The APIs are intended to fill in some gaps in Graph API coverage for mailbox items compared to Exchange Web Services (EWS). It’s part of the campaign to remove EWS from Exchange Online by October 2026. An example of where permanent removal of mailbox items is needed is when migrating mailboxes from one tenant to another. After a successful move, the migration utility might clean up by removing items from the source mailbox.
In any case, APIs are now available to permanently delete mail message, mail folder, event, calendar, contact, and contact folder objects.
What Permanent Removal Means
In this context, permanent removal means that no client interface exists to allow the user to recover the message. For example, users can’t use Outlook’s Recover Deleted Items facility to retrieve the deleted items and administrators can’t use the Get-RecoverableItems cmdlet to do likewise (or appear in a report of recoverable items).
The reason why this is so is that when Outlook deletes items in the Deleted Items folder, the items move to the Deletions folder within Recoverable Items. When the API deletes an item, the item moves to the Purges folder. If the item is not subject to a hold, the Managed Folder Assistant will remove it the next item the mailbox is processed. If it is subject to a hold, the item remains in the Purges folder until the hold lapses.
Permanent Removal with the Microsoft Graph API
Two pieces of information are needed to permanently remove a message item using the Graph API: the object identifier for the account that owns the mailbox and the message identifier. Let’s assume that you have a variable containing details of a message:
$Message | Format-List Subject, CreatedDateTime, Id Subject : Thank You for Subscribing CreatedDateTime : 06/05/2022 06:47:28 Id : AAMkADAzNzBmMzU0LTI3NTItNDQzNy04NzhkLWNmMGU1MzEwYThkNABGAAAAAAB_7ILpFNx8TrktaK8VYWerBwDcIrNcmtpBSZUJ1fXZjZ5iAB_wAYDdAAA3tTkMTDKYRI6zB9VW59QNAAQnaACXAAA=
To delete the item, construct a URI pointing to the message and post the request to the messages endpoint. This example shows where the variables for the user identifier and message identifier are in the URI:
$Uri = ("https://graph.microsoft.com/v1.0/users/{0}/messages/{1}/permanentDelete" -f $UserId, $Message.Id) $Uri https://graph.microsoft.com/v1.0/users/eff4cd58-1bb8-4899-94de-795f656b4a18/messages/AAMkADAzNzBmMzU0LTI3NTItNDQzNy04NzhkLWNmMGU1MzEwYThkNABGAAAAAAB_7ILpFNx8TrktaK8VYWerBwDcIrNcmtpBSZUJ1fXZjZ5iAB_wAYDdAAA3tTkMTDKYRI6zB9VW59QNAAQnaACXAAA=/permanentDelete Invoke-MgGraphRequest -Uri $Uri -Method Post
The Graph API doesn’t ask for confirmation before proceeding to remove the item and it doesn’t provide a status to show that the deletion was successful. The only indication that something happened is found by using the Get-MailboxFolderStatistics cmdlet to see if the items in the Purges folder increase:
Get-MailboxFolderStatistics -FolderScope RecoverableItems -Identity Tony.Redmond | Format-Table Name, ItemsInFolder Name ItemsInFolder ---- ------------- Recoverable Items 0 Deletions 2135 DiscoveryHolds 2543 Purges 16 SubstrateHolds 12 Versions 79
Alternatively, use the MFCMAPI utility to examine the items in the Purges folder. Figure 1 shows that the “Thank you for subscribing” message is in the Purges folder.

Permanent Removal with the Microsoft Graph PowerShell SDK
The Remove-MgUserMessagePermanent cmdlet does the same job as the Graph API request:
Remove-MgUserMessagePermanent -UserId $UserId -MessageId $Message.Id
Once again, there’s no status or confirmation required for the deletion to proceed. The other Microsoft Graph PowerShell SDK cmdlets to permanently remove objects are:
- Remove-MgUserMailFolderPermanent: Remove mail folder
- Remove-MgUserCalendarPermanent: Remove calendar.
- Remove-MgUserEventPermanent: Remove calendar event.
- Remove-MgUserContactPermanent: Remove contact.
- Remove-MgUserContactFolderPermanent: Remove contact folder.
All the cmdlets work in the same way. Deletion is immediate and permanent.
Adding new automation capabilities by extending APIs is always welcome. I just need to find a suitable use case for the new cmdlets.
Need some assistance to write and manage PowerShell scripts for Microsoft 365? Get a copy of the Automating Microsoft 365 with PowerShell eBook, available standalone or as part of the Office 365 for IT Pros eBook bundle.