Friday, September 21, 2012

PowerShell Script - Mailbox Folder Import and Migration Verification


I have used this script in the past to verify that mailbox content was imported or migrated successfully. Basically, all it does is look for mailboxes that have an empty Inbox, Sent Items, Contacts, or Calendar folder. If a mailbox is found with at least one of these folders being empty, it adds the mailbox to a report with the count of each folder, then generates a CSV report at the end.
The list of mailboxes to check can be one of the following:
  1. CSV file - the script only looks for a column of emailAddress.
  2. By specifying an OU of users to check
  3. All mailboxes in the Exchange org.
The only required switch is -OutFile which requires a valid file name and path for the CSV file.
I have tested this script on Exchange 2010 SP1, Windows 2008 R2, and PowerShell 2.0 in both production and a lab environment. If you run into any issues please post a comment or question.



<#

.SYNOPSIS
Reports on mailboxes with an empty Inbox, Calendar, Contact, or Sent Items folder. 
This is very useful as a quick check to see if migrated or imported mailboxes have empty
folders, but does NOT verify that ALL data was successfully migrated/imported. It does serve
well as a quick reference on mailboxes that may have blatantly failed during migration/import.

.DESCRIPTION
The list of mailboxes to evaluate can be sourced from a CSV, a particular OU, or all mailboxes
in the current Exchange organization. For each mailbox, we check to see if any of the following
mail folders (and their subfolders) are empty: Inbox, Sent Items, Contacts, Calendar. If any of
these are reported as having zero items, we add the mailbox's email address and each folder's
item count to a CSV.

.PARAMETER OutFile
Specifies the full path and filename to store the CSV formatted report. This is REQUIRED.

.PARAMETER CSV
Specifies the full path and filename of the CSV to be used as input. The CSV used here only 
requires the emailAddress field in the header and for each mailbox. If both -CSV and -OU are used
together, -OU will be ignored.

.PARAMETER OU
Specifies the canonical name of the AD Organizational Unit containing mailboxes to be inspected.
This is the same as the -OrganizationalUnit parameter of the Get-Mailbox cmdlet in Exchange 2010.
If both -CSV and -OU are used together, -OU will be ignored.

.EXAMPLE
./MbxImpMigCheck.ps1 -OutFile c:\Temp\report.csv
Generates a report on any mailbox in the Exchange Organization that has an empty Inbox,
Sent Items, Contacts, or Calendar folder, and saves the report as a CSV in C:\Temp\report.csv
WARNING: This can take a while to run in large environments

.EXAMPLE
./MbxImpMigCheck.ps1 -OutFile c:\Temp\report.csv -CSV c:\Temp\inputFile.csv
Generates a report on any mailbox in the CSV that has an empty Inbox, Sent Items, Contacts, or 
Calendar folder, and saves the report as a CSV in C:\Temp\report.csv

.EXAMPLE
./MbxImpMigCheck.ps1 -OutFile c:\Temp\report.csv -OU "ou=mailboxes,dc=domain,dc=com"
Generates a report on any mailbox in the Mailboxes OU of the domain.com domain that has an empty 
Inbox, Sent Items, Contacts, or Calendar folder, and saves the report as a CSV in C:\Temp\report.csv

.NOTES
Author: Trent Nevius (trent@beyond-next.com)
PowerShell Modules required: [Exchange 2010]
Tested PowerShell version: [2.0]
Tested software: Microsoft Exchange 2010 SP1 on Windows 2008 R2

.LINK
http://gallery.technet.microsoft.com/scriptcenter/Mailbox-Folder-Import-and-24a62dc3

#>

# Define Parameters
Param(
[string] $CSV = "",
[string] $OU = "",
[string] $OutFile
)

# Ensure the OutFile parameter was supplied
if ($OutFile -eq "") {
Write-Host "`nMissing parameter: The -OutFile parameter is required. Please re-run this script with a valid path and filename for the -OutFile parameter.`n"
exit
}

Add-pssnapin Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction SilentlyContinue

# Define array variables
$Results = @("emailAddress,Inbox,SentItems,Calendar,Contacts`n")
$Mailboxes = @()

if ($CSV -ne "") {Import-CSV -Path $CSV | foreach {$Mailboxes += Get-Mailbox $_.emailAddress}}
elseif ($OU -ne "") {$Mailboxes = Get-Mailbox -OrganizationalUnit $OU}
else {$Mailboxes = Get-Mailbox -ResultSize unlimited}


foreach ($mailbox in $Mailboxes) {
$CalendarCount = (get-mailboxfolderstatistics $mailbox.alias -FolderScope Calendar).ItemsInFolderAndSubfolders
$InboxCount = (get-mailboxfolderstatistics $mailbox.alias -FolderScope Inbox).ItemsInFolderAndSubfolders
$ContactCount = (get-mailboxfolderstatistics $mailbox.alias -FolderScope Contacts).ItemsInFolderAndSubfolders
$SentCount = (get-mailboxfolderstatistics $mailbox.alias -FolderScope SentItems).ItemsInFolderAndSubfolders
    if (($CalenderCount -eq 0) -or ($InboxCount -eq 0) -or ($ContactCount -eq 0) -or ($SentCount -eq 0)) {
        $Results += $mailbox.PrimarySMTPAddress.ToString() + ",$InboxCount,$SentCount,$CalendarCount,$ContactCount`n"
    }
}
$Results > $OutFile
Write-Host "`nReport Complete, results output formatted as CSV to " $Outfile