Powershell – How to move Exchange items to a PST using PowerShell

exchange-2010powershell

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
Done.
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!

Best Answer

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