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:
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:
1 | 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:
1 | 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:
1 | Get-MailboxExportRequest | Get-MailboxExportRequestStatistics |
After the requests complete, you can remove the requests in a similar fashion, using the Remove-MailboxExportRequest command:
1 | 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:
1 | 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?
1 | 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:
1 | 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!
1 2 | # 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:
1 | C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command ". 'c:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1'; Connect-ExchangeServer -auto; .\MassExport.ps1" |
Pingback: 閫佹枡鐒℃枡 Pathfinder 銉戙偣銉曘偂銈ゃ兂銉€銉?3way銉儱銉冦偗 3way 銉撱偢銉嶃偣銉愩儍銈?3way銉愩儍銈?銉堛兗銉堛儛銉冦偘 闃叉按 銉撱偢銉嶃偣 銉儱銉冦偗銈点儍銈?3way銉堛兗銉?銉栥
Hey Steve, your script is awesome. But instead I am trying to use my simplified script to export mailboxes for certain days irrespective of which day it runs. But its not working it always export whole mailbox.
$mailbox = “psingh”
$FromDate = (Get-Date).AddDays(-10).ToString(“MM/D/yyyy”)
$FromDate = “‘$($FromDate)'”
New-MailboxExportRequest -ContentFilter {(Received -ge $FromDate) -or (Sent -ge $FromDate)} -Mailbox $mailbox -FilePath “\\FileServer\EmailBackups\ExportTest\MonthTest2\Singh, Paramjot.pst”
Write-Host “Done.”
Script exports the mailbox of correct size when i entered the specific dates. Please suggest what I can do to make it working. Thanks
Great Information! Thanks for writing it up!
Thanks for sharing such a useful piece of Information.This will surely help those who are looking to export mailboxes with powershell cmdlets. But as you all know, executing powershell cmdlets to export mailboxes to PST is not everyone’s cup of tea and many times you can encounter errors while working with powershell scripts. Moreover, the export process with powershell cmdlets is quite time consuming and there is no surety that 100% data will get exported to a new PST.
So, I would recommend using Stellar EDB to PST as with this software even a layman can export mailboxes to PST easily and that too in a quick time without any hassle. For more info, visit http://www.stellarinfo.com/email-repair/edb-pst-converter.php
Hi, how can i export only disabled users from an specific OU?
Thank you a lot for the valuable article. I tried to apply the CSV file part and it looked like it writes the .pst file to the PST folder then deletes it. Is there anything to do?
Good Day Steve,
Is it possible to utilize this script to export PSTs from Archive Databases?
Hi,
i use the same command with -isarchive and it works.
foreach ($i in (Get-Mailbox)) { New-MailboxExportRequest -isarchive -Mailbox $i -FilePath “\\AZUA\Exports\$($i.Alias).pst” }
Thanks, it works perfectly!!!
Eres un crack! Gracias
Pingback: Export Pst File In Exchange 2007 - ORG.org
Pingback: Search-mailbox The Target Mailbox Or .pst File Path Is Required - ORG.org
Pingback: How To Export Pst From Exchange 2010 Sp2 - ORG.org
Pingback: Outlook 2010 Export Pst Script - ORG.org
Pingback: Export Pst File From Exchange | OutlookRecoveryGuide.org
Pingback: Script To Import Pst Files Into Exchange 2010 | OutlookRecoveryGuide.org
Pingback: Import Pst File Exchange 2010 Sp2 | OutlookRecoveryGuide.org
Pingback: Exchange 2010 Pst File Export | OutlookRecoveryGuide.org
Pingback: Export Pst Exchange 2007 64 Bit | OutlookRecoveryGuide.org
Pingback: Export Outlook 2010 Pst To Windows Live Mail | OutlookRecoveryGuide.org
Pingback: Export Pst File From Exchange Server 2003 | OutlookRecoveryGuide.org
Pingback: Export Pst Exchange 2007 Sp3 | OutlookRecoveryGuide.org
Pingback: Export To Pst Outlook 2010 Powershell | OutlookRecoveryGuide.org
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.
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
Thanks so much for this article. Worked perfectly for me. Why Microsoft took away a great tool like ExMerge I’ll never know.
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.