Using the Exchange 2010 SP1 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, 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:
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:
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:
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:
After the requests complete, you can remove the requests in a similar fashion, using the Remove-MailboxExportRequest command:
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:
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?
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:
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!
# 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:
July 23rd, 2010 - 01:37
Great write-up! You and Henrik are neck and neck!
http://www.msexchange.org/articles_tutorials/exchange-server-2010/management-administration/look-import-export-mailbox-improvements-exchange-2010-service-pack-1-part1.html
Did your server have multiple roles installed or just the mailbox role? there was a bug with multiple roles and import-mailbox in 2010 RTM.
July 23rd, 2010 - 07:04
Hi Mike,
This was going to be an post covering all the features but yep, Henrik is publishing a much better multi-part article therefore I thought I’d focus on just the mass-export features.
Good point about the roles. That’s the very reason I’ve been holding back on posting this article – the lab environment I started writing this against has CAS, HT, DAG all on seperate servers, and includes a CAS array in the mix, so I hit a similar bug to the one you mention. Good news is that it’s fixed in newer builds and should hopefully stay fixed for SP1 RTW!
If you are trying this now on SP1 beta, it should be fine on a multi-role test box though.
Steve
July 25th, 2010 - 23:23
nice post. thanks.
August 9th, 2010 - 14:41
Great post – I get this error:
Couldn’t connect to the source mailbox.
+ CategoryInfo : NotSpecified: (0:Int32) [New-MailboxExportRequest], RemoteTransientException
+ FullyQualifiedErrorId : B34FC71E,Microsoft.Exchange.Management.RecipientTasks.NewMailboxExportRequest
Do you know anything about this ?
August 9th, 2010 - 15:50
Yes. It’s a known big in the beta build and manifests itself mainly when there is a CAS array setup. It’s fixed in later builds and will be in RTW of SP1.
Easiest way to test out this feature before it’s released is to setup a multi-role server on it’s own. I can provide workaround steps if you need tho.
Steve
August 19th, 2010 - 20:58
Please to post workarround steps
August 19th, 2010 - 21:09
Hi Thomas,
The workaround is to get rid of the CAS array and replace it with a standalone CAS fronting the MDB.
This will be fixed in SP1 RTM though.
Steve
August 23rd, 2010 - 22:46
Hi Steve, I’m interested for a workaround, since I’m using CAS array in my lab.
Regards,
Andrija
August 23rd, 2010 - 23:24
Hi Andrija,
You have to remove the CAS array and replace it with a standalone CAS instead.
That’s not great – but SP1 when released doesn’t have this issue.
Steve
August 24th, 2010 - 14:03
Hi All,
I have a lab environment with the exact same problem. (Couldn’t connect to the source mailbox.)
My lab is build with a single server exchange installation. Anyone knows another couse for this error?
Regard,
Kees
August 24th, 2010 - 17:05
The cause is to do with Kerberos auth between MRS>CAS IIRC. If you have no CAS array enabled (you can still have enabled on single server) then you may have to hold tight for SP1 RTM
August 29th, 2010 - 20:28
Hiya,
If you haven’t already, upgrade to the SP1 RTM version that was released the other day
S
September 8th, 2010 - 10:22
i am using Exchange 2010 SP1 RTM and receiving following error:
Couldn’t connect to the source mailbox.
+ CategoryInfo : NotSpecified: (0:Int32) [New-MailboxExportRequest], RemotePermanentException
+ FullyQualifiedErrorId : DA7266AE,Microsoft.Exchange.Management.RecipientTasks.NewMailboxExportRequest
September 8th, 2010 - 22:14
Hi Abdul,
That’s strange. Is the mailbox you are exporting on an SP1 mailbox server?
Steve