If you are exporting mailboxes to PST files to upload to O365 for migration purposes, you may notice that as you begin the export mailbox process, some mailboxes may stall. For further complicate things, when the process starts again, it begins from zero percent, but the existing PST file is not wiped. Instead the restarted process begins to append data to the existing file. If your mailbox process stalls 4-5 times, you could end up with a PST file that’s 4-5 times larger than the mailbox!

This is usually due to excessive corruption on mailboxes or server disk I/O performance issues. Depending on your server, you may want to limit the export to fewer mailbox exports. You can check the perfmon disk I/O to gauge how many export processes can be concurrently run.

The script below, is simple in nature. It prompts for a mailbox name, the begins a PST file export of that mailbox. It periodically checks the status, showing you how far along it is. Once it’s done, it checks if that mailbox has an archive and if so, it will begin to export the archive file.

While the archive is being exported, the program exits, allowing you to run it again, while ensuring that you are only exporting a maximum of two mailboxes at the same time.

Copy and past the code to a text editor and save it as a PS1 extension. If you have a lot of mailboxes, you can further automate the process by creating a script to read the mailbox names from a CSV file and nestle the program below withing the routine.

# Slow server mailbox export helper, by Miguel Fra, Falcon IT Services


# $uname is the filed that holds the mailbox name, you will be prompted to enter a mailbox name

$uname = Read-Host "Enter mailbox username"

Write-Host "Starting mailbox export process for:" $uname


# Change the 'your server' field to your own server's UNC path

# Start the primary export

# The accept large data loss will allow the process to skip corrupted items and continue the export

$primaryRequest = New-MailboxExportRequest -Mailbox $uname -FilePath "\\yourserver\PST\$uname.pst" -AcceptLargeDataLoss -BadItemLimit 10000000

Write-Host "Started mailbox export for $uname. Waiting for completion..."

# Wait until export is completed (loop every 60 seconds) while showing % completed

do {
    $stats = Get-MailboxExportRequest -Mailbox $uname | Get-MailboxExportRequestStatistics
    $percent = $stats.PercentComplete
    $status = $stats.Status

    Write-Host ("{0}: {1}% complete - Status: {2}" -f (Get-Date -Format "HH:mm:ss"), $percent, $status)

    if ($percent -lt 100 ) {
        Start-Sleep -Seconds 60
    }
} until ($percent -ge 100 -or $status -in @('Completed', 'CompletedWithWarning', 'Failed'))

Write-Host "`nPrimary mailbox export completed for $uname with status: $status"


# --- Start Archive Export ---
Write-Host "Starting mailbox archive export for $uname..."

# Change the 'your server' field to your own server's UNC path

$archiveRequest = New-MailboxExportRequest -Mailbox $uname -IsArchive -FilePath "\\yourserver\PST\$uname.archive.pst" -AcceptLargeDataLoss -BadItemLimit 10000000

# Wait until archive export is completed (loop every 60 seconds)
do {
    $archStats = Get-MailboxExportRequest -Mailbox $uname | Get-MailboxExportRequestStatistics
    $archPercent = $archStats.PercentComplete
    $archStatus = $archStats.Status

    Write-Host ("{0}: Archive {1}% complete - Status: {2}" -f (Get-Date -Format "HH:mm:ss"), $archPercent, $archStatus)

    if ($archPercent -lt 100  ) {
        Start-Sleep -Seconds 60
    }
} until ($archPercent -ge 100 -or $archStatus -in @('Completed', 'CompletedWithWarning', 'Failed'))

Write-Host "`nArchive mailbox export completed for $uname with status: $archStatus"

Leave a comment

Your email address will not be published. Required fields are marked *

error: Sorry, copy/paste is disabled
Skip to content