Skip to content

Instantly share code, notes, and snippets.

@shuuryou
Last active March 11, 2024 10:51
Show Gist options
  • Select an option

  • Save shuuryou/5ccede3a303cb53b34037e0359b05973 to your computer and use it in GitHub Desktop.

Select an option

Save shuuryou/5ccede3a303cb53b34037e0359b05973 to your computer and use it in GitHub Desktop.
Exchange Server 2010 mailbox export with splitting by year if the mailbox is too large.
# Exchange Server 2010 eats up extreme amounts of memory when exporting large
# mailboxes. This script attempts to provide a workaround by splitting exports
# of mailboxes that are larger than 10 GB into yearly chunks.
#
# This script will obviously create a few PSTs that are empty. You can easily
# spot these by their file size. Empty PSTs are 265 KB in size.
#
# It worked for my one-off use case, but is provided AS-IS and without any
# warranty or guarantees of correctness.
$startyear = 1999 # Email older than 25 years hopefully isn't relevant anymore
# The reason for not just going by the user's creation date
# is that the user may have content in their mailbox from
# before their creation date (someone gave them MSG files,
# they restored from someone else's email archive, etc.)
$destination = '\\server\exports\' # Where to store exports
############################################################################
function Wait-ForExportCompletion
{
param(
[Parameter(Mandatory = $true)]
$reqName
)
Write-Host "Exporting $reqName" -NoNewline
$req = Get-MailboxExportRequest -Name $reqName
while ($req.Status -ne 'Completed' -and $req.Status -ne 'Failed')
{
$exportStats = $req | Get-MailboxExportRequestStatistics
if ($null -ne $exportStats.PercentComplete)
{
try
{
$averageTimePerItem = ($exportStats.TotalInProgressDuration.TotalSeconds) / $exportStats.ItemsTransferred
$itemsRemaining = $exportStats.EstimatedTransferItemCount - $exportStats.ItemsTransferred
$predictedRemainingDurationSeconds = $averageTimePerItem * $itemsRemaining
$predictedRemainingDuration = [TimeSpan]::FromSeconds($predictedRemainingDurationSeconds)
Write-Progress -Activity "Processing $($req.Name)" -Status "$($exportStats.PercentComplete)% Complete. ETA: $($predictedRemainingDuration.ToString()), Remaining: $itemsRemaining" -PercentComplete $exportStats.PercentComplete
}
catch
{
Write-Progress -Activity "Processing $($req.Name)" -Status 'Initializing' -PercentComplete 0
}
Write-Host '.' -NoNewline
}
Start-Sleep -Seconds 5
$req = Get-MailboxExportRequest -Name $reqName
}
'Done.'
Write-Progress -Activity "Processing $reqName" -Status 'Export completed.' -PercentComplete 100
if ($req.Status -eq 'Failed')
{
$req | Get-MailboxExportRequestStatistics | Format-List
throw 'Export failed.'
}
}
$username = Read-Host 'Enter the mailbox identity'
$mailbox = $null
try
{
$mailbox = Get-Mailbox -identity $username
}
catch
{
Write-Error 'Invalid mailbox identity.'
throw
}
'Determining mailbox size. This may take a while...'
$mailboxsize = $mailbox | Get-MailboxStatistics | Select-Object @{Name = 'TotalItemSizeGB'; Expression = { [math]::Round(($_.TotalItemSize.ToString().Split('(')[1].Split(' ')[0].Replace(',', '') / 1GB), 0) } }
if ($mailboxsize.TotalItemSizeGB -le 10)
{
'This mailbox is small. Exporting as a single PST file.'
$reqName = "$username.complete"
New-MailboxExportRequest -Mailbox $username -Name $reqName -FilePath "$destination\$reqName.pst" | Out-Null
Wait-ForExportCompletion -reqName $reqName
}
else
{
'This mailbox is large. It will be split into yearly PST files.'
$y = $startyear
$endyear = (Get-Date).Year
While ($y -le $endyear)
{
$start = New-Object DateTime $y, 1, 1
$end = New-Object DateTime ($y + 1), 1, 1
$reqName = "$username.email.$y"
New-MailboxExportRequest -ContentFilter "MessageKind -eq 'Email' -and ((Received -ge '$start') -and (Received -lt '$end') -or (Sent -ge '$start') -and (Sent -lt '$end'))" -Mailbox $username -Name $reqName -FilePath "$destination\$reqName.pst" | Out-Null
Wait-ForExportCompletion -reqName $reqName
$y++
}
# Items that are not email don't have a sent or received property.
$reqName = "$username.nonemail"
New-MailboxExportRequest -ContentFilter "MessageKind -ne 'Email'" -Mailbox $username -Name $reqName -FilePath "$destination\$reqName.pst" | Out-Null
Wait-ForExportCompletion -reqName $reqName
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment