In June I added a post on how to migrate exchange 2010 mailboxes to an Exchange 2010 DAG in a controlled fashion. Since then I’ve completely restructured the script and made it an all-in-one solution.
The first section of the script contains variables that need to be set.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
#region ========================================================================
# Created on: 9/3/2013 8:01 PM
# Created by: Jon Howe
# URL: http://45.63.13.214/?p=539
# Filename: Set-MailboxMoveActive-v2.ps1
#endregion ========================================================================
#region Set Variables
#Amount of mailboxes to migrate at a time
$BatchSize = 5
#Mailbox DB to pull mailboxes from
$sourceMailboxDatabase = "Mailbox Database 3"
#Default amount of time to sleep when we hit a roadblock
$sleepMinutes = 20
#Time to start migrating mailboxes
$startTime = Get-Date -Hour 23 -Minute 00 -Second 00
#Time to stop migrating mailboxes
$stopTime = Get-Date -Hour 05 -Minute 00 -Second 00
#Array containing all of your DAG servers (used to check disk space)
$DAG_Servers = @("EXCH-DAG-A","EXCH-DAG-B")
#OS label for the DAG DAGA/Log drives on your DAG servers.
$OS_Label_Prefix = "DAGDB*"
#Threshold for stopping the migration (in bytes)
$MinOSDriveFreeBytes = 16106127360 #32212254720 is 30GB, 16106127360 is 15GB
#endregion Set Variables
$PS_Is_Awesome = $TRUE #!!!
While ($PS_IS_Awesome) #region Main Loop
{
#region Check for Business Hours
if ( (Get-Date) -gt $stopTime -and (Get-Date) -lt $startTime ) #region In Business Hours
{
Write-Host "We're in business hours. Sleeping..." -ForegroundColor 'DarkCyan'
Start-Sleep -Seconds ($sleepMinutes * 60)
} #endregion In Business Hours
else #region Out of Business Hours
{
#region Check to make sure drive space isn't too low
foreach($mbx in $DAG_Servers)
{
$space = `
get-WmiObject win32_volume -ComputerName $mbx |
select driveletter,label,freespace,capacity |
where {$_.label -like $OS_Label_Prefix}
foreach($drive in $space)
{
$human_freespace = [math]::Round($drive.freespace / (1024*1024*1024),1)
if ($drive.freespace -lt $MinOSDriveFreeBytes)
{
Write-Host "Drive" $drive.driveletter "on server $mbx with label" $drive.label "is under 30 GB. It's currently at" $human_freespace "GB..."
write-host "Sleeping for $sleepMinutes minutes." -ForegroundColor 'DarkCyan'
for ($i = 1; $i -le ($sleepMinutes * 60); $i++)
{
Write-Progress -Activity 'Drive Space is too low. Waiting until it frees up.' -Status "We've waited $i Seconds" -SecondsRemaining (($sleepMinutes * 60)-$i)
sleep -Seconds 1
}
}
}
}
#endregion Check to make sure drive space isn't too low
#region Check to see if a move-request is currently occurring
if (Get-MoveRequest | Where-Object { $_.Status -eq "Queued" -or $_.Status -eq "InProgress" -or $_.Status -eq "CompletionInProgress"})
{
Write-Host "There are move requests currently processing. Sleeping for $sleepMinutes minutes" -ForegroundColor 'DarkCyan'
for ($i = 1; $i -le ($sleepMinutes * 60); $i++)
{
Write-Progress -Activity "Can't begin if move requests are already running. Waiting for them to complete" -Status "We've waited $i Seconds" -SecondsRemaining (($sleepMinutes * 60)-$i)
sleep -Seconds 1
}
continue
}
#endregion Check to see if a move-request is currently occurring
#region General information display and information gathering.
Write-Host "We're out of business hours, drive space looks good, and there are no batches running" -ForegroundColor 'Yellow'
write-host "Let's submit one!" -ForegroundColor 'Yellow'
# Get Mailbox Sizes
Write-Host "Getting Mailbox Sizes" -ForegroundColor 'Blue'
$allmbx = Get-Mailbox -database $sourceMailboxDatabase |
Get-MailboxStatistics |
Sort-Object TotalItemSize |
Select-Object DisplayName,TotalItemSize
#endregion General information display and information gathering.
# Submit move requests to best datatabase
Write-Host "Submitting move requests now" -ForegroundColor 'Blue'
$batch = 1
for ($i=1;$i -le 5;$i++) #region For Loop
{
#region Determine the best database to send mailboxes to
if ($i % $BatchSize -eq 0)
{
# Find best Database
$result = Get-MailboxDatabase -identity "DAG*" -Status |
Select-Object name,DatabaseSize,AvailableNewMailboxSpace |
Sort-Object -Property DatabaseSize
$bestDatabase = $result[0].name
$batch++
}
#endregion Determine the best database to send mailboxes to
#Submit the mailbox move requests
Write-Host "New Move -" $allmbx[$i].DisplayName "to DB" $bestDatabase -ForegroundColor 'DarkGreen'
New-MoveRequest -TargetDatabase $bestDatabase -Identity $allmbx[$i].DisplayName | out-null
} #endregion For Loop
Write-Host "Batches submitted. Sleeping for $sleepMinutes minutes" -ForegroundColor 'DarkCyan'
for ($i = 1; $i -le ($sleepMinutes * 60); $i++)
{
Write-Progress -Activity 'Waiting while move requests complete' -Status "We've waited $i Seconds" -SecondsRemaining (($sleepMinutes * 60)-$i)
sleep -Seconds 1
}
} #endregion Out of Business Hours
#endregion Check for Business Hours
} #endregion Main Loop
|
One thought on “Update: Exchange 2010 – Bulk Mailbox Migration In Batches (The Right Way)”