Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

We have a mailbox that receives status emails that we need to keep essentially for ever, and they contain potentially large attachments. I need to be able to move these messages to a PST on a regular (daily or weekly) basis so want to automate this.

At the moment I am using a MailboxExportRequest to get them into a PST:

New-MailboxExportRequest -ContentFilter {(Received -ge '01/01/2013') -and (Received -lt '01/02/2013')} -Mailbox "MonitorMailbox" -FilePath "\\Server\backup\EmailLog\MonitorMailbox 2013-01.pst"

And I follow this with a SearchMailbox -DeleteContent:

Get-Mailbox -Identity "MonitorMailbox" | Search-Mailbox -SearchQuery "Received:01/01/2013..01/02/2013" -DeleteContent

The problem is that I'm having to manually update the date parameters each time in four places, and I'm worried that it's not very transactional (if that even makes sense in this context).

I'm trying to create a little PS script to iterate through dates by month and build a set of commands to spin through and export this information, but was wondering if there's a simpler way to "move to PST", or if I need to try and build the above statements dynamically.

Here's a more complete script, as I have it so far, which should export all items for the 10 days preceding the beginning of this month (to speed up testing):

$mailbox = "Cylindric"
$endDate = Get-Date -Day 1 "00:00:00"
$startDate = $endDate.AddDays(-10)

$month = "{0:D2}" -f [int]$startDate.Month
$year = "{0:D4}" -f [int]$startDate.Year

Write-Host -NoNewline "Exporting items between $startDate and $endDate..."
New-MailboxExportRequest -Name "EmailLog$year$month" -ContentFilter {(Received -ge $startDate) -and (Received -lt $endDate)} -Mailbox $mailbox -FilePath "\\ReadyNAS\backup\Mailboxes\EmailLog\EmailLog${year}-${month}.pst"
Write-Host "Done."

Write-Host -NoNewline "Waiting for export to complete..."
While(!(Get-MailboxExportRequest -Mailbox $mailbox -Name "EmailLog$year$month" -Status Completed))
    #Sleep for a  few minutes
    Write-Host -NoNewline "."
    Start-Sleep -s 60
Write-Host "Done."

Write-Host -NoNewline "Removing Export Request..."
Get-MailboxExportRequest -Mailbox $mailbox -Status Completed -Name "EmailLog$year$month" | Remove-MailboxExportRequest
Write-Host "Done."

And the output:

Exporting items between 05/22/2013 00:00:00 and 06/01/2013 00:00:00...
Name            Mailbox       Status
----            -------       ------
EmailLog201305  Cylindric     Queued
Waiting for export to complete..........Done.

This seems to be exporting a lot more than these 10 days though. The PST appears to contain ALL emails!

share|improve this question
Have you considered creating an archive mailbox?… – Jim B May 29 '13 at 13:56
Enterprise feature, isn't it? – Cylindric May 29 '13 at 15:31

Use the Get-Date cmdlet!

The snippet below will check what month it is, subtract 1 and export all messages to your .pst file

$endDate = Get-Date -Day 1 "00:00:00"
$startDate = $endDate.AddMonths(-1)
$month = "{0:D2}" -f [int]$startDate.Month

# Convert dates to short date strings
$endDate = $endDate.ToShortDateString()
$startDate = $startDate.ToShortDateString()

New-MailboxExportRequest -ContentFilter {(Received -ge $startDate) -and (Received -lt $endDate)} -Mailbox "MonitorMailbox" -FilePath "\\Server\backup\EmailLog\MonitorMailbox 2013-${month}.pst"

while(!(Get-MailboxExportRequest -Mailbox "MonitorMailbox" -Status Completed))
    #Sleep for a  few minutes
    Start-Sleep -s 300
Get-MailboxExportRequest -Mailbox "MonitorMailbox" -Status Completed | Remove-MailboxExportRequest

Get-Mailbox -Identity "MonitorMailbox" | Search-Mailbox -SearchQuery "Received:'${startDate}'..'${endDate}'" -DeleteContent

Simple run this once a month to get the last months emails archived

share|improve this answer
The New-ExportRequest runs asynchronously, how can I make sure the delete doesn't try to start before the export is finished? – Cylindric May 31 '13 at 14:57
See my added suggestion. Remember to test it before setting it up – Mathias R. Jessen May 31 '13 at 15:04
Not sure why, but I'm always getting my entire mailbox exported. I had something like this before when using the ContentFilter, and I could only get it working with manual date strings as the parameters instead of variables. – Cylindric Jun 3 '13 at 10:14
Just realized why, see my updated example – Mathias R. Jessen Aug 8 '13 at 14:42
For anyone having a hard time getting this to work, the content filter may need to be specified as "(Received -ge '$startDate') -and (Received -lt '$endDate')"; otherwise, it would become $null as reported in this question:… – wandersick Mar 14 at 6:36

If you're willing to put this into a scheduled task, this should get what you're looking for:

New-MailboxExportRequest -ContentFilter {(Received -ge $fromtime) -and (Received -lt $totime)} -Mailbox "MonitorMailbox" -FilePath "\\Server\backup\EmailLog\MonitorMailbox "+$totime.year+"-"+$totime.month+"-"+$"+".pst"
Get-Mailbox -Identity "MonitorMailbox" | Search-Mailbox -SearchQuery $mailQuery -DeleteContent

What it does is take advantage of Powershell's date handling functions. The $fromtime and $totime variables are first zeroed to midnight, then set to a distance of one day. We then use those variables in constructing the queries needed by the Exchange cmdlets.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.