Using the Exchange 2010 Mailbox Export features for Mass Exports to PST files

In Exchange 2007 SP1 thru to Exchange 2010 RTM, the Export-Mailbox command was the replacement for the once-familiar ExMerge utility when it came to exporting mailboxes to PST files.

The main problem with Export-Mailbox for most Exchange administrators is the requirement for Outlook – either on a 32-bit machine with Management Tools for Exchange 2007, or on a 64-bit machine for Exchange 2010. All in all, it wasn’t ideal and certainly didn’t facilitate scripted mailbox exports.

Thankfully, with Exchange 2010 SP1, SP2 and SP3, Export-Mailbox is going the way of the dodo and new cmdlets for Mailbox imports and exports are available. Just like the New-MoveRequest cmdlet, the new import/export command use the Mailbox Replication Service to perform the move via one of the Client Access Servers giving performance benefits, such as ensuring the PST transfer doesn’t have to go via the machine with the Exchange Management Tools/Outlook installed, as was the case previously.

The main aim of this post is to give you an overview of how to use the new mailbox export cmdlets, and then show you how to put them to practical use, both at the command line and with a scheduled task for brick-level backups.

Getting it set up

The basic requirements for using the new feature are pretty straightforward. You need to use an account that’s a member of the organisational management groups, and have the “Mailbox Import Export” role assignment assigned to you or a role group you’re a member of. As the export is done at a CAS server (and if you’ve multiple CAS servers you can’t specify which one in each site will be used) you can’t specify a local drive letter and path – you must specify a UNC path to a network share that the “Exchange Trusted Subsystem” group has read/write access to.

Step One

Create a share on a server, and grant Exchange Trusted Subsystem read/write permission. In this example I’m using a share called Exports on a test server called Azua in my lab environment:

image

Step Two

Next, you’ll need to grant a user, or group, the Mailbox Import Export role assignment. You can do this using the Exchange Management shell with a single command. In this example, I’m granting my lab domain’s Administrator user the role assignment:

image


New-ManagementRoleAssignment –Role “Mailbox Import Export” –User AD\Administrator

After you’ve done this, close and re-open the Exchange Management shell, and you’re ready to go!

Exporting a Mailbox

At it’s simplest, use the New-MailboxExportRequest command with the –Mailbox parameter, to specify the mailbox to export along with the –FilePath parameter, to specify the PST file to create and export data to, e.g:

image


New-MailboxExportRequest -Mailbox Administrator -FilePath "\\AZUA\Exports\Administrator.pst"

In addition, there are some other useful options – such as –BatchName, which allows grouping of requests together, and –ContentFilter, which allows only certain content to be exported to the PST – useful for discovery purposes.  As usual, use the Get-Help New-MailboxExportRequest –detailed command to review the full plethora of options.

After submission of your requests, you can check progress, including the percentage complete, with the two Get-MailboxExportRequest and the Get-MailboxExportRequestStatistics commands. Pipe the former into the latter to get a listing:

image


Get-MailboxExportRequest | Get-MailboxExportRequestStatistics

After the requests complete, you can remove the requests in a similar fashion, using the Remove-MailboxExportRequest command:

image

Get-MailboxExportRequest | Remove-MailboxExportRequest

Performing mass exports

One benefit of Powershell is it’s very easy to put together commands enabling mass-exports of PST data with only a few commands. If you really wanted to, you could even use a Powershell script as a secondary brick-level backup!

The Basics

So to check out how to do this, let’s look at it’s simplest – backing up all the mailboxes (assuming it’s a full Exchange 2010 environment) to a single share:

image

foreach ($i in (Get-Mailbox)) { New-MailboxExportRequest -Mailbox $i -FilePath "\\AZUA\Exports\$($i.Alias).pst" }

In the above example, we’re simply performing a for-each loop through each mailbox and creating a new Mailbox Export Request, using the alias to build the name for the PST.

But – what if we’re in a mixed environment, and only want to target the Exchange 2010 mailboxes?

image

foreach ($i in (Get-Mailbox | Where {$_.ExchangeVersion.ExchangeBuild.Major -eq 14})) { New-MailboxExportRequest -Mailbox $i -FilePath "\\AZUA\Exports\${$i.Alias).pst" }

In this example above, now, we’ve added a clause to only select the mailboxes where the Exchange Major Build is 14 – Exchange 2010. Simple!

Moving on from such wide-targeting, you may want to target just a pre-defined list, using a CSV file. To do this, simply create a CSV file with the column “Alias”, and list the Mailbox alias fields you wish to export. Then, using the Import-CSV command we can use this CSV file to create the requests:

image

foreach ($i in (Import-Csv .\exports.csv)) { New-MailboxExportRequest -Mailbox $i.Alias -FilePath "\\AZUA\Exports\$($i.Alias).pst" }

Performing Mass Exports as a scheduled task

Now you’ve seen the basics of how easy it is to perform mass mailbox exports using the New-MailboxExportRequest command, I’ll finish off with a final example showing how to use this mass export feature as part of a scheduled task.

This script is aimed at backing up all the mailboxes on a single database, or a single server. After creating the requests, it waits for the requests to complete then, if you’ve specified a report directory, it will write reports showing completed and incomplete (i.e. failed!) requests. Finally it removes the requests it created.

To use the script, you need to alter the config section and specify either a server or a database, a share to export to, a share to write a report to after the process has completed and you can choose whether to remove each mailbox’s associated PST file or leave as-is at each export – merging the contents.

You’ll see the content of the script below and at the bottom of the post I’ve zipped it up along with a bootstrap CMD file you could use when setting up a schedule task. As always – use at your own risk and test out in your lab environment first. Happy Exporting!


# Exchange 2010 SP1 Mailbox Export Script
# Steve Goodman. Use at your own risk!

###############
# Settings #
###############

# Pick ONE of the two below. If you choose both, it will use $Server.
$Server = “server”
$Database = “”

# Share to export mailboxes to. Needs R/W by Exchange Trusted Subsystem
# Must be a UNC path as this is run by the CAS MRS service.
$ExportShare = “\\server\share”

# After each run a report of the exports can be dropped into the directory specified below. (The user that runs this script needs access to this share)
# Must be a UNC path or the full path of a local directory.
$ReportShare = “\\server\share”

# Shall we remove the PST file, if it exists beforehand? (The user that runs this script needs access to the $ExportShare share)
# Valid values: $true or $false
$RemovePSTBeforeExport = $false

###############
# Code #
###############

if ($Server)
{
if (!(Get-ExchangeServer $Server -ErrorAction SilentlyContinue))
{
throw “Exchange Server $Server not found”;
}
if (!(Get-MailboxDatabase -Server $Server -ErrorAction SilentlyContinue))
{
throw “Exchange Server $Server does not have mailbox databases”;
}
$Mailboxes = Get-Mailbox -Server $Server -ResultSize Unlimited
} elseif ($Database) {
if (!(Get-MailboxDatabase $Database -ErrorAction SilentlyContinue))
{
throw “Mailbox database $Database not found”
}
$Mailboxes = Get-Mailbox -Database $Database
}
if (!$Mailboxes)
{
throw “No mailboxes found on $Server”
}

if (!$Mailboxes.Count)
{
throw “This script does not support a single mailbox export.”
}

# Pre-checks done

# Make batch name
$date=Get-Date
$BatchName = “Export_$($date.Year)-$($date.Month)-$($date.Day)_$($date.Hour)-$($date.Minute)-$($date.Second)”

Write-Output “Queuing $($Mailboxes.Count) mailboxes as batch ‘$($BatchName)'”

# Queue all mailbox export requests
foreach ($Mailbox in $Mailboxes)
{

if ($RemovePSTBeforeExport -eq $true -and (Get-Item “$($ExportShare)\$($Mailbox.Alias).PST” -ErrorAction SilentlyContinue))
{
Remove-Item “$($ExportShare)\$($Mailbox.Alias).PST” -Confirm:$false
}
New-MailboxExportRequest -BatchName $BatchName -Mailbox $Mailbox.Alias -FilePath “$($ExportShare)\$($Mailbox.Alias).PST”
}

Write-Output “Waiting for batch to complete”

# Wait for mailbox export requests to complete
while ((Get-MailboxExportRequest -BatchName $BatchName | Where {$_.Status -eq “Queued” -or $_.Status -eq “InProgress”}))
{

sleep 60
}

# Write reports if required
if ($ReportShare)
{
Write-Output “Writing reports to $($ReportShare)”
$Completed = Get-MailboxExportRequest -BatchName $BatchName | Where {$_.Status -eq “Completed”} | Get-MailboxExportRequestStatistics | Format-List
if ($Completed)
{
$Completed | Out-File -FilePath “$($ReportShare)\$($BatchName)_Completed.txt”
}
$Incomplete = Get-MailboxExportRequest -BatchName $BatchName | Where {$_.Status -ne “Completed”} | Get-MailboxExportRequestStatistics | Format-List
if ($Incomplete)
{
$Incomplete | Out-File -FilePath “$($ReportShare)\$($BatchName)_Incomplete_Report.txt”
}
}

# Remove Requests
Write-Output “Removing requests created as part of batch ‘$($BatchName)'”
Get-MailboxExportRequest -BatchName $BatchName | Remove-MailboxExportRequest -Confirm:$false

Command file contents:

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command ". 'c:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1'; Connect-ExchangeServer -auto; .\MassExport.ps1"

Download as ZIP

278 thoughts on “Using the Exchange 2010 Mailbox Export features for Mass Exports to PST files

  1. Pingback: Export Pst File From Exchange | OutlookRecoveryGuide.org

  2. Pingback: Script To Import Pst Files Into Exchange 2010 | OutlookRecoveryGuide.org

  3. Pingback: Import Pst File Exchange 2010 Sp2 | OutlookRecoveryGuide.org

  4. Pingback: Exchange 2010 Pst File Export | OutlookRecoveryGuide.org

  5. Pingback: Export Pst Exchange 2007 64 Bit | OutlookRecoveryGuide.org

  6. Pingback: Export Outlook 2010 Pst To Windows Live Mail | OutlookRecoveryGuide.org

  7. Pingback: Export Pst File From Exchange Server 2003 | OutlookRecoveryGuide.org

  8. Pingback: Export Pst Exchange 2007 Sp3 | OutlookRecoveryGuide.org

  9. Pingback: Export To Pst Outlook 2010 Powershell | OutlookRecoveryGuide.org

  10. Hi Steve,

    Great article by the way.

    I am getting the error “Unable to open PST file ‘\\servername\share\file.pst’. Error details: Access to the path ‘\\servername\share\file.pst’. is denied.

    It looks like there’s a permissions issue here and I’ve done some digging around to see what account or group to give permission to but I’m getting nowhere.

    Please help.

    Thanks,
    Ron

    • Grant access to Exchange Trusted Subsystem. I believe it’s mentioned in help for the New-MailboxExportRequest cmdlet.

  11. Hello, this script is great but i have a question. Can you use the foreach CSV to select particular mailboxes with the massexport script? Where would i add in the foreach command for this to work. I have my CSV file and have tested it working on a one off export.

    Cheers
    Neil

  12. Thanks so much for this article. Worked perfectly for me. Why Microsoft took away a great tool like ExMerge I’ll never know.

  13. Hello all, I’m using this useful script in a Small Business Server 2011 standard environment (Exchange 2010).
    It happens a strange thing. The script sometimes works correctly but often , instead the “full” size pst files , I get all files of 265 kb. I scheduled this script to run every day at same time so I think the problem is not time related.
    Sometimes, even after a “faulty” execution, if I run the scheduled task manually it completes correctly.. but sometimes not. The script is configured to delete existent files before export.

    In the meanwhile no other things are changed (I’m the administrator) so I don’t understand what is causing this issue.

    Any idea ?

    Thank you very much in advance.

Leave a Reply