Archiving Emails to the Cloud

Many of my clients are making the move to the cloud for reasons that are technological, policy driven and budget driven. Whatever the reason it is my job to help them assess and perform a wide variety of functions when it comes to email and Online accessibility (ADFS/DirSync).

Creating a mailbox archive has many benefits whether on site or in the cloud. For the cloud in particular the benefits:

  • Lower storage costs – SAN, electricity, etc.
  • Less maintenance – No SAN to maintain and keep up to date
  • Smaller Inbox – quicker access to email that matters

Why use PowerShell to perform this function when Retention Tags and Policies can perform this task automatically? Answer: tags take time. If a 90 day retention policy is created, it will take 90 days before the first items are moved to the archive. PowerShell allows us to shortcut this and move items that are already over 90 days old. The below script is flexible enough for us to archive 10, 25, 45, 90 or whatever amount of days that need to be archived.

Script One

With this part of the process the script below will create an archive for a user, export a particular folder to a PST file and then import into the newly created on-prem archive.

cls
write-host "How many days back would you like to start removing email from and place them into an Archive mailbox? " -nonewline -foregroundcolor green
$days = read-host
$negdays = (-1)*$days
# Prepare variables
$Date = Get-Date
$startDate = $Date.Adddays($negdays)
write-host " "
write-host "Please specify a CSV file to use [i.e. c:\temp\users.csv] " -nonewline -foregroundcolor green
$csv = read-host
write-host " "
$users = import-csv $csv

# Create Archive
foreach ($line in $users) {
	$mailbox = $line.mailbox
	Enable-Mailbox $mailbox -Archive
}

# Choose a folder to archive
write-host "Pick a folder to archive for this process.  Options:" -ForegroundColor green
write-host " " 
write-host "    Inbox, SentItems, DeletedItems, Calendar, Contacts, Drafts, Journal, Tasks, Notes" -ForegroundColor white
write-host "    JunkEmail, CommunicationHistory, Voicemail, Fax, Conflicts, SyncIssues" -ForegroundColor white
write-host "    LocalFailures, ServerFailures" -ForegroundColor white
write-host " "
write-host "Archive which folder " -nonewline -ForegroundColor green
$folder = read-host
$foldername = '#'+$folder+'#'

# Export emails over 90 days from the Deleted Items folder
foreach ($line in $users) {
	$filepath = [string]$line.path+[string]$line.mailbox+".pst"
	$mailbox = $line.mailbox
	$name = [string]$line.mailbox+"-Export"
	write-host " "
	write-host "Exporting emails for " -nonewline -foregroundcolor cyan
	write-host "$mailbox" -foregroundcolor yellow -nonewline
	write-host " to a PST file now." -foregroundcolor cyan
	write-host " "
	New-MailboxExportRequest -name $name -ContentFilter {Received -gt $startDate} -Mailbox $line.mailbox -IncludeFolders $foldername -FilePath $filepath
}

Do {
	start-sleep 2
	write-host " "
	write-host "Waiting for export to complete" -foregroundcolor yellow
} While ((Get-MailboxExportRequest -name $name | Get-MailboxExportRequestStatistics).status -ne "completed") 

# Import emails over xx days from the Deleted Items folder to an Online Archive
foreach ($line in $users) {
	$mailbox = $line.mailbox
	$name2 = [string]$line.mailbox+"-Import"
	write-host " "
	write-host "Importing emails for " -nonewline -foregroundcolor cyan
	write-host "$mailbox" -foregroundcolor yellow -nonewline
	write-host " to the online archive now." -foregroundcolor cyan
	write-host " "
	New-MailboxImportRequest -name $name2 -Mailbox $line.mailbox -IsArchive -FilePath $filepath
	write-host "Don't forget to remove the " -nonewline -foregroundcolor yellow
	write-host "$filepath" -foregroundcolor red -nonewline
	write-host " after the script completes." -foregroundcolor yellow
	Do {
		start-sleep 2
		write-host " "
		write-host "Waiting for Import to complete" -foregroundcolor cyan
	} While ((Get-MailboximportRequest -name $name2 | Get-MailboximportRequestStatistics).status -ne "completed") 
}

# Remove export impot requests
write-host "Next, the script is going to delete all mailbox import and export requests."
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

write-host " "
write-host "Do you want to remove all Mailbox Export Requests [y or n] " -nonewline -ForegroundColor yellow
$choice1 = read-host
if ($choice1 -eq 'y') {Get-MailboxExportRequest | remove-mailboxexportrequest;write-host "Mailbox export requests were removed" -ForegroundColor Cyan
   } else { write-host " ";write-host "Do not forget to remove these later." -ForegroundColor white}

write-host " "
write-host "Do you want to remove all Mailbox Import Requests [y or n] " -nonewline -ForegroundColor yellow
$choice2 = read-host
if ($choice2 -eq 'y') {Get-MailboximportRequest | remove-mailboximportrequest;write-host "Mailbox import requests were removed" -ForegroundColor Cyan
   } else { write-host " ";write-host "Do not forget to remove these later." -ForegroundColor white
}

Walk-Through

For this sample run though, we are archiving 90 days of emails for all mailboxes in a CSV file (which contains an alias and a location for the PST file). There is also loop to wait for the export process to finish before importing. At the end of the script is also a process for removing the import and export requests.

FolderExportToArchive
Now, if the user has an archive mailbox already, the script checks for it and notifies you that it found an existing archive:

ArchiveExists
Script Two

This part of the script moves the archive to the cloud. Depending on your bandwidth and the size of the archives, this could take minutes or hours or even days..

write-host "Please provide your Office 365 Global Admin account credentials."
$Creds = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell -Credential $Creds -Authentication Basic -AllowRedirection
Import-PSSession $Session
write-host " "
write-host "Please provide your on prem Exchange administrator credentials."
$RemoteCredential = Get-Credential
New-MoveRequest -id "Move To Cloud" -Remote -archiveonly -RemoteHostName <MRS Proxy Name> -TargetDeliveryDomain <tenant>.mail.onmicrosoft.com -RemoteCredential $RemoteCredential -whatif

… and that’s it. Now you’ve moved some items to the cloud and when your retention policy does kick in, the items will go to the cloud and not on-prem.

Walkthorugh

Here is what the script looks like when you a removing a list of users stored in a CSV file. The bottom area, circled in red, shows the archive move being queued for migration:

ArchiveMoveToCloud

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s