Microsoft 365

Import PST files to Exchange Online with network upload and AzCopy

Bulk-import PST files into Exchange Online mailboxes and archives with the Microsoft Purview Import service: SAS URL, AzCopy upload, mapping CSV, filtering and retention hold.

13 min read
On this page

To bulk-import PST files into Exchange Online, create an import job in the Microsoft Purview portal under Data lifecycle management > Microsoft 365 > Import, copy the network upload SAS URL it gives you, and upload the PST files with azcopy.exe copy "<source folder>" "<SAS URL>". You then submit a CSV mapping file that tells the Import service which mailbox (primary or archive) each PST goes to, let the service analyze the data, optionally filter it, and start the import. Network upload is free, needs no Azure subscription of your own, and imports each PST-to-mailbox pair in parallel.

Who this is for and what you will have at the end

This guide is for Microsoft 365 and Exchange Online administrators who need to load a set of PST files into user mailboxes: archived mail from file shares, exports from a legacy system, or PSTs collected from departing users. It covers the network upload method only. If your source is a live mail system, a mailbox migration is usually the better tool; the Google Workspace to Microsoft 365 migration guide covers that path.

By the end you will have:

  • A role group that can create import jobs without using Global Administrator.
  • Your PST files uploaded to the Microsoft-provided Azure Storage location for your tenant.
  • A validated mapping CSV and a running import job.
  • A plan for the retention hold that the Import service turns on after the import.

How network upload works and what limits apply

Network upload copies your PST files to a temporary Azure blob container named ingestiondata in the same regional datacenter as your tenant. The Microsoft 365 Import service then reads the files from that container and writes the content into the target mailboxes. You never get a storage account of your own; access is through a Shared Access Signature (SAS) URL that is unique to your organization.

The limits that matter when you plan the batches:

ItemLimit or behavior
Upload toolAzCopy only. Azure Storage Explorer can list files but can't upload or modify them.
PST file sizeUpload files no larger than 20 GB; larger files can affect import performance.
File namesEach PST file must have a unique name.
Mapping fileMaximum 500 rows. Use several mapping files and jobs for more PSTs.
Item sizeItems larger than 150 MB are skipped.
Folder depthPST files with 300 or more levels of nested folders can't be imported.
Archive targetOnly the main archive is filled, up to 100 GB per import. Auto-expanding archive storage isn't targeted.
Import rateAbout 24 GB per day per mailbox. Not guaranteed.
ParallelismDifferent PST/mailbox pairs import in parallel; several PSTs to the same mailbox import one at a time.
Retention of uploadsFiles are deleted 30 days after the most recent import job was created, if no jobs are in progress.
PST formatANSI and Unicode, from Outlook 2007 and later.
Targets not supportedPublic folders and Microsoft 365 groups.

Two of these shape the whole project. The 20 GB guidance means you should split very large PSTs before upload. The 100 GB archive limit means that if a user's archive needs more than that, you split the data across several imports and leave time for the archive to auto-expand between them.

Prerequisites

Assign the import roles

To create import jobs you need the Mailbox Import Export role and the Mail Recipients role in Exchange Online, or the Global Administrator role. No role group has Mailbox Import Export assigned by default. Microsoft recommends the least-privileged option, so create a dedicated role group in Exchange Online PowerShell:

Import-Module ExchangeOnlineManagement
Connect-ExchangeOnline -UserPrincipalName admin@contoso.com
 
New-RoleGroup -Name "PST Import" -Roles "Mailbox Import Export", "Mail Recipients" -Members admin@contoso.com

Without these roles you can't open the Import page in the Purview portal.

Prepare the source and the target mailboxes

  • Put the PST files in a file share, on a file server, or in an Azure Storage location that your organization manages. AzCopy uploads every PST in the source folder, so stage only the files for this batch.
  • Rename files so every name is unique, and note the exact case of each name. The mapping file is case-sensitive.
  • If you will set IsArchive to TRUE, enable the archive mailbox for those users first. If the archive isn't enabled, the import for that user fails (other users in the job aren't affected).
  • For an inactive mailbox, collect its ExchangeGuid, because the mapping file needs the GUID instead of the email address:
Get-Mailbox annb@contoso.com -InactiveMailboxOnly | Format-List ExchangeGuid

When an active mailbox and a soft-deleted or inactive mailbox share the same address, use the GUID to identify the target uniquely. For active mailboxes use Get-Mailbox <identity> | Format-List ExchangeGuid, and for soft-deleted mailboxes add -SoftDeletedMailbox.

Step 1: Copy the SAS URL and download AzCopy

  1. Sign in to the Microsoft Purview portal at https://purview.microsoft.com with an account that has the import roles.
  2. Go to Data lifecycle management > Microsoft 365 > Import.
  3. On the Import tab, select New import job.
  4. Enter a job name using lowercase letters, numbers, hyphens and underscores only. Uppercase letters and spaces aren't allowed. Select Next.
  5. On Do you want to upload or ship data?, select Upload your data, then Next.
  6. On the Import data page, select Show network upload SAS URL, then Copy to clipboard, and save the URL somewhere protected.
  7. Select Download Azure AzCopy. This is a standalone executable with nothing to install.

Treat the SAS URL like a password. It grants write access to your organization's upload container. Microsoft supports only the AzCopy version linked from this page (also available at https://aka.ms/downloadazcopylatest) with the documented syntax.

You only do this step once. For later batches, reuse the SAS URL and start again at Step 2.

Step 2: Upload the PST files with AzCopy

Open a Command Prompt, change to the folder that holds azcopy.exe, and run:

azcopy.exe copy "\\FILESERVER01\PSTs" "https://<account>.blob.core.windows.net/ingestiondata?<SAS token>"

Rules for the command:

  • The source must be a directory or an Azure Storage location, not a single PST file. Every PST in the source is uploaded.
  • Surround both the source and the SAS URL with double quotation marks.
  • --recursive uploads PSTs in subfolders too. Files in subfolders end up with a different path in the container, and you must use that exact path in the mapping file.
  • If the source is a general-purpose v2 storage account that supports access tiers, add --s2s-preserve-access-tier=false.
  • If you put the SAS URL in a batch file, escape % as %% and & as ^&.

To keep batches apart, add a subfolder after ingestiondata in the destination URL:

azcopy.exe copy "\\FILESERVER01\PSTs\Finance" "https://<account>.blob.core.windows.net/ingestiondata/Finance?<SAS token>"

Status messages show progress, and a final message reports the number of files uploaded. Save the working command line in the same protected place as the SAS URL so the next batch only needs a new source path.

Optional: check the upload with Azure Storage Explorer

Azure Storage Explorer helps you confirm the exact names and paths before you build the CSV. In the Connect to Azure Storage dialog, choose Blob container, then Shared access signature (SAS), and paste the SAS URL under Blob container SAS URL. The display name fills in as ingestiondata. When you finish, right-click ingestiondata and select Detach; otherwise the next attach attempt fails. You can't delete uploaded files from here, and an attempt returns a permissions error.

Step 3: Build the mapping CSV

Download the PST Import mapping file template from the Import documentation and keep its header row exactly as it is, including the SharePoint columns the Import service ignores:

Workload,FilePath,Name,Mailbox,IsArchive,TargetRootFolder,ContentCodePage,SPFileContainer,SPManifestContainer,SPSiteUrl
Exchange,,annb.pst,annb@contoso.com,FALSE,/,,,,
Exchange,,annb_archive.pst,annb@contoso.com,TRUE,,,,,
Exchange,Finance,donh.pst,donh@contoso.com,FALSE,/ImportedPst,,,,
ColumnWhat to put in it
WorkloadExchange for mailbox imports.
FilePathBlank if you uploaded to the container root; otherwise the subfolder name, such as Finance. Never include ingestiondata. Case-sensitive.
NameThe PST file name exactly as uploaded, including case. Must be unique within the job.
MailboxThe target's email address, or the ExchangeGuid for inactive or ambiguous mailboxes.
IsArchiveFALSE or blank for the primary mailbox, TRUE for the archive.
TargetRootFolderBlank creates a folder named Imported at the root. / merges into the existing folder structure (Inbox into Inbox). /FolderName imports under that folder.
ContentCodePageOptional code page for ANSI PSTs from double-byte languages, for example 932 for Japanese.
SPFileContainer, SPManifestContainer, SPSiteUrlLeave blank.

The choice of TargetRootFolder matters for duplicates. The Import service stamps each imported item with the PST item's EntryId and skips items it has already imported, but only within the same target folder. Reimporting the same PST to a different TargetRootFolder imports everything again, and items that already exist natively in the mailbox can be duplicated on first import. Run a small test batch before you settle on a value.

For a user whose primary mailbox is still on-premises in a hybrid deployment, you can import into the cloud archive by setting IsArchive to TRUE and using the on-premises mailbox address.

Step 4: Create the import job

  1. In Data lifecycle management > Microsoft 365 > Import, select New import job, name it, and choose Upload your data.
  2. On the Import data page, select I'm done uploading my files and I have access to the mapping file, then Next.
  3. Select Select mapping file, choose your CSV, and select Validate. The file name turns green when it passes. If it fails, select View log for a per-row error report.
  4. Accept the terms and conditions, select Save, then Close.

The job appears with the status Analysis in progress. Select Refresh until it changes to Analysis completed.

Step 5: Filter the data and start the import

Select the job and choose Import to Microsoft 365. The Filter your data page shows what the analysis found, including the age of the items.

  • No, I want to import everything: select Next, then Import data.
  • Yes, I want to filter it before importing: select Next, then More filtering options to set:
    • Age: import only items newer than the selected age. Age buckets come from the year of each item's sent or received date.
    • Type: clear message types you don't want. The Other category (journal entries, faxes, out-of-office templates, recall reports and similar) can't be excluded.
    • Users: exclude messages where specific SMTP addresses appear in the From, To or Cc fields. The data insights don't reflect this filter, but it's applied during the import.

Select Apply, review the summary, and select Import data. When every PST has finished, the job status is Complete.

Verification

  • Open the job in the Import list. The status flyout shows the status of each PST file in the mapping file and any filter settings.
  • Check that the target folder exists in the user's mailbox or archive and that item counts look reasonable. Message metadata such as sent and received dates and recipients is preserved.
  • Check the receive size limit. If a PST contained an item larger than 35 MB, the Import service raises MaxReceiveSize on that mailbox to 150 MB:
Get-Mailbox annb@contoso.com | Format-List MaxReceiveSize, RetentionHoldEnabled

Handle the retention hold

After an import, the Import service sets RetentionHoldEnabled to True on the mailbox for an indefinite period. The Managed Folder Assistant then doesn't expire or archive items in the user-visible folders, which protects old imported mail from a deletion or archive policy that would otherwise act on it immediately. Items in the Recoverable Items folder are still processed.

Decide how to end it. Either turn it off when users have had time to sort their mail:

Set-Mailbox annb@contoso.com -RetentionHoldEnabled $false

or leave it on and set an end date:

Set-Mailbox annb@contoso.com -EndDateForRetentionHold 12/31/2026

The date uses the short date format from the Regional Options of the computer running the command (the example assumes MM/dd/yyyy). RetentionHoldEnabled stays True after that date, but MRM starts processing the mailbox normally, so don't use the property alone to judge whether a hold is still in effect.

A third option is to lengthen the retention age in the policy assigned to the mailbox first and then remove the hold. To list every mailbox still on retention hold:

Get-Mailbox -ResultSize Unlimited | Where-Object {$_.RetentionHoldEnabled -eq $true} |
    Format-Table Name, RetentionPolicy, RetentionHoldEnabled -AutoSize

If imported mail later pushes users toward their quotas, the Recoverable Items folder full guide explains how holds and retention interact with mailbox storage.

Troubleshooting

SymptomCauseFix
Mapping file fails validationMore than 500 rows, a changed header row, or a malformed valueRead View log, keep the template header, split into several CSVs and jobs.
A PST fails while others succeedName or FilePath case doesn't match the uploaded fileCopy names and paths from Storage Explorer and match case exactly.
Archive import fails for one userIsArchive is TRUE but the archive isn't enabledEnable the archive and create a new job for that PST.
A user needs more than 100 GB imported to the archiveA single import fills only the main archive, up to 100 GBSplit the data across several imports and allow time for auto-expansion between them.
File list for an old job is emptyUploads are deleted 30 days after the last job was createdUpload again and create a new job within 30 days.
Large items missing after importItems over 150 MB are skippedExpected; the Exchange Online message size limit applies.
Duplicate items after reimportDifferent TargetRootFolder, or native items without the import stampReimport only to the same target folder; test first.
Error on the next Storage Explorer attachPrevious session wasn't detachedDetach ingestiondata after each use.
Problems creating a job in the portalKnown issue at 1366 x 768 screen resolutionChange the screen resolution and create the job again.

Checklist

  • Create a role group with Mailbox Import Export and Mail Recipients.
  • Stage PSTs under 20 GB with unique names; enable archives where needed.
  • Copy and protect the SAS URL; download the supported AzCopy build.
  • Upload a directory with azcopy.exe copy, using a subfolder per batch.
  • Build the mapping CSV with exact case, at most 500 rows, and a tested TargetRootFolder.
  • Create the job within 30 days of upload, validate, filter if needed, and start it.
  • Verify per-PST status, then remove or schedule the end of the retention hold.

References

Questions people ask

Is PST import with network upload free in Microsoft 365?

Yes. Microsoft lists the network upload method as free and available under all commercial licensing agreements, and it doesn't require your organization to have its own Azure subscription. Drive shipping is the method that has costs and is limited to Enterprise Agreement customers.

Which roles do I need to create a PST import job?

You need the Mailbox Import Export role and the Mail Recipients role in Exchange Online, or the Global Administrator role. No role group has Mailbox Import Export by default, so add it to Organization Management or create a dedicated role group that holds both roles.

How long do uploaded PST files stay in the Azure storage area?

If no import jobs are in progress, all PST files in the ingestiondata container are deleted 30 days after the most recent import job was created. That means you must create the import job within 30 days of uploading the files. You can't delete uploaded PST files yourself.

Can I import PST files into a public folder or a Microsoft 365 group?

No. The PST Import service doesn't support importing PST files to public folders or to Microsoft 365 (unified) groups. You can import to user mailboxes, archive mailboxes, cloud archives for on-premises users and inactive mailboxes.

Exchange OnlineMicrosoft PurviewAzCopyPST import
  1. Recoverable Items folder full in Exchange Online: diagnose and fix

    Find out why a mailbox's Recoverable Items folder hit its quota, which hold is keeping the data, and how to free space with an archive, a retention tag or a reviewed hold change.

    Microsoft 36512 min read
  2. Calendar permissions in Exchange Online: Add-MailboxFolderPermission guide

    Share calendars, change the organization-wide Default permission and add calendar delegates in Exchange Online with Add-, Set- and Remove-MailboxFolderPermission, including localized folder names.

    Microsoft 3659 min read
  3. Configure ARC trusted sealers and Enhanced Filtering for an email gateway

    Stop SPF, DKIM and DMARC failures on mail that reaches Exchange Online through a third-party gateway by combining Enhanced Filtering for Connectors and ARC.

    Microsoft 36511 min read