news and know-how about microsoft, technology, cloud and more.

Export email messages from Exchange Online to a CSV file with Graph PowerShell

I had to export email messages from a specific folder in my Outlook mailbox to a CSV file for further processing. Nothing special, just a quick export. I noticed that Outlook allows messages to be exported, but the date of the message is missing in the export file! Really? So here is a workaround to quickly export email messages using Graph PowerShell.

Why PowerShell

Of course there are many ways to export emails. Unfortunately, the Outlook method is unsatisfactory. When opening the File menu in Outlook for the desktop, there is an "Open & Export" menu which has an Import/Export function. Well, the wizard allows to export messages to a CSV or to a PST file.


Then, the user can select a folder and export all messages to the selected file. The problem for me was, that there is no message date included... The graphic shows the first lines of such a CSV file, with the columns headers and no date. That is useless.


Another task was to automate the export as simply as possible. So, PowerShell, here we go.

Export with Graph PowerShell

Unfortunately, the relatively new Exchange v2 PowerShell module does not support an email messages export as far as I have seen. Knowing Microsoft Graph, this was my first choice. To automate an export, the Microsoft Graph PowerShell module came in at the right time.

The goal was to export (almost) all messages from a subfolder "~CoE" of my Inbox:


While the basic idea and the script was simple, I struggled with expanding the data supplied. Thankfully, my colleague Christoph Wilfing, our PowerShell expert, supported me and did the tricky part of the elegant extraction of the multi-value properties. Many thanks, Christoph!

Here I'm just focusing on the PowerShell script, I'm running it on PowerShell Core. You can get it from my GitHub Office 365 scripts repository here, or below. For more information with details, see Install the Microsoft Graph PowerShell SDK, Get started with the Microsoft Graph PowerShell SDK, and Microsoft.Graph.Mail.

# export-messages-with-graph-powershell.ps1
#, Toni Pohl, Christoph Wilfing

# One-time process: Install the Graph module
Install-Module Microsoft.Graph -Scope CurrentUser
# Or update the existing module to the latest version
# Update-Module Microsoft.Graph

# Check the cmdlets
# Get-InstalledModule Microsoft.Graph

Import-Module Microsoft.Graph.Mail

# Connect with Mail.Read permissions
Connect-MgGraph -Scopes "Mail.Read"

# Show the user context just as info

# get your user id - insert your own primary email address here
$user = Get-MgUser -Filter "UserPrincipalName eq '<your-email-address>'"
# Get a list of all mail folders
$folders = Get-MgUserMailFolder -UserId $user.Id -All
# Select the Inbox
$inbox = $folders | Where-Object { $_.DisplayName -eq "Inbox" }
# Get a list of all sub folders of the Inbox
$childs = Get-MgUserMailFolderChildFolder -UserId $user.Id -MailFolderId $inbox.Id -All
# Select the desired folder
$myfolder = $childs | Where-Object { $_.DisplayName -eq "<your-subfolder>" }

# Get all mails and export them (add an optional where filter if needed).
# We remove all HTML tags, repair line breaks and HTML spaces to get a readable text in the result file.
Get-MgUserMailFolderMessage -All `
    -UserId $user.Id `
    -MailFolderId $myfolder.Id | `
    Select-Object `
    @{N = 'Received'; E = { $_.ReceivedDateTime } }, `
    @{N = 'Sender'; E = { $_.Sender.foreach{ ($_.Emailaddress) }.address } }, `
    @{N = 'ToRecipient'; E = { $_.ToRecipients.foreach{ ($_.Emailaddress) }.address } }, `
    @{N = 'ccRecipient'; E = { $_.ccRecipients.foreach{ ($_.Emailaddress) }.address } }, `
    @{N = 'Subject'; E = { $_.Subject } }, `
    @{N = 'Importance'; E = { $_.Importance } }, `
    @{N = 'Body'; E = { ($_.Body.Content -replace '</p>',"`r`n" -replace "<[^>]+>",'' -replace "&nbsp;",' ').trim() } } | `
    Where-Object {( ($_.Subject -notlike "*newsletter*") -and ($_.Subject -notlike "*FYI*") ) } | `
    Export-Csv ".\mails.csv" -Delimiter "`t" -Encoding utf8

# End. Check the mails.csv file.
# Best, open it with Microsoft Excel: Menu Data, From Text/CSV and follow the wizard.

# Disconnect when done

When the script is executed, it produces (overwrites) the output file, here it´s mails.csv.

Check the result

The CSV can be imported in Microsoft Excel. The output shows the relevant email messages of the exported folder (inclusive date and time). In addition, the body is clean and easy to read and we are free to modify the script and the message properties as needed.


As you can see, you can easily automate such exports and other email-related tasks. The Microsoft Graph PowerShell module runs with PowerShell 7 and later and it's also compatible with Windows PowerShell 5.1.

I hope this little tool saves time and is a quick fix for such use cases!