Exchange Online Export-Import Graph API Preview

Hi All,
About two Weeks ago, Microsoft has announced the public preview of the Exchange Export-Import Graph API.
Many of our customers currently rely on APIs powered by Exchange Web Services (EWS) for tasks like Exchange mailbox backup, archiving and migration. However, with the EWS deprecation initiative, customers have been asking for a method built on the Microsoft Graph platform to discover mailbox items, selectively export them and then import these items into Exchange Online mailboxes.
API features We are introducing a solution that includes several valuable features, enabling users to effectively utilize these new APIs:
- Discovery into Mailbox Hierarchy: The APIs allow drilling down into the mailbox hierarchy, including mailbox folders, child folders, and individual mailbox items.
- Agnostic to the type of mailbox items: Our solution identifies and supports all types of mailbox items, such as messages, contacts, and calendar items, given that they fall under the IPM subtree (refer to IPM Subtree | Microsoft Learn for more information).
- Support for Archive Mailboxes: Our solution provides support for both users primary mailboxes and their In-Place Archive mailboxes.
- Folder Management: Users can create, update, and delete mailbox folders, allowing flexibility in modifying mailbox folder structures.
- Extended Properties: Our solution enables support for single-value and multi-value extended properties associated with mailbox folders and items. These properties allow storing and accessing custom data that is not already exposed in the Microsoft Graph API metadata (refer to Outlook extended properties overview – Microsoft Graph v1.0 | Microsoft Learn for more information).
- Granular Permission Scopes: We ensure controlled access for applications and users, allowing them to read, export, and import their Exchange mailbox data based on their specific use cases. View the documentation here.
Note: These APIs currently do not support Public Folders.
Already Supported Graph Functions
A lot of these Graph Functions like Folder and Item Management, already exist in current Graph API’s. I’ve documented some basic Functionality here some time ago:
Entra App registration
I’ve created an Entra Application registration
Added the Redirect URI
Addet the Certificate for Authentication
Added the Application Permissions:
- Mail.Read
- MailboxFolder.Read.All
- MailboxFolder.ReadWrite.All
- MailboxItem.ImportExport.All
- MailboxItems.Read.All
- User.Read.All
Get AccessToken
I’ve used the PSMSALNet to aquire the Access Token.
Note that PSMSALNet requires PowerShell 7.4 or newer
###############################################################################
# Get Access Token using App Permission with a Certificate
###############################################################################
#Setting up the Variables for all Examples
Import-Module PSMSALNet
$TenantId = "46bbad84-29f0-4e03-8d34-f6841a5071ad" #Icewolfch.onmicrosoft.com
$AppID = "5107c0b7-477e-4af1-bf4c-222f492c1c12" #EXOExportImport
$RedirectUri = "https://login.microsoftonline.com/common/oauth2/nativeclient"
$CertificateThumbprint = "A3A07A3C2C109303CCCB011B10141A020C8AFDA3"
#Get Access Token
$Certificate = Get-ChildItem -Path cert:\CurrentUser\my\$CertificateThumbprint
$HashArguments = @{
ClientId = $AppID
ClientCertificate = $Certificate
TenantId = $TenantId
Resource = "GraphAPI"
}
$Token = Get-EntraToken -ClientCredentialFlowWithCertificate @HashArguments
$AccessToken = $Token.AccessToken
$AccessToken
Check Access Token
There are several ways to check the Access Token. Ive used the PowerShell Module JWTDetails
###############################################################################
# Check Access JWT Token
###############################################################################
# In Browser https://jwt.ms/
#Install-PSResource -Name JWTDetails
#Get-InstalledPSResource -Name JWTDetails
Get-JWTDetails $AccessToken
Exchange Settings
To get the ExchangeMailboxId required by some of the following Querys, you need to use this API. As you can see, it also supports Archive Mailboxes.
Permission type | Least privileged permissions | Higher privileged permissions |
---|---|---|
Delegated (work or school account) | User.Read.All | User.ReadWrite.All |
Delegated (personal Microsoft account) | Not supported. | Not supported. |
Application | User.Read.All | User.ReadWrite.All |
###############################################################################
# exchangeSettings resource type
# https://learn.microsoft.com/en-us/graph/api/resources/exchangesettings?view=graph-rest-beta
###############################################################################
#Mailbox without Archive
$Mailbox = "a.bohren@icewolf.ch"
$URI = "https://graph.microsoft.com/beta/users/$Mailbox/settings/exchange"
$ContentType = "application/json"
$Headers = @{"Authorization" = "Bearer "+ $AccessToken}
$Result = Invoke-RestMethod -Method "GET" -Uri $URI -Headers $Headers -ContentType $ContentType
$Result | fl
#Mailbox with Archive
$Mailbox = "m.muster@icewolf.ch"
$URI = "https://graph.microsoft.com/beta/users/$Mailbox/settings/exchange"
$ContentType = "application/json"
$Headers = @{"Authorization" = "Bearer "+ $AccessToken}
$Result = Invoke-RestMethod -Method "GET" -Uri $URI -Headers $Headers -ContentType $ContentType
$Result | fl
Exchange
If you check with Exchange Online PowerShell you can see the Format:
MBX:<ExchangeGUID or ArchiveGUID>@<Tenantid>
Import-Module ExchangeOnlineManagement
Connect-ExchangeOnline -ShowBanner:$false
Get-Mailbox -Identity m.muster -Archive | fl *guid*
Folder Management
List Folders
List Folders of a specific Mailbox or Archive Mailbox (Only Folders from “Top of Information Store” or “IPM_Subtree”). It will give you back the ID of the Folder - similar to EWS.
Permission type | Least privileged permissions | Higher privileged permissions |
---|---|---|
Delegated (work or school account) | MailboxItem.ImportExport | Not available. |
Delegated (personal Microsoft account) | Not supported. | Not supported. |
Application | MailboxItem.ImportExport.All | Not available. |
###############################################################################
# List Folders
# https://learn.microsoft.com/en-us/graph/api/mailbox-list-folders?view=graph-rest-beta&tabs=http
###############################################################################
#GET /admin/exchange/mailboxes/{mailboxId}/folders
$MailboxId = "MBX:18f5d451-048e-4f8c-a663-d2229c32a678@46bbad84-29f0-4e03-8d34-f6841a5071ad" #m.muster@icewolf.ch
$URI = "https://graph.microsoft.com/beta/admin/exchange/mailboxes/$MailboxId/folders"
$ContentType = "application/json"
$Headers = @{"Authorization" = "Bearer "+ $AccessToken}
$Result = Invoke-RestMethod -Method "GET" -Uri $URI -Headers $Headers -ContentType $ContentType
$Result.Value
#https://graph.microsoft.com/beta/admin/exchange/mailboxes/MBX:584e83eb-c967-4b4a-9fba-227fab424dbd@46bbad84-29f0-4e03-8d34-f6841a5071ad/folders?$select=id,displayName,childFolderCount,totalItemCount
Create Folder
This Example shows you how to create a Folder.
Permission type | Least privileged permissions | Higher privileged permissions |
---|---|---|
Delegated (work or school account) | MailboxFolder.ReadWrite | Not available. |
Delegated (personal Microsoft account) | Not supported. | Not supported. |
Application | MailboxFolder.ReadWrite.All | Not available. |
###############################################################################
# Create mailboxFolder
# https://learn.microsoft.com/en-us/graph/api/mailbox-post-folders?view=graph-rest-beta&tabs=http
###############################################################################
#POST /admin/exchange/mailboxes/{mailboxId}/folders/inbox/childFolders
#POST https://graph.microsoft.com/beta/admin/exchange/mailboxes/MBX:e0648f21@aab09c93/folders
$MailboxId = "MBX:18f5d451-048e-4f8c-a663-d2229c32a678@46bbad84-29f0-4e03-8d34-f6841a5071ad" #m.muster@icewolf.ch
$URI = "https://graph.microsoft.com/beta/admin/exchange/mailboxes/$MailboxId/folders/Inbox/childFolders"
$ContentType = "application/json"
$Headers = @{"Authorization" = "Bearer "+ $AccessToken}
$Body = @"
{
"displayName": "Announcements",
"type": "IPF.Note",
"singleValueExtendedProperties": [
{
"id": "String 0x3001",
"value": "Announcements"
}
]
}
"@
$Result = Invoke-RestMethod -Method "POST" -Uri $URI -Body $Body -Headers $Headers -ContentType $ContentType
$Result
Get mailboxFolder
This Example shows you how to get a specific Folder (based on FolderID)
Permission type | Least privileged permissions | Higher privileged permissions |
---|---|---|
Delegated (work or school account) | MailboxFolder.Read | MailboxFolder.ReadWrite |
Delegated (personal Microsoft account) | Not supported. | Not supported. |
Application | MailboxFolder.Read.All | MailboxFolder.ReadWrite.All |
###############################################################################
# Get mailboxFolder
# https://learn.microsoft.com/en-us/graph/api/mailboxfolder-get?view=graph-rest-beta&tabs=http
###############################################################################
#GET /admin/exchange/mailboxes/{mailboxId}/folders/{mailboxFolderId}
#GET /admin/exchange/mailboxes/{mailboxId}/folders/{mailboxFolderId}/childFolders/{mailboxFolderId}
$MailboxId = "MBX:18f5d451-048e-4f8c-a663-d2229c32a678@46bbad84-29f0-4e03-8d34-f6841a5071ad" #m.muster@icewolf.ch
$FolderId = "AAMkADE4ZjVkNDUxLTA0OGUtNGY4Yy1hNjYzLWQyMjI5YzMyYTY3OAAuAAAAAABTq53BPRd5QLt7lLR88XvbAQAz0IL1wr3xRKNiSJ254HvqAASS-E4rAAA="
$URI = "https://graph.microsoft.com/beta/admin/exchange/mailboxes/$MailboxId/folders/$FolderID"
$ContentType = "application/json"
$Headers = @{"Authorization" = "Bearer "+ $AccessToken}
$Result = Invoke-RestMethod -Method "GET" -Uri $URI -Headers $Headers -ContentType $ContentType
$Result
Update mailboxFolder
This Example shows you how to Update the Display Name of a Folder.
Permission type | Least privileged permissions | Higher privileged permissions |
---|---|---|
Delegated (work or school account) | MailboxFolder.ReadWrite | Not available. |
Delegated (personal Microsoft account) | Not supported. | Not supported. |
Application | MailboxFolder.ReadWrite.All | Not available. |
###############################################################################
# Update mailboxFolder
# https://learn.microsoft.com/en-us/graph/api/mailboxfolder-update?view=graph-rest-beta&tabs=http
###############################################################################
#PATCH /admin/exchange/mailboxes/{mailboxId}/folders/{mailboxFolderId}
#PATCH /admin/exchange/mailboxes/{mailboxId}/folders/{mailboxFolderId}/childFolders/{mailboxFolderId}
$MailboxId = "MBX:18f5d451-048e-4f8c-a663-d2229c32a678@46bbad84-29f0-4e03-8d34-f6841a5071ad" #m.muster@icewolf.ch
$FolderId = "AAMkADE4ZjVkNDUxLTA0OGUtNGY4Yy1hNjYzLWQyMjI5YzMyYTY3OAAuAAAAAABTq53BPRd5QLt7lLR88XvbAQAz0IL1wr3xRKNiSJ254HvqAASS-E4rAAA="
$URI = "https://graph.microsoft.com/beta/admin/exchange/mailboxes/$MailboxId/folders/$FolderID"
$ContentType = "application/json"
$Headers = @{"Authorization" = "Bearer "+ $AccessToken}
#0x3001 PR_DISPLAY_NAME
$Body = @"
{
"displayName": "Announcements Update",
"singleValueExtendedProperties": [
{
"id": "String 0x3001",
"value": "Announcements Update"
}
]
}
"@
$Result = Invoke-RestMethod -Method "PATCH" -Uri $URI -Body $Body -Headers $Headers -ContentType $ContentType
$Result
Delete mailboxFolder
This Example shows you how to delete a Mailbox Folder.
Permission type | Least privileged permissions | Higher privileged permissions |
---|---|---|
Delegated (work or school account) | MailboxFolder.ReadWrite | Not available. |
Delegated (personal Microsoft account) | Not supported. | Not supported. |
Application | MailboxFolder.ReadWrite.All | Not available. |
###############################################################################
# Delete mailboxFolder
# https://learn.microsoft.com/en-us/graph/api/mailbox-delete-folders?view=graph-rest-beta&tabs=http
###############################################################################
#DELETE /admin/exchange/mailboxes/{mailboxId}/folders/{mailboxFolderId}/$ref
#DELETE /admin/exchange/mailboxes/{mailboxId}/folders/{mailboxFolderId}/childFolders/{mailboxFolderId}/$ref
$MailboxId = "MBX:18f5d451-048e-4f8c-a663-d2229c32a678@46bbad84-29f0-4e03-8d34-f6841a5071ad" #m.muster@icewolf.ch
$FolderId = "AAMkADE4ZjVkNDUxLTA0OGUtNGY4Yy1hNjYzLWQyMjI5YzMyYTY3OAAuAAAAAABTq53BPRd5QLt7lLR88XvbAQAz0IL1wr3xRKNiSJ254HvqAASS-E4rAAA="
$URI = "https://graph.microsoft.com/beta/admin/exchange/mailboxes/$MailboxId/folders/$FolderID"
$ContentType = "application/json"
$Headers = @{"Authorization" = "Bearer "+ $AccessToken}
$Result = Invoke-RestMethod -Method "DELETE" -Uri $URI -Headers $Headers -ContentType $ContentType
$Result
List childFolders
This Example shows you how to List the child Folders of a specific Mailbox Folder. You can use the Default Foldernames (Inbox, SentItems, Calendar, Contacts or the FolderID).
Permission type | Least privileged permissions | Higher privileged permissions |
---|---|---|
Delegated (work or school account) | MailboxFolder.Read | MailboxFolder.ReadWrite |
Delegated (personal Microsoft account) | Not supported. | Not supported. |
Application | MailboxFolder.Read.All | MailboxFolder.ReadWrite.All |
###############################################################################
# List childFolders
# https://learn.microsoft.com/en-us/graph/api/mailboxfolder-list-childfolders?view=graph-rest-beta&tabs=http
###############################################################################
#GET /admin/exchange/mailboxes/{mailboxId}/folders/{mailboxFolderId}/childFolders
$MailboxId = "MBX:18f5d451-048e-4f8c-a663-d2229c32a678@46bbad84-29f0-4e03-8d34-f6841a5071ad" #m.muster@icewolf.ch
$FolderId = ""
#$URI = "https://graph.microsoft.com/beta/admin/exchange/mailboxes/$MailboxId/folders/$FolderID/childFolders"
$URI = "https://graph.microsoft.com/beta/admin/exchange/mailboxes/$MailboxId/folders/Inbox/childFolders"
$ContentType = "application/json"
$Headers = @{"Authorization" = "Bearer "+ $AccessToken}
$Result = Invoke-RestMethod -Method "GET" -Uri $URI -Headers $Headers -ContentType $ContentType
$Result.Value
Item Management
List items
This Example shows you how to List the Items in a specific Folder. As you can see, you only get the ID of the Object and CreateDate, ModifyDate, type and Size. No Subject, no Body.
Permission type | Least privileged permissions | Higher privileged permissions |
---|---|---|
Delegated (work or school account) | MailboxItem.Read | Not available. |
Delegated (personal Microsoft account) | Not supported. | Not supported. |
Application | MailboxItem.Read.All | Not available. |
###############################################################################
# List items
# https://learn.microsoft.com/en-us/graph/api/mailboxfolder-list-items?view=graph-rest-beta&tabs=http
###############################################################################
#GET /admin/exchange/mailboxes/{mailboxId}/folders/{mailboxFolderId}/items
$MailboxId = "MBX:18f5d451-048e-4f8c-a663-d2229c32a678@46bbad84-29f0-4e03-8d34-f6841a5071ad" #m.muster@icewolf.ch
#$URI = "https://graph.microsoft.com/beta/admin/exchange/mailboxes/$MailboxId/folders/$FolderId/items"
$URI = "https://graph.microsoft.com/beta/admin/exchange/mailboxes/$MailboxId/folders/Inbox/items"
$ContentType = "application/json"
$Headers = @{"Authorization" = "Bearer "+ $AccessToken}
$Result = Invoke-RestMethod -Method "GET" -Uri $URI -Headers $Headers -ContentType $ContentType
$Result.Value
Get mailboxItem
This Example shows you how to get a specific Item in a specific Folder. You only get some meta Information about the Item.
Permission type | Least privileged permissions | Higher privileged permissions |
---|---|---|
Delegated (work or school account) | MailboxItem.Read | Not available. |
Delegated (personal Microsoft account) | Not supported. | Not supported. |
Application | MailboxItem.Read.All | Not available. |
###############################################################################
# Get mailboxItem
# https://learn.microsoft.com/en-us/graph/api/mailboxitem-get?view=graph-rest-beta&tabs=http
###############################################################################
#GET /admin/exchange/mailboxes/{mailboxId}/folders/{mailboxFolderId}/items/{mailboxItemId}
$MailboxId = "MBX:18f5d451-048e-4f8c-a663-d2229c32a678@46bbad84-29f0-4e03-8d34-f6841a5071ad" #m.muster@icewolf.ch
$FolderId = "AQMkADE4ZjVkNDUxLTA0OGUtNGY4Yy1hNjYAMy1kMjIBOWMzMmE2NzgALgAAA1OrncE9F3lAu3uUtHzxe9sBAIAjf8qBKDxLtlFnOlm0V04AAAIBDAAAAA==" #Inbox
$ItemId = "AAMkADE4ZjVkNDUxLTA0OGUtNGY4Yy1hNjYzLWQyMjI5YzMyYTY3OABGAAAAAABTq53BPRd5QLt7lLR88XvbBwCAI3-KgSg8S7ZRZzpZtFdOAAAAAAEMAAAz0IL1wr3xRKNiSJ254HvqAASNnpV6AAA="
$URI = "https://graph.microsoft.com/beta/admin/exchange/mailboxes/$MailboxId/folders/$FolderId/items/$ItemId"
$Headers = @{"Authorization" = "Bearer "+ $AccessToken}
$Result = Invoke-RestMethod -Method "GET" -Uri $URI -Headers $Headers -ContentType $ContentType
$Result
Get singleValueLegacyExtendedProperty
You still can’t get Items in the AssociatedItems Folder. But now you can get some MAPI Properties with the following Query.
Outlook extended properties overview
Format | Example | Description |
---|---|---|
“{type} {guid} Name {name}” | “String {8ECCC264-6880-4EBE-992F-8888D2EEAA1D} Name TestProperty” | Identifies a property by the namespace (the GUID) it belongs to, and a string name. |
“{type} {guid} Id {id}” | “Integer {8ECCC264-6880-4EBE-992F-8888D2EEAA1D} Id 0x8012” | Identifies a property by the namespace (the GUID) it belongs to, and a numeric identifier. |
“{type} {proptag}” | “String 0x4001” | Identifies a predefined property by its property tag. |
Permissions
Supported resource | Delegated (work or school account) | Delegated (personal Microsoft account) | Application |
---|---|---|---|
calendar | Calendars.Read | Calendars.Read | Calendars.Read |
contact | Contacts.Read | Contacts.Read | Contacts.Read |
contactFolder | Contacts.Read | Contacts.Read | Contacts.Read |
event | Calendars.Read | Calendars.Read | Calendars.Read |
group calendar | Group.Read.All | Not supported | Not supported |
group event | Group.Read.All | Not supported | Not supported |
group post | Group.Read.All | Not supported | Group.Read.All |
mailFolder | Mail.Read | Mail.Read | Mail.Read |
message | Mail.Read | Mail.Read | Mail.Read |
Outlook task | Tasks.Read | Tasks.Read | Not supported |
Outlook task folder | Tasks.Read | Tasks.Read | Not supported |
###############################################################################
# Get singleValueLegacyExtendedProperty
# https://learn.microsoft.com/en-us/graph/api/singlevaluelegacyextendedproperty-get?view=graph-rest-beta&tabs=http
###############################################################################
#GET /me/messages/{id}?$expand=singleValueExtendedProperties($filter=id eq '{id_value}')
#GET /users/{id|userPrincipalName}/messages/{id}?$expand=singleValueExtendedProperties($filter=id eq '{id_value}')
#GET /me/mailFolders/{id}/messages/{id}?$expand=singleValueExtendedProperties($filter=id eq '{id_value}')
$Mailbox = "a.bohren@icewolf.ch"
$MessageID = "AQMkADU4NGU4M2ViLWM5NjctNGI0YS05ZmJhLTIyADdmYWI0MjRkYmQARgAAAzqJ2GWaRBxKv-EJWOBGbRAHAEZu88iLm85MjHqnrJ10b8oAAAIgiwAAAcb9AhgmYESSPal9iQNu6wAGS204OwAAAA=="
$Headers = @{"Authorization" = "Bearer "+ $AccessToken}
#PR_MESSAGE_CLASS
$URI = "https://graph.microsoft.com/beta/users/$Mailbox/messages/$MessageID/?`$expand=singleValueExtendedProperties(`$filter=id eq 'string 0x001A')"
$Result = Invoke-RestMethod -Method "GET" -Uri $URI -Headers $Headers -ContentType $ContentType
$Result.singleValueExtendedProperties | fl
#DKIM Signature
$URI = "https://graph.microsoft.com/beta/users/$Mailbox/messages/$MessageID/?`$expand=singleValueExtendedProperties(`$filter=id eq 'String {00020386-0000-0000-C000-000000000046} Name dkim-signature')"
$Result = Invoke-RestMethod -Method "GET" -Uri $URI -Headers $Headers -ContentType $ContentType
$Result.singleValueExtendedProperties | fl
#MessageSize
$URI = "https://graph.microsoft.com/beta/users/$Mailbox/messages/$MessageID/?`$expand=singleValueExtendedProperties(`$filter=id eq 'Long 0x0E08')"
$Result = Invoke-RestMethod -Method "GET" -Uri $URI -Headers $Headers -ContentType $ContentType
$Result.singleValueExtendedProperties | fl
These Querys also work in Graph Explorer. Obviously, you will need to change the Emailadress and the ItemId.
#PR_MESSAGE_CLASS
https://graph.microsoft.com/beta/users/a.bohren@icewolf.ch/messages/AQMkADU4NGU4M2ViLWM5NjctNGI0YS05ZmJhLTIyADdmYWI0MjRkYmQARgAAAzqJ2GWaRBxKv-EJWOBGbRAHAEZu88iLm85MjHqnrJ10b8oAAAIgiwAAAcb9AhgmYESSPal9iQNu6wAGS204OwAAAA==/?$expand=singleValueExtendedProperties($filter=id eq 'string 0x001A')
#DKIM Signature
https://graph.microsoft.com/beta/users/a.bohren@icewolf.ch/messages/AQMkADU4NGU4M2ViLWM5NjctNGI0YS05ZmJhLTIyADdmYWI0MjRkYmQARgAAAzqJ2GWaRBxKv-EJWOBGbRAHAEZu88iLm85MjHqnrJ10b8oAAAIgiwAAAcb9AhgmYESSPal9iQNu6wAGS204OwAAAA==/?$expand=singleValueExtendedProperties($filter=id eq 'String {00020386-0000-0000-C000-000000000046} Name dkim-signature')
#MessageSize
https://graph.microsoft.com/beta/users/a.bohren@icewolf.ch/messages/AQMkADU4NGU4M2ViLWM5NjctNGI0YS05ZmJhLTIyADdmYWI0MjRkYmQARgAAAzqJ2GWaRBxKv-EJWOBGbRAHAEZu88iLm85MjHqnrJ10b8oAAAIgiwAAAcb9AhgmYESSPal9iQNu6wAGS204OwAAAA==/?$expand=SingleValueExtendedProperties($filter=id eq 'Long 0x0E08')
Export Mailbox Items
This Example shows you how to Export a Mailbox Item. You can add multipe ItemIds in one Query
Permission type | Least privileged permissions | Higher privileged permissions |
---|---|---|
Delegated (work or school account) | MailboxItem.ImportExport | Not available. |
Delegated (personal Microsoft account) | Not supported. | Not supported. |
Application | MailboxItem.ImportExport.All | Not available. |
###############################################################################
# mailbox: exportItems
# https://learn.microsoft.com/en-us/graph/api/mailbox-exportitems?view=graph-rest-beta&tabs=http
###############################################################################
# POST /admin/exchange/mailboxes/{mailboxId}/exportItems
# POST https://graph.microsoft.com/beta/admin/exchange/mailboxes/MBX:e0643f21@a7809c93/exportItems
$MailboxId = "MBX:584e83eb-c967-4b4a-9fba-227fab424dbd@46bbad84-29f0-4e03-8d34-f6841a5071ad" #a.bohren@icewolf.ch
$URI = "https://graph.microsoft.com/beta/admin/exchange/mailboxes/$MailboxId/exportItems"
$ContentType = "application/json"
$Headers = @{"Authorization" = "Bearer "+ $AccessToken}
$Body = @"
{
"itemIds": [
"AQMkADU4NGU4M2ViLWM5NjctNGI0YS05ZmJhLTIyADdmYWI0MjRkYmQARgAAAzqJ2GWaRBxKv-EJWOBGbRAHAEZu88iLm85MjHqnrJ10b8oAAAIgiwAAAcb9AhgmYESSPal9iQNu6wAGS204OwAAAA=="
]
}
"@
$Result = Invoke-RestMethod -Method "POST" -Body $Body -Uri $URI -Headers $Headers -ContentType $ContentType
$Result.Value | fl
#Save Data to File
$Result.value.data | Set-Content -Path "C:\Temp\data.txt"
Import Session
This Example shows you how to create a Import Session for a specific Mailbox. It will return you the ImportURL.
Permission type | Least privileged permissions | Higher privileged permissions |
---|---|---|
Delegated (work or school account) | MailboxItem.ImportExport | Not available. |
Delegated (personal Microsoft account) | Not supported. | Not supported. |
Application | MailboxItem.ImportExport.All | Not available. |
###############################################################################
# mailbox: createImportSession
# https://learn.microsoft.com/en-us/graph/api/mailbox-createimportsession?view=graph-rest-beta&tabs=http
###############################################################################
# POST /admin/exchange/mailboxes/{mailboxId}/createImportSession
$MailboxId = "MBX:18f5d451-048e-4f8c-a663-d2229c32a678@46bbad84-29f0-4e03-8d34-f6841a5071ad" #m.muster@icewolf.ch
$URI = "https://graph.microsoft.com/beta/admin/exchange/mailboxes/$MailboxId/createImportSession"
$Headers = @{"Authorization" = "Bearer "+ $AccessToken}
$Result = Invoke-RestMethod -Method "POST" -Uri $URI -Headers $Headers
$ImportURL = $Result.importUrl
$ImportURL
Import Mailbox Item
This Example shows you how to Import a Mailbox Item to a Mailbox.
Permission type | Least privileged permissions | Higher privileged permissions |
---|---|---|
Delegated (work or school account) | MailboxItem.ImportExport | Not available. |
Delegated (personal Microsoft account) | Not supported. | Not supported. |
Application | MailboxItem.ImportExport.All | Not available. |
###############################################################################
# mailbox: Import Mailbox Item
#https://learn.microsoft.com/en-us/graph/import-exchange-mailbox-item
###############################################################################
#POST https://outlook.office365.com/api/gbeta/Mailboxes('MBX:e0643f21@a7809c93')/importItem?authtoken=eyJhbGciOiJSUzI1NiIsImtpZCI6IjFTeXQ1b
$MailboxId = "MBX:18f5d451-048e-4f8c-a663-d2229c32a678@46bbad84-29f0-4e03-8d34-f6841a5071ad" #m.muster@icewolf.ch
$FolderId = "AAMkADE4ZjVkNDUxLTA0OGUtNGY4Yy1hNjYzLWQyMjI5YzMyYTY3OAAuAAAAAABTq53BPRd5QLt7lLR88XvbAQAz0IL1wr3xRKNiSJ254HvqAAK-yWB4AAA=" #Sub5_Demo
$Content = Get-Content -Path "C:\Temp\data.txt"
$Body = @"
{
"FolderId": "$FolderID",
"Mode": "create",
"Data": "$Content"
}
"@
$Result = Invoke-RestMethod -Method "POST" -Uri $ImportURL -Body $Body -ContentType "application/json" #-Headers $Headers
$Result | fl
An Email has been restored to another Mailbox.
Summary
I’ve explained an tested how to use the public preview of the Exchange Online Export-Import Graph API. It’s a welcome change and i guess a lot of 3rd Party Applications specialized in this Field have waited on these Features. I guess, we will see 3rd Party Applications will adopt these API’s and integrate it in theyr solutions.
As you can see everything is based on FolderId and ItemId. An Application has to build the Folder hierarchy and Export each Item in each folder. In case of a Restore into a new or diffrent Mailbox, the challenge is to create the Mailbox Folder hierarchy and have a translation Table between the old and new FolderId’s.
Another concern is the Performance of the API. One comment pointed out, that in EWS there are 27 concurrent connections allowed in Exchange Online in Graph there are only 4. I guess until the GA Release the Throttling will have sorted out.
Regards
Andres Bohren