Created
August 5, 2016 05:31
-
-
Save JustinGrote/e7cebe41a2159bcef6591c3198c84646 to your computer and use it in GitHub Desktop.
Exchange Mailbox Batch Migration with Intelligent Mailbox Balancing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#requires -version 3.0 | |
#requires -pssnapin Microsoft.Exchange.Management.PowerShell.E2010 | |
<# | |
.SYNOPSIS | |
Generates a CSV that can be used with the BatchMigration process | |
.DESCRIPTION | |
This script generates a CSV from a list of mailboxes for local migrations. Its primary use is to allow for custom mailbox distribution methods, such as by least-full database or round-robin | |
This is primarily meant for greenfield migrations where all databases are of similar configuration, and not heterogeneous database environments. | |
.NOTES | |
Must be run on a computer with Exchange Management Shell installed due to serialization issues and byte conversion. | |
I could make it work remotely but it would require some ugly regex work on the serialized objects since default Exchange config doesn't allow scripts to be run remotely | |
.EXAMPLE | |
New-MailboxBatchMigrationCSV.ps1 -Identity (get-mailboxdatabase server1 | get-mailbox) -targetdatabase newdatabase* | export-csv "$home\desktop\mailboxdb.migrationbatch.csv" | |
Generate a batch migration CSV from an old mailbox database to databases newdatabase01, newdatabase02, newdatabase03, etc. | |
.EXAMPLE | |
$csvpath="C:\scripts\migrations\Group1.csv" | |
New-MailboxBatchMigrationCSV.ps1 -Identity (import-csv $csvpath).emailaddress -TargetDatabase Tinamail* -AutoMDBMethod leaststorageused -ShowDatabaseSizeDelta | export-csv "$csvpath.migrationbatch.csv" | |
Take a csv of email Addresses and generate a migrationbatch CSV based on leastStorageUsed algorithm | |
#> | |
#Uncomment this and trailing } to make into a command rather than a script | |
#function New-MailboxBatchMigrationCSV { | |
[CmdletBinding()] | |
param( | |
#Identity of the mailbox to migrate. May pass one or more email addresses,aliases,identity strings,or mailbox objects. | |
[Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]$Identity, | |
#Candidate Target Mailbox Databases. Leave blank to use all relevant databases. | |
[String[]]$TargetDatabase, | |
#Database Selection Method to use | |
#Default is LeastStorageUsed | |
#LeastStorageUsed: Select databases based on least storage used, resulting in even distribution by GB | |
[String]$AutoMDBMethod='LeastStorageUsed', | |
#Outputs the estimated final database sizes, in KB. This uses Write-Host so as not to interfere with the pipeline | |
[Switch]$ShowDatabaseSizeDelta | |
) | |
begin { | |
#If no databases were specified, get all databases | |
if (!($targetDatabase)) { | |
$targetDatabase = (Get-MailboxDatabase).Name | |
} | |
#TODO: Add ExcludeFromProvisioning Logic | |
#If we are doing 'leaststorageused', get the candidate mailbox sizes and set up the database size hashtable | |
if ($AutoMDBMethod -match 'leastStorageUsed') { | |
$mailDBSizeTable = @{} | |
foreach ($TargetDatabaseItem in $TargetDatabase) { | |
foreach ($mailDB in (Get-MailboxDatabase $TargetDatabaseItem -status | sort name)) { | |
#Generate a simple hashtable entry for each database for the total curent "used" size of the database | |
$mailDBSizeTable.Add($mailDB.Name,($mailDB.DatabaseSize.toKB() - $mailDB.AvailableNewMailboxSpace.toKB())) | |
} | |
} | |
} | |
#If ShowBeforeAfterSizes, take a snapshot of the DBSizeTable | |
if ($ShowDatabaseSizeDelta) { | |
$mailDBSizeTableBefore = $mailDBSizeTable.clone() | |
} | |
} | |
process { | |
$i = 1 | |
foreach ($IdentityItem in $Identity) { | |
write-progress "Evaluating $IdentityItem mailbox placement" -PercentComplete (($i/$identity.count)*100) | |
$mbox = get-mailbox $IdentityItem | |
if ($mbox) { | |
$mboxStats = get-mailboxstatistics $IdentityItem | |
#First Determine the candidate mailbox database | |
$selectedDatabase = ($mailDBSizeTable.GetEnumerator() | sort Value | select -first 1).Name | |
[PSCustomObject]@{ | |
EmailAddress = $mbox.PrimarySmtpAddress | |
TargetDatabase = $selectedDatabase | |
} | |
#Add the projected mail to be added to the database total, for use in the next evaluation | |
$mailDBSizeTable[$selectedDatabase] = $mailDBSizeTable[$selectedDatabase] + $mboxStats.TotalItemSize.Value.ToKB() | |
} | |
$i++ | |
} | |
#Show the final database totals if requested | |
if ($ShowDatabaseSizeDelta) { | |
$strDBSizes = $mailDBSizeTable.GetEnumerator() | foreach { | |
[PSCustomObject]@{ | |
Name = $_.Name | |
Before = $mailDBSizeTableBefore[$_.Name] | |
After = $_.Value | |
Growth = ($_.Value - $mailDBSizeTableBefore[$_.Name]) | |
PercentGrowth = [Math]::Round((($_.Value / $mailDBSizeTableBefore[$_.Name])-1)*100) | |
} | |
} | sort name | format-table | out-string | |
write-host "" | |
write-host -ForegroundColor Green "===Estimated Database Sizes after Migration===" | |
write-host -ForegroundColor Green $strDBSizes | |
} | |
} | |
#} #Function |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment