The Get-MgUserMessageContent cmdlet with Microsoft Graph PowerShell provides a method for exporting emails to your local machine in .eml format, which anyone can read. In this post, I will show you how to bulk export emails from any Exchange Online (M365) mailbox in your organisation. Also, how to filter the export for emails within a certain date range and with specific information in the subject line.
Requirements
This script uses the following Microsoft Graph PowerShell modules:
- Microsoft.Graph.Authentication
- Microsoft.Graph.Mail
You will also need a Global Administrator account in your tenant to consent to the following permissions:
- Mail.Read
For support with these requirements, see my post: How To Install the Microsoft Graph PowerShell Module.
The Mail.Read permission is only available in the application context. For this, you will need to register a new application in Microsoft Entra and connect to it in the application context through PowerShell. See my post Connect To Microsoft Graph PowerShell With a Client Secret.
Backup Exchange Online Mailbox
Backing up Exchange Online emails using Microsoft Graph PowerShell should only be done in certain scenarios. For example, a user has left your organisation, and you need a copy of the user’s files in .eml format. Or you need to download a copy of a users emails between a certain date.
You can use the below script to download a copy of all the emails in the user’s mailbox (including attachments of emails).
## Define information here
$ApplicationId = ""
$SecuredPassword = ""
$tenantID = ""
$UserID "" #Example: [email protected]
$filepath = "" #Example: C:\temp\
#Connect to Microsoft Graph
$SecuredPasswordPassword = ConvertTo-SecureString `
-String $SecuredPassword -AsPlainText -Force
$ClientSecretCredential = New-Object `
-TypeName System.Management.Automation.PSCredential `
-ArgumentList $ApplicationId, $SecuredPasswordPassword
Connect-MgGraph -TenantId $tenantID -ClientSecretCredential $ClientSecretCredential
#Store all emails
##Add filter if required
$messages = Get-MgUserMessage -UserId $userid -all
#Download all emails
Foreach ($message in $messages) {
$file = ($File = "$($message.subject) $($message.ReceivedDateTime).eml").Split([IO.Path]::GetInvalidFileNameChars()) -join '_'
$outfile = $filepath + $file
try {
Get-MgUserMessageContent -UserId $userid -MessageId $message.id -OutFile $outfile
}
Catch {
LogWrite "Unable to export " $message.Subject
}
}
Defining a date range for backing up Exchange Online emails
In the case that you want to only export emails between a certain date range, you can use filter queries to limit your results.
Below, I have combined two filters using the AND operator to export only emails between the 1st of January and the 9th of January.
Get-MgUserMessage -UserId $userid -all `
-filter "ReceivedDateTime ge 2024-01-01 AND ReceivedDateTime le 2024-01-09"
This filter can be expanded even further to include messages that have a certain string of text in the subject line. For example:
I have used the backtick `, to make it readable without scroling.
Get-MgUserMessage -UserId $userid -all `
-filter "ReceivedDateTime ge 2024-01-01 AND ReceivedDateTime le 2024-01-09 `
AND contains(Subject, 'New Device')" `
| Select Subject, ReceivedDateTime
Wrapping up
Downloading email message files in bulk shouldn’t be considered as an only ‘backup’ solution to storing mail for users that have left the business. You should still consider a 3rd party backup solution and/or maintaining the mailbox as a shared mailbox. However, it provides a convenient solution to export bulk emails in case of a backup, investigation, or compliance reason.