-->

Saturday, October 24, 2020

Exchange - Create New Databases And Delete the Old Ones

On rare occasions you may need to create new Mailbox Databases on your Exchange DAG. Maybe you need to scale out for a company merger, or re-balance your mailboxes evenly across your Mailbox servers. 

Or, as seen on many, many forums, people ask how to shrink databases safely, without downtime...which leads to: Like me, you planned for a year’s worth of mail to migrate from Notes to Exchange and the Quest guy (yes, when you pay for the Quest Migration Tool, an expert is required to run it) moved EVERYTHING going back 15 years, including when the tool failed on hundreds of mailboxes and created multiple subfolders of duplicate items. So, in my case I ended up with 6 Databases of ~1TB each...after deduping, remember that deletions leaves whitespace, they’re taking up a lot of disk space. MS technically supports 16TB DB’s but that gets pretty dicey if you have failovers or if you have to perform a restore.

When getting DB size under control (read that as "shrinking"), best practice is to create new DB’s, migrate mailboxes and delete the old DB’s…DO NOT perform an offline defrag, especially in a DAG because it will cause downtime and ruin your month if/when it goes wrong…you also need 1.5x the size of a DB to defrag, nope! Moving mailboxes causes no outage, and is nearly transparent to users. I say "nearly" because Outlook may do a small reconnect during the last 30 seconds of a mailbox move, but if you have your load balancer settings correct, users will never know.

In this article, I’ll show you how to set up those new databases and get rid of the giant old ones...strap in, it's a long one :)

Create DAG Mount Points

First, we’ll create the mount point needed for our new databases volume.

Perform the following steps on each Exchange Mailbox Server – it is very important that volumes and folders match exactly on each server.

If you’ve followed my previous Exchange setup articles before or you follow best practice, you may already have your Exchange Volume presented to your servers as a drive. 

**Note** In my environment, I was able to grow the disks in VMWare, so I created the DB structure on the same volume as the old DB’s. If you’re setting up new disks, then follow the next section.


1. On the C: drive, create a folder called EXVols – this folder will be used to mount our E: (Volume1).
2. Next, on the C: drive, create a folder called ExDBs – this folder will hold the Database mount points.

Creating the Volume

3. Within the ExVols folder, create a new folder called Volume1 

4. Open Windows Disk Management to mount our volume to our ExVols folders.
5. Right-click E: and select Change Drive Letter and Paths
6. Click Add and browse to the location of the Volume1 folder – C:\ExVols\Volume1
7. Click OK, twice

You should see the folder with a Disk icon meaning it’s now a Mount Point. 

Creating the Database Folders

Under the C:\ExDBs folder, create the new Database folders for as many DB’s as you plan to have. In my case we’ll have 12, so we’ll create the following folders:


C:\ExDBs\MDB01
C:\ExDBs\MDB02
C:\ExDBs\MDB03
C:\ExDBs\MDB04
C:\ExDBs\MDB05
C:\ExDBs\MDB06
C:\ExDBs\MDB07
C:\ExDBs\MDB08
C:\ExDBs\MDB09
C:\ExDBs\MDB10
C:\ExDBs\MDB11
C:\ExDBs\MDB12

**Note** We’re creating the DB folders with different names than your current DB folders. If you already databases name DB01-DB06, we’ll name the new ones MDB01-MDB12. You might wonder "why not continue with DB07 and up?". We’re replacing the old DB’s because we want to get all of that whitespace back, which we wouldn’t be able to achieve without moving all mailboxes and deleting the old DB’s.

After you have your folders set, open an Elevated command prompt, and run:

mountvol

This will list the available volumes for use.

In my case I know the one I want is \\?\Volume{eeadb719-54af-4384-9c90-78dbf04acf86}\ because we can see the folder Volume1 is mounted to it

Run the following command to mount MDB01:

Mountvol MDB01 \\?\Volume{eeadb719-54af-4384-9c90-78dbf04acf86}\

If you go to your C:\ExDBs folder, you’ll notice the folder icon for MDB01 has changed to a mount point icon.

Now mount your other DB’s:


Mountvol MDB02 \\?\Volume{eeadb719-54af-4384-9c90-78dbf04acf86}\
Mountvol MDB03 \\?\Volume{eeadb719-54af-4384-9c90-78dbf04acf86}\
Mountvol MDB04 \\?\Volume{eeadb719-54af-4384-9c90-78dbf04acf86}\
Mountvol MDB05 \\?\Volume{eeadb719-54af-4384-9c90-78dbf04acf86}\
Mountvol MDB06 \\?\Volume{eeadb719-54af-4384-9c90-78dbf04acf86}\
Mountvol MDB07 \\?\Volume{eeadb719-54af-4384-9c90-78dbf04acf86}\
Mountvol MDB08 \\?\Volume{eeadb719-54af-4384-9c90-78dbf04acf86}\
Mountvol MDB09 \\?\Volume{eeadb719-54af-4384-9c90-78dbf04acf86}\
Mountvol MDB10 \\?\Volume{eeadb719-54af-4384-9c90-78dbf04acf86}\
Mountvol MDB11 \\?\Volume{eeadb719-54af-4384-9c90-78dbf04acf86}\
Mountvol MDB12 \\?\Volume{eeadb719-54af-4384-9c90-78dbf04acf86}\ 

If you run mountvol again, you’ll see all DB’s mounted under the Volume1 folder.

Creating the Database Directory Structure

Next, we’ll create the database directory structure; each folder will have 2 folders beneath it: one folder for the Database .edb file and one for the Logs.

**Note** In a DAG, it is best practice to keep database and log files on the same volume, as long as it is separate from the System Volume.

You can create these folders directly from Volume1 (E:) or by going to C:\ExDBs\MDB01 through MDB12 (they will have the same folders).

In E:\ExDBs\MDB01, create a new folder named MDB01.db and new folder called MDB01.log.

In E:\ExDBs\MDB02, create a new folder named MDB02.db and new folder called MDB02.log.

In E:\ExDBs\MDB03, create a new folder named MDB03.db and new folder called MDB03.log.

In E:\ExDBs\MDB04, create a new folder named MDB04.db and new folder called MDB04.log.

In E:\ExDBs\MDB05, create a new folder named MDB05.db and new folder called MDB05.log.

In E:\ExDBs\MDB06, create a new folder named MDB06.db and new folder called MDB06.log.

In E:\ExDBs\MDB07, create a new folder named MDB07.db and new folder called MDB07.log.

In E:\ExDBs\MDB08, create a new folder named MDB08.db and new folder called MDB08.log.

In E:\ExDBs\MDB09, create a new folder named MDB09.db and new folder called MDB09.log.

In E:\ExDBs\MDB10, create a new folder named MDB10.db and new folder called MDB10.log.

In E:\ExDBs\MDB11, create a new folder named MDB11.db and new folder called MDB11.log.

In E:\ExDBs\MDB12, create a new folder named MDB12.db and new folder called MDB12.log.

**Note** You will notice that each folder also contains the DB folders for the other DB’s. For instance if you go to C:\ExDBs\MDB02, you'll see all of the MDB folders listed. That’s normal because we’re using the same underlying storage presented to Windows.

Create Mailbox Databases

Next, we’ll be creating our twelve Databases, and evenly distributing them across our servers. 

MDB01, MDB04, MDB07, MDB10 on Server01

MDB02, MDB05, MDB08, MDB11 on Server02

MDB03, MDB06, MDB09, MDB12 on Server03

Create the Databases by running the following cmdlets in the Exchange Management Shell (EMS):


New-MailboxDatabase –Name MDB01 –Server EXCH-MBX-01 –LogFolderPath C:\ExDBs\MDB01\MDB01.log –EdbFilePath C:\ExDBs\MDB01\MDB01.db\MDB01.edb

New-MailboxDatabase –Name MDB02 –Server EXCH-MBX-02 –LogFolderPath C:\ExDBs\MDB02\MDB02.log –EdbFilePath C:\ExDBs\MDB02\MDB02.db\MDB02.edb

New-MailboxDatabase –Name MDB03 –Server EXCH-MBX-03 –LogFolderPath C:\ExDBs\MDB03\MDB03.log –EdbFilePath C:\ExDBs\MDB03\MDB03.db\MDB03.edb

New-MailboxDatabase –Name MDB04 –Server EXCH-MBX-01 –LogFolderPath C:\ExDBs\MDB04\MDB04.log –EdbFilePath C:\ExDBs\MDB04\MDB04.db\MDB04.edb

New-MailboxDatabase –Name MDB05 –Server EXCH-MBX-02 –LogFolderPath C:\ExDBs\MDB05\MDB05.log –EdbFilePath C:\ExDBs\MDB05\MDB05.db\MDB05.edb

New-MailboxDatabase –Name MDB06 –Server EXCH-MBX-03 –LogFolderPath C:\ExDBs\MDB06\MDB06.log –EdbFilePath C:\ExDBs\MDB06\MDB06.db\MDB06.edb

New-MailboxDatabase –Name MDB07 –Server EXCH-MBX-01 –LogFolderPath C:\ExDBs\MDB07\MDB07.log –EdbFilePath C:\ExDBs\MDB07\MDB07.db\MDB07.edb

New-MailboxDatabase –Name MDB08 –Server EXCH-MBX-02 –LogFolderPath C:\ExDBs\MDB08\MDB08.log –EdbFilePath C:\ExDBs\MDB08\MDB08.db\MDB08.edb

New-MailboxDatabase –Name MDB09 –Server EXCH-MBX-03 –LogFolderPath C:\ExDBs\MDB09\MDB09.log –EdbFilePath C:\ExDBs\MDB09\MDB09.db\MDB09.edb

New-MailboxDatabase –Name MDB10 –Server EXCH-MBX-01 –LogFolderPath C:\ExDBs\MDB10\MDB10.log –EdbFilePath C:\ExDBs\MDB10\MDB10.db\MDB10.edb

New-MailboxDatabase –Name MDB11 –Server EXCH-MBX-02 –LogFolderPath C:\ExDBs\MDB11\MDB11.log –EdbFilePath C:\ExDBs\MDB11\MDB11.db\MDB11.edb

New-MailboxDatabase –Name MDB12 –Server EXCH-MBX-03 –LogFolderPath C:\ExDBs\MDB12\MDB12.log –EdbFilePath C:\ExDBs\MDB12\MDB12.db\MDB12.edb

**Note** You will get a Warning that “The Information Store must be restarted after DB creation” - this is by design. Exchange 2013/2016 uses different memory management so that store.exe does not use all available RAM. MS suggests DB creation is during maintenance window, since restarting the store.exe service dismounts databases active on that server…even though it’s super annoying.

 

Add Database Copies

Next, we'll create our DB copies. Note the Activation Preference (AP), which mounts the copy according to server:


DB

EXCH-MBX-01 -AP

EXCH-MBX-02 -AP

EXCH-MBX-03 -AP

MDB01

1

2

3

MDB02

3

1

2

MDB03

3

2

1

MDB04

1

2

3

MDB05

3

1

2

MDB06

3

2

1

MDB07

1

2

3

MDB08

3

1

2

MDB09

3

2

1

MDB10

1

2

3

MDB11

3

1

2

MDB12

3

2

1


Run the following cmdlets in the EMS to create the DB copies according to activation preference, separately on each line (yes, there's a bunch):

Add-MailboxDatabaseCopy -Identity MDB01 -MailboxServer EXCH-MBX-02 -ActivationPreference 2
Add-MailboxDatabaseCopy -Identity MDB01 -MailboxServer EXCH-MBX-03 -ActivationPreference 3
Add-MailboxDatabaseCopy -Identity MDB02 -MailboxServer EXCH-MBX-03 -ActivationPreference 2
Add-MailboxDatabaseCopy -Identity MDB02 -MailboxServer EXCH-MBX-01 -ActivationPreference 3
Add-MailboxDatabaseCopy -Identity MDB03 -MailboxServer EXCH-MBX-02 -ActivationPreference 2
Add-MailboxDatabaseCopy -Identity MDB03 -MailboxServer EXCH-MBX-01 -ActivationPreference 3
Add-MailboxDatabaseCopy -Identity MDB04 -MailboxServer EXCH-MBX-02 -ActivationPreference 2
Add-MailboxDatabaseCopy -Identity MDB04 -MailboxServer EXCH-MBX-03 -ActivationPreference 3
Add-MailboxDatabaseCopy -Identity MDB05 -MailboxServer EXCH-MBX-03 -ActivationPreference 2
Add-MailboxDatabaseCopy -Identity MDB05 -MailboxServer EXCH-MBX-01 -ActivationPreference 3
Add-MailboxDatabaseCopy -Identity MDB06 -MailboxServer EXCH-MBX-02 -ActivationPreference 2
Add-MailboxDatabaseCopy -Identity MDB06 -MailboxServer EXCH-MBX-01 -ActivationPreference 3
Add-MailboxDatabaseCopy -Identity MDB07 -MailboxServer EXCH-MBX-02 -ActivationPreference 2
Add-MailboxDatabaseCopy -Identity MDB07 -MailboxServer EXCH-MBX-03 -ActivationPreference 3
Add-MailboxDatabaseCopy -Identity MDB08 -MailboxServer EXCH-MBX-03 -ActivationPreference 2
Add-MailboxDatabaseCopy -Identity MDB08 -MailboxServer EXCH-MBX-01 -ActivationPreference 3
Add-MailboxDatabaseCopy -Identity MDB09 -MailboxServer EXCH-MBX-02 -ActivationPreference 2
Add-MailboxDatabaseCopy -Identity MDB09 -MailboxServer EXCH-MBX-01 -ActivationPreference 3
Add-MailboxDatabaseCopy -Identity MDB10 -MailboxServer EXCH-MBX-02 -ActivationPreference 2
Add-MailboxDatabaseCopy -Identity MDB10 -MailboxServer EXCH-MBX-03 -ActivationPreference 3
Add-MailboxDatabaseCopy -Identity MDB11 -MailboxServer EXCH-MBX-03 -ActivationPreference 2
Add-MailboxDatabaseCopy -Identity MDB11 -MailboxServer EXCH-MBX-01 -ActivationPreference 3
Add-MailboxDatabaseCopy -Identity MDB12 -MailboxServer EXCH-MBX-02 -ActivationPreference 2
Add-MailboxDatabaseCopy -Identity MDB12 -MailboxServer EXCH-MBX-01 -ActivationPreference 3

Next, we need to exclude the old databases from mailbox autoprovisioning, so new mailboxes will only be created on the new DB’s during our migration…we don’t want to finish our moves and later have to go back and move new mailboxes too!

Run the following cmdlets on each line:

Set-MailboxDatabase "DB01" -IsExcludedFromProvisioning $true
Set-MailboxDatabase "DB02" -IsExcludedFromProvisioning $true
Set-MailboxDatabase "DB03" -IsExcludedFromProvisioning $true
Set-MailboxDatabase "DB04" -IsExcludedFromProvisioning $true
Set-MailboxDatabase "DB05" -IsExcludedFromProvisioning $true
Set-MailboxDatabase "DB06" -IsExcludedFromProvisioning $true

**Note** Change the database names to match your old DB’s

Mailbox Migration

In this section, I’ll show you how I personally move mailboxes to evenly spread them across the new Databases. We’ll be moving mailboxes in chunks, so we don’t overload our mailbox servers, by creating a set of CSV’s for each OldDB-to-NewDB.

**Note** A lot of Exchange admins like "group" mailbox type, department or an office location for specific databases; that goes against best practice. The reason is: if you lose that database or it becomes corrupt, you risk losing an entire group of mailboxes and if you had one for say "sales" all of those sales people would be down. Instead, we want to spread them around the entire org.

First I get a list of all mailboxes in the organization, by running the following cmdlet:

Get-Mailbox –Resultsize Unlimited | Select PrimarySMTPAddress | Export-CSV C:\Temp\All_Mailboxes.csv

Now, open the CSV in Excel and add a column where we will number them 1-12, down the column, which will correspond to our new databases…it will look like this:

 

New DB

PrimarySMTPAddress

1

JohnLennon@exchangeitup.com

2

GeorgeHarrison@exchangeitup.com

3

PaulMcCartnet@exchangeitup.com

4

RingoStarr@exchangeitup.com

5

RobertPlant@exchangeitup.com

6

JimmyPage@exchangeitup.com

7

JohnPaulJones@exchangeitup.com

8

JohnBonham@exchangeitup.com

9

JimiHendrix@exchangeitup.com

10

PeterYarrow@exchangeitup.com

11

PaulStookey@exchangeitup.com

12

MaryTravers@exchangeitup.com

1

DonHenley@exchangeitup.com

2

JoeWalsh@exchangeitup.com

3

TimSchmit@exchangeitup.com

4

DeaconFrey@exchangeitup.com

5

VinceGill@exchangeitup.com

6

NikkiSixx@exchangeitup.com

7

MickMars@exchangeitup.com

8

VinceNeil@exchangeitup.com

9

TommyLee@exchangeitup.com

10

GingerBaker@exchangeitup.com

11

JackBruce@exchangeitup.com

12

EricClapton@exchangeitup.com

1

DimebagDarrell@exchangeitup.com

2

VinniePaul@exchangeitup.com

3

TerryGlaze@exchangeitup.com

4

RexBrown@exchangeitup.com

5

PhilAnselmo@exchangeitup.com

6

RobZombie@exchangeitup.com

7

SeanYseult@exchangeitup.com

8

PhilBuerstatte@exchangeitup.com

9

JohnTempesta@exchangeitup.com

10

TimJeffs@exchangeitup.com

11

TomFive@exchangeitup.com

12

JYuenger@exchangeitup.com

**Note** 5 bonus points if you can name those bands without looking them up :)

Now that we have our Mailbox Master list, we’ll group the users by number. All 1’s will be grouped, all 2’s, all 3’s etc – like so:


New DB

Email Address

1

JohnLennon@exchangeitup.com

1

DonHenley@exchangeitup.com

1

DimebagDarrell@exchangeitup.com

2

GeorgeHarrison@exchangeitup.com

2

JoeWalsh@exchangeitup.com

2

VinniePaul@exchangeitup.com

3

PaulMcCartnet@exchangeitup.com

3

TimSchmit@exchangeitup.com

3

TerryGlaze@exchangeitup.com

4

RingoStarr@exchangeitup.com

4

DeaconFrey@exchangeitup.com

4

RexBrown@exchangeitup.com

5

RobertPlan@exchangeitup.com

5

VinceGill@exchangeitup.com

5

PhilAnselmo@exchangeitup.com

6

JimmyPage@exchangeitup.com

6

NikkiSixx@exchangeitup.com

6

RobZombie@exchangeitup.com

7

JohnPaulJones@exchangeitup.com

7

MickMars@exchangeitup.com

7

SeanYseult@exchangeitup.com

8

JohnBonham@exchangeitup.com

8

VinceNeil@exchangeitup.com

8

PhilBuerstatte@exchangeitup.com

9

JimiHendrix@exchangeitup.com

9

TommyLee@exchangeitup.com

9

JohnTempesta@exchangeitup.com

10

PeterYarrow@exchangeitup.com

10

GingerBaker@exchangeitup.com

10

TimJeffs@exchangeitup.com

11

PaulStookey@exchangeitup.com

11

JackBruce@exchangeitup.com

11

TomFive@exchangeitup.com

12

MaryTravers@exchangeitup.com

12

EricClapton@exchangeitup.com

12

JYuenger@exchangeitup.com

Now, we’ll split our number groups into separate CSV’s with “EmailAddress” as the heading, and we’ll name them something like DB01-MDB01.csv; DB01-MDB02.csv; DB01-MDB03.csv; DB01-MDB04.csv; DB01-MDB05.csv; DB01-MDB06.csv; DB01-MDB07.csv; DB01-MDB08.csv; DB01-MDB09.csv; DB01-MDB10.csv; DB01-MDB11.csv; DB01-MDB12.csv; DB02-MDB01.csv; DB02-MDB02.csv; etc…do this for each old database-to-new database (yes it will take a while, but it will pay off when you start migrating).

Your end results will look like:

DB01-MDB01.csv :

EmailAddress

JohnLennon@exchangeitup.com

DonHenley@exchangeitup.com

DimebagDarrell@exchangeitup.com

DB01-MDB02.csv:

EmailAddress

GeorgeHarrison@exchangeitup.com

JoeWalsh@exchangeitup.com

VinniePaul@exchangeitup.com

DB01-MDB03:

EmailAddress

PaulMcCartnet@exchangeitup.com

TimSchmit@exchangeitup.com

TerryGlaze@exchangeitup.com

Now, we’re ready to migrate mailboxes in bulk from our CSV’s.

In the EMS, run the following:

Import-CSV DB01-MDB01.csv | % {New-MoveRequest -Identity $_.EmailAddress -TargetDatabase MDB01 -BadItemLimit 1000 -AcceptLargeDataLoss}

**Note** Change the CSV name, and the TargetDatabase corresponding to our CSV.

**Note** I always use the BadItemLimit, which requires the AcceptLargeDataLoss switch, because some users who have giant mailboxes, which are very likely to have corrupted items, and we want to skip those and complete the move without errors. You will receive a warning in the Shell, that you may lose data; you can ignore that.

You may be asking “Wait! Why aren’t you using the EAC to migrate batches?!” Well, the EAC uses the uses the arbitration mailbox to manage moves, which generates TONS of transaction logs, which may fill up your disks very quickly! If that happens, you’d need to either enable circular logging or complete backups between each batch…ain’t nobody got time for that! Using the New-MoveRequest is a straight move, plus PowerShell is more fun ;)

To check your move status, run:

Get-MoveRequest | Get-MoveRequestStatistics

When the moves show as “100% completed”, run the following cmdlet to clear the moves (you must do this or else it will cause issue later if you ever needed to move them again or delete a database):

Get-MoveRequest –MoveStatus completed | Remove-MoveRequest –Confirm:$False

Deleting Old Databases

Ok, now that you’ve moved all mailboxes, before we can delete the old databases, we’ll make sure there are no lingering system mailboxes on them.

Run the following cmdlets to check each old database:

Get-Mailbox -Database DB01
Get-Mailbox -Database DB01 -archive
Get-Mailbox -Database DB01 -arbitration
Get-Mailbox -Database DB01 -publicfolder
Get-Mailbox -Database DB01 -monitoring
Get-Mailbox -Database DB01 –auditlog


**Note** Change “DB01” to your old database name(s)

If any of the above cmdlets result in hits, you’ll need to move those mailboxes to the new databases. For instance, to move Monitoring mailboxes, run:

Get-Mailbox -Database DB01 –monitoring | New-MoveRequest –TargetDatabase MDB01

**Note** I always move these mailboxes from the equivalent old DB to the new DB, for instance DB01-to-MDB01, DB02-to-MDB02 and so forth.

Run the above Get-MoveRequestStatistics to check status and Remove-Request cmdlets to clear these moves as well.

Once, you have all system mailboxes moved, we can delete the old database copies, then remove the DB, and delete the .ebd and log files:

In the EMS, run the following:

Remove-MailboxDatabaseCopy –Identity DB01\EXCH-MBX-02 –Confirm:$False
Remove-MailboxDatabaseCopy –Identity DB01\EXCH-MBX-03 –Confirm:$False

Do the above for each old database copy on the server it’s not hosted on. For instance, in the above example, DB01 is hosted on EXCH-MBX-01, so we’re removing the copies from EXCH-MBX-02/03.

You can also use the EAC, by going to Servers > Databases > Click the Remove link under passive copies:

EAC Remove DB Copy


Next, delete the databases, by running:

Remove-MailboxDatabase DB01 –Confirm:$False
Remove-MailboxDatabase DB02 –Confirm:$False
Remove-MailboxDatabase DB03 –Confirm:$False
Remove-MailboxDatabase DB04 –Confirm:$False
Remove-MailboxDatabase DB05 –Confirm:$False
Remove-MailboxDatabase DB06 –Confirm:$False

You’ll receive a warning/confirmation that the database has been removed, but you will need to manually delete the database and logs files.

To do that, browse to the path listed in the warning for both the .edb and log files, and CTRL-A, SHIFT-DEL. (SHIFT-DEL will bypass the Recycle Bin)

**Note** You may receive a warning that files are in use by noderunner or another service. If that happens, just give it a few minutes and try again...they'll go away eventually.

Once you have all database copies, databases and associated files deleted, we can delete the folders and mount points.

Navigate to E:\ (or whatever Volume you have your old DB’s stored on) and delete the DB01.db and DB01.log folders. Do this for each old database folder.

For the mount points, open Computer Management > Disk Management > Right-Click your Exchange Volume > Select your old DB mount point(s) and click Remove:


Disk management

Do the above for each old database mount point.

Congrats, you’re done! You now have shiny new databases, that are much smaller than the originals, which makes it easier to manage, easier to backup (if you’re one of those unlucky people whose management require backups even though a DAG doesn’t need it) and much less time for logs to ship in case of a failover.

No comments:

Post a Comment