Exporting mail to .PST files using PowerShell

We have one Exchange mailbox that has seen exponential growth with no good workaround to be had. I started worrying when we passed 100 GB for the single box, and by 160 GB users started getting properly annoyed by the performance when browsing the box. I spoke to the manager for the department and suggested exporting the data to a number of archive files that could be manually accessed by select users.

The basic command

As usual, for this kind of task we want to reach for our CLI. The command to copy data to a .PST is New-MailboxExportRequest. A typical use case for a small box could look something like this:

New-MailboxExportRequest -Mailbox "MailboxName" -Name JobIdentifier -FilePath \\servername\path\filename.pst

Two notes:
1) The Name of the job is how we may reference it later on. It doesn’t have to make sense, but in case we create multiple jobs our lives get easier if they have sane names.
2) The FilePath argument must point at a UNC share where the domain group Exchange Trusted Subsystem has Modify rights. Avoid writing to a system or database volume directly on the mail server, or bad things may happen when the volume fills up.

Advanced parameters

We will undoubtedly want to create more advanced queries, though. In the case of my giant mailbox, it makes sense to split the contents chronologically. The ContentFilter parameter can be made advanced enough if we want to:

New-MailboxExportRequest -ContentFilter {(((Sent -gt '2016-08-01') -and (Sent -lt '2016-10-01')) -or ((Received -gt '2016-08-01') -and
(Received -lt '2016-10-01')))} -Mailbox "MailboxName" -Name MailboxAugToSep2016dump -IsArchive -FilePath \\servername\path\filename.pst

To break the command down:
1) We want to filter for both the Sent and the Received properties of our mails, since we want to catch not only mails that were received during the period, but also outbound mail from the time.
2) Since we use the “greater than” and “less than” parameters, it’s good to know how they work in the case of dates: When written in this way, what we’re actually putting in is “the date, at 00:00”. In other words the -gt switch will pick up the entire day of the date entered, but to catch the entire last day of a month with the -lt switch, we must enter the first day of the following month. In this case we’ll dump everything up until 00:00 on October the 1st, which is exactly what we want.
3) In this case I added the IsArchive directive. This tells the command to look in the online archive belonging to the mailbox instead of in the actual mailbox.

Checking job status

We can check if an export request is queued, in progress, completed, or failed, simply by running Get-MailboxExportRequest. But as usual we can get some truly useful information by stringing some commands together. Why did a job fail? Did the supposedly “completed” job parse our command line the way we expected it to?

Get-MailboxExportRequest -status Completed | Get-MailboxExportRequestStatistics -IncludeReport | fl > c:\report.txt

Here we first ask for a list of Completed jobs – but we might as well ask for failed jobs. Then we dump a pretty verbose list of the report(s) to a regular text file for easy reading.

Clearing jobs

Once we’re confident we know what we need to know about our completed or failed jobs, we can use the Remove-MailboxExportRequest cmdlet to clear our job list. Combine it with Get-MailboxExportRequest to clear many at a time. For example:

Get-MailboxExportRequest -status Completed | Remove-MailboxExportRequest

This will simply remove all jobs with the status Completed.

References

New-MailboxExportRequest
Get-MailboxExportRequestStatistics


Fixing “No DKIM keys saved for this domain” in EOP and Office365

Sometimes a newly added domain in Microsoft EOP will not let you enable DKIM from the web user interface. The only workaround I know of is to prepare the domain using PowerShell.

To connect a PS session to O365, I use the following script, ripped straight from Microsoft’s documentation:

$UserCredential = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
Import-PSSession $Session -DisableNameChecking

After waiting for an eternity for the necessary stuff to load, run the following command – and wait another eternity for it to finish:

New-DkimSigningConfig -DomainName "mydomain.tld" -Enabled $true

Note: Unless you’ve already added the necessary _domainkey CNAME records to your DNS zonefile, this command will succeed in generating the DKIM keys, but will fail to enable DKIM signing for the domain. Without looking into it I suspect that the Set-DkimSigningConfig cmdlet could be used to enable signing.

Finally disconnect from your O365 PS session:

Remove-PSSession $Session

Your domain now signs mail sent through O365 or via Exchange Online Protection.

Bonus knowledge: With a recent version of PowerShell Core installed, you can manage situations like this from a regular Mac or Linux box.