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:
Related posts:



September 21st, 2011 - 21:29
Hi Steve,
I just tried using your script on an sbs 2011 machine running exchange 2010 but i get the following error.
File C:\Scripts\MassExport.ps1 cannot be loaded. The file C:\Scripts\MassExport.ps1 is not digitally signed. The script
will not execute on the system. Please see “get-help about_signing” for more details..
At line:1 char:122
+ . ‘c:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1′; Connect-ExchangeServer -auto; .\MassExport
.ps1 <<<<
+ CategoryInfo : NotSpecified: (:) [], PSSecurityException
+ FullyQualifiedErrorId : RuntimeException
Any ideas why this will not run?
Many Thanks,
James
September 21st, 2011 - 21:44
Hi James,
Try (from an administrator/elevated Powershell session):
Set-ExecutionPolicy Unrestricted
And then attempt to run the script.
Alternatively, if you want to be more secure:
Set-ExecutionPolicy RemoteSigned
Then open the file’s Zone.Identifier alternate data stream in notepad (with the quotes)
notepad “MassExport.ps1:Zone:Identifier”
And ensure the contents are similar to below:
[ZoneTransfer]
ZoneId=0
This should set the script so the OS thinks it originated locally (more info here http://blogs.msdn.com/b/powershell/archive/2007/03/07/how-does-the-remotesigned-execution-policy-work.aspx)
Steve
Steve
September 22nd, 2011 - 20:24
Ok so now the script gets past that error but then says the following
Security Warning
Run only scripts that you trust. While scripts from the Internet can be useful, this script can potentially harm your
computer. Do you want to run C:\Scripts\MassExport.ps1?
[D] Do not run [R] Run once [S] Suspend [?] Help (default is “D”): ?
D – Do not run the script from this publisher now, and continue to prompt me to run this script in the future.
R – Run the script from this publisher now, and continue to prompt me to run this script in the future.
S – Pause the current pipeline and return to the command prompt. Type exit to resume execution when you are done.
I can select run once but that would need to be done manually every time the script runs.
Any ideas how i could get around that?
September 28th, 2011 - 11:43
Hi James,
Another workaround is to copy and paste the contents of the script into a new, local .ps1 file.
Steve
November 14th, 2011 - 15:44
Hi Steve, creating a local ps1 file done the trick. Sorry it took so long to reply. Thank you for a great script!!
November 30th, 2011 - 23:24
Glad it works,
Steve
December 22nd, 2011 - 17:13
You need to run the following command to allow .ps1 scripts:
Set-ExecutionPolicy -RemoteSigned
September 22nd, 2011 - 11:49
The export script was just what I needed, It works perfect – thanks
September 28th, 2011 - 20:19
Thank you, men… Good job!
This is a great solucion for automatized backup using Windows Backup.
September 29th, 2011 - 23:39
Thanks, Glad you like it
Steve
October 18th, 2011 - 08:54
i need help regarding the export command. when i export any mail box more then 9 time. i got the error message is
“the name must unique per mailbox. there is not a default name available for a new request owned by mailbox”
when execute New-Mailboxexportrequest command , the show counter like this:
Name Mailbox export
——-
Mailbox-export
October 18th, 2011 - 09:03
i can not able to execute new-exportmailboxrequest command more than 9 time any mail box . just for remember that when we execute the command it show like this :
Name Mailbox Status
——- ——— ——–
Mailboxexport1 information about mailbox queued
after next time a repeate the same above command it will again come like :
Name Mailbox Status
——- ——— ——–
Mailboxexport2 information about mailbox queued
till
Name Mailbox Status
——- ——— ——–
Mailboxexport9 information about mailbox queued
all the above command execute fine.
My problem is when i try same command for more than 9 on any mailbox i got the error message like this:
“the name must unique per mailbox. there is not a default name available for a new request owned by mailbox.”
Your prompt reply very appreciate.
Thanks in advance
October 25th, 2011 - 20:34
Ali, I had the same problem. Need to run the command to get rid of the previous requests before running your new one:
Get-MailboxExportRequest | Remove-MailboxExportRequest -Confirm:$false
October 25th, 2011 - 20:32
Thanks!
October 26th, 2011 - 08:56
I got the mailbox to pst export function working great….
Since we also have a couple of important public folders, some containing mail, some containing shared contacts, etc… we would love to export those (all) public folders to PST to.
Can this also be done with the powershell script?
November 8th, 2011 - 00:29
Hiya,
This can’t currently be done with the mailbox export cmdlets using a script. The best suggestion for public folder database backup would be to use a proper third part backup utility or perhaps add another PF replica and dismount for file-level backup, then remount.
Steve
November 7th, 2011 - 11:29
Thanks for this script Works like a charm !!
November 8th, 2011 - 00:16
Cheers, glad it was useful!
Steve
November 23rd, 2011 - 00:18
Hi Steve, so following the conversation on the MSExchange list,
1. I dont think it will work to populate the $Server variable with more than one server (DAG partners, both active and passive mailbox server). Just wondering how this can be overcome without scheduling two separate scripts?
2. Polling exchange event log when the ps1 is run, I’m seeing quite a number of errors wrt: corrupted items during the mailboxexport operation. Will inserting a badlimit count work to stop this?
Thanks,
New-MailboxExportRequest -BatchName $BatchName -Mailbox $Mailbox.Alias -FilePath “$($ExportShare)\$($Mailbox.Alias).PST” -BadItemLimit 100
November 30th, 2011 - 23:35
Hi David,
Sorry for the delay with the reply.The script is rather basic when it comes to servers but if you have a specific requirement it could be modified. For example you could add the following at the top of the script:
$Servers=”server1″,”server2″
foreach ($Server in $Servers) {
and add the following at the end of the script:
}
The errors with corrupted items may be skipped with that option but I would investigate for an underlying cause, personally.
Steve
November 27th, 2011 - 09:40
Hi !
No matter how or how hard I try, I can´t get access to the Export-Mailbox command.
Im running a SBS2011, i have outlook 2010 x64 installed, and ive tried reinstalling the management tools .. What am I missing ?
I’ve tried elevated Powershell, adding users to the admin-accounts, trusted subsystem and on and on. The cmdlet still manages to stay hidden/gone.
November 30th, 2011 - 23:39
Hi Jesper,
The Export-Mailbox command is replaced in Exchange 2010 SP1 and above by the New-MailboxExportRequest command. Outlook is not required on the server. This guide should explain how to use the new cmdlets.
Steve
November 28th, 2011 - 20:38
Are you using an account that has the Mailbox Import Export role assigned to it?
November 30th, 2011 - 11:47
Thanks for the guide.
I’m having an issue, no matter what I do I can’t get the permissions right on the share I want to write to. The user I’m using for the export is a member of doman user, domain admin, Exchange Trusted Subsystem and Organization Managment. I have also added the Exchange Trusted Subsystem read write permissions to my share location.
I’m getting the ‘Access to the Path \\Server\Share\name.pst’ is denied error.
I know it’s something simple, any ideas? Thanks
November 30th, 2011 - 23:42
The user shouldn’t need the permissions as it doesn’t perform the move. The Exchange server itself (using the SYSTEM account) does. The Exchange server must be a member of that group so I would double check it is (it should be!) and double check the share permissions and share NTFS permissions. Also for troubleshooting, try allowing Everyone access.
Steve
December 3rd, 2011 - 09:26
Hi Steve,Thnks for the script
In my requirment, i have to create a script which export a single mailbox on daily basis and the exported pst name should be unique(pst format could be DD-MM-YY.pst). And after mailbox export the mails from the mailbox should be deleted automatically so that the same mails will not be exported in next day export. Can you please guide me in writing such script
December 12th, 2011 - 19:05
Hi,
I have a problem running the massexport.cmd as a scheduled task. When I execute the massexport.cmd manually, there is no problem and the mail export is running and populating the backup share. However, when running as a scheduled task, no data is getting updated. The change date of the PST-backup files are unchanged.
Do you have a tip on how to get this running as a scheduled task?
Thanks.
December 13th, 2011 - 12:02
Hey Steve Nice Script
But I have the same issue as Geir .
I Placed the 2 file in \v14\bin\ directory
Give domainadmins full security richts on the 2 files .
When i start the cmd file manualy is starts the script , but wen i try to start the cmd file from out the windows scheduler nothing happens.
December 13th, 2011 - 10:51
Hi,
Thanks a lot for the great help.
I’m trying to use the script to export all the mailbox in a specific database.
Can you please provide me with the required code
thanks a lot
December 18th, 2011 - 14:31
Hi
thanks for the script, we are using it since we started our migration, some months ago (took some times, not almost done). Anyway, everything went on well until some times (I can’t be precise). Now, whenever the script is ran (full admin rights), it starts, put about 150 mailboxes in queue and I got bunch of random errors like
“couldn’t connect to the source mailbox”
“Categorie info: Not Specified: (0:Int32) [new-mailboxexportrequest ], RemotePermanentException”
“FullyQualifiedErrorId : C2DA5FB1,Microsoft.Exchange.Management.RecipientTasks.NewMailboxExportRequest”
I can export about 150 mailboxes (on 300, currently) but that’s all.
please note: roles (CAS,HUB,MB) are installed on the same server, no DAG, just a legacy 2003 server still running, since we are in the process of migration. Script is ran from the server itself, to a local disk (through a share).
I tried to “set-executionpolicy unrestricted” (to be more permissive), but no luck.
I tried, then, to select my first database (I got 5 of them) rater than my server: now it put 200+ mailboxes in queue with no problem.
If I can’t fix the problem, I’ll workaround it with a foreach in the beginning of your script. It’s very strange, though.
I have tried this:
“- Editing the value of MaxTotalMovesPerMRS = “100″ to “500″ did the trick…”
via:
http://social.technet.microsoft.com/Forums/en-US/exchange2010/thread/c0cb3ed8-f964-4c63-acd2-344a26088d39
but it did not help either…
December 31st, 2011 - 12:06
HI Steve!
Is this scipt export online archive to pst?
thank you and Hapy New Year!
December 31st, 2011 - 20:06
It can but needs to be modified to do so
Steve
January 1st, 2012 - 16:21
Hi!
I add isArchive to this line:
New-MailboxExportRequest -BatchName $BatchName -Mailbox $Mailbox.Alias -FilePath “$($ExportShare)\$($Mailbox.Alias).PST” -IsArchive
February 1st, 2012 - 18:44
Yep, that sounds about right
Steve
December 31st, 2011 - 20:46
Hi there
I spent some times on some backups problems (symantec and exchange related) when I came across a strange problem: modifying some values in the MSExchangeMailboxReplication.exe.config (to allow more mailboxes to be exported at one go) messed my PST export
Do you think it could be related to my problem described above (see my previous comment)?
I am trying to get some information about how to use the MSExchangeMailboxReplication.exe.config file, because it seems very fussy…
thanks
January 4th, 2012 - 01:30
Hi
I add
#Add Exchange features.
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
Just under the Code section for Exchange 2010. Then you can run the script directly without errors.
Just running script now, Need to Mod to be schedule Task and also email results but should not be to hard.
Thanks
February 1st, 2012 - 18:43
Hi Craig,
Using that method will
a) Speed up the script!
b) Solve your problem
However it should be noted that only Remote PowerShell is supported by the Exchange team except in particular scenarios (like fixing RBAC)
Steve
January 12th, 2012 - 13:51
Thank you VERY much for the syntax to get this procedure completed. I spent a while trying this and variations of it to get the job done: Export-Mailbox -Identity user -PSTFolderPath d:\user.pst to no avail. I have bookmarked your site as VERY IMPORTANT
February 1st, 2012 - 18:35
Hi Jonathan,
Glad you found it useful!
Steve
January 19th, 2012 - 09:02
Great article, clear and helpful. Thanks Steve!
January 23rd, 2012 - 12:10
Problem with Export e-mails from journaling mailbox to pst file
Hello
I using Exchange 2010 SP1 RU5.
When I export e-mail messages from journaling mailbox to pst file, all e-mails are empty.
In journal mailbox I’ve checked e-mail.
This e-mail (journal report) include orginal e-mail message. This message include some body text and attachements.
When I open pst file and open this e-mail message (journal report) there is orginal e-mail message, but when i open it there is only attachement.
Do you know why body text was removed?
Thank you very much for help.
Tomasz
January 27th, 2012 - 11:43
I’m having the same issue with 2010 sp2, the emails have size to them but the body has nothing. Even when I look at these in OWA it’s the same
February 1st, 2012 - 18:26
Hi Tomasz,
To be frank, I don’t know. I’ve heard of a number of problems that the PST export facilities can have in different circumstances. If you have PSS it may be worth raising a call, so if its a bug it can be fixed.
Steve
January 27th, 2012 - 08:24
Problem With export Mailboxes from an Database.
When I Run the Script only 2 of 6 MAilboxes are Queued for export. Why are the other mailboxes are not exported.
THX
Jochen
February 1st, 2012 - 18:28
Hi Jochen,
I can’t say for sure. It might be worth attempting to export the mailboxes manually. In general this script seems to work well for a lot of people with few issues (most commonly getting the script running)
Steve
January 29th, 2012 - 11:55
Thank you very much Steve! Using the above script on two SBS 2011 servers now and it works great
/Tommie
February 1st, 2012 - 18:19
Cheers, glad you found it useful.
Steve
February 2nd, 2012 - 15:12
Hi, Steve.
Great work, and thank you for sharing.
I can export individual mailboxes just fine, but have a situation now where an OU hs been created and disabled user accounts placed into it.
They cannot be deleted until their individual mailboxes are exported to .pst files for use by HR if necessary.
My knowledge of scripting is right up there with my knowledge of rocket science, and I’m not up tosped on rocket science, either!
Is it possible to modify your script example so that it will export the mailboxes for all users of a specified OU within Active Directory, e.g. “Disbled,” for example
Thanks,
Bill