Hello Plebeians (I totally had to spell check that word… Man I am a filthy pleb)!

I keep writing this post and then deleting it all because it’s just well… Not very funny. I really hate when I can’t be funny, it’s akin to waking up in the morning and doing 30 push ups and 40 sit ups and 50 squats, only to walk into the bathroom and see you are still a bloated 900 lb fat ass. You see, you feel all warm and fuzzy at the start, because you are working so hard, but then you remember the 22 hundred Ding Dongs you ate the night before and and then you start to cry, buckets of straight lard. So on to writing it for the umpteenth time. (Wow, apparently umpteenth is a registered word in my spell check… No squiggly lines today!)

So I got an email from a potential client who said they were trying to do some pretty amazing stuff with Exchange. Normally when I hear these words I am smote down with visions of some jerk with his hand on his crotch and about 150 users planning a ‘Geo-Redundant’ Exchange environment. (HINT: Just because you put your servers in different closets in your office building doesn’t mean you are Geo-Redundant. ‘Geo’ implies located in a Geographically distinct region, say another state, or country, or continent.)

But this time I was sorely mistaken. Instead of someone who needed to be taught about how Active Directory sites ‘revolutionize’ how their remote sites authenticate, I was told that they had to create a proof of concept that would accept 100 messages a second. Now that’s an amazing concept! You’d want an army of servers to do that! Apparently not, they were planning to use 4 servers and 25 messages each. That’s like asking a bull to walk carefully through this China shop, it’s just not going to happen.

So after a long discussion about Exchange design and what their custom application does, I decided that it should be ‘theoretically’ (If by now you haven’t noticed the extended use of single quotes, you’re not paying attention! These are to stress that I am in fact making air quotes at the screen every time I write them… Which makes the whole typing thing excessively difficult to do… Do you see the things I do for you??? DO YOU!?) possible, but I didn’t know the exact ramifications to say the least, and that we will just have to test it and see.

For our setup (And against the design I laid out, though admittedly, they had already deployed it like this, so I guess effort vs results it’s fine they went this way.) we deployed four Exchange 2010 servers with all roles on each. They each were 8 core virtual machines with 32 gigs of memory. (Yeah, these had some serious… “Tracks of land” if you know what I mean!) We also had each one installed with two SSDs. (Well, virtual things can’t really have “installed” used as a verb. THEY GOT TWO SSDs! STOP JUDGING ME!)

Now another piece of info I should share. The custom application that they had required that emails be sent in, hit one mailbox, then be forwarded from that mailbox to another, then be pulled from there to an archival vault. They decided that the first mailbox should actually be mailboxes, and then the second archive target be a single mailbox. This is per server. (I know I know, it’s more convoluted than when your 12 year old best friend tried to explain where the clitoris is… I digress, again all before I could impact the over all design of the system.)

So the first thing I did was set up two databases, one for each mailbox set, the ‘receiving mailboxes’ and the ‘archiving mailbox.’ This worked spectacularly! A lot better than the time I asked that prostitute to put on elf ears and call me “Snow Daddy Santa.” (Which, as it turns out, is not that odd of a request, she’d turned it down a few times before I even asked for it! SO MUCH FOR MAKING ME FEEL SPECIAL!)

Everything was unicorns and rainbows and we were all standing around shaking each other’s hands and smoking big cigars, like Hera had just split my head open and out popped Exchange! (Aww, it’s such a cute little environment! Yes it is! Yes it is! *squeezes cheeks far too hard*) This did not last for long though as I received a phone call from them two days later exclaiming that their databases were growing to enormous sizes even after they’d deleted all the emails! (And I had set the deleted items to retain for 0 days, or just not.)

I’m going to take this moment to explain the difference between awesome clients, and crappy clients. Awesome clients, like these ones, understand that they are venturing into new and uncharted territories. (To boldly go where no client has gone before!) And so when stuff breaks, which I promise it will, they call and ask for help. This is a reasonable reaction to me not divining that this sort of thing would happen. Crappy clients on the other hand call and immediately start telling me I need to ‘Give them more confidence’ or ‘Should have foreseen this.’ Are you kidding me!? Do you seriously think that I’ve got every single KB article ever published by Microsoft stored in my head??? (This comes out because I dealt with both clients in the same day, and the awesome client kept me up until midnight looking at their issue, while the crappy one would have had their phone calls ignored.)

So as it turns out (I should have known this) Exchange databases need time to pick up after themselves. When they are writing, they write contiguous files so that they can go back and read their databases better. This leaves a lot of white space. In this case, ALL white space. (To the tune of about 400 GB) This database was whiter than Weird Al in his spoof of that Chamillionaire song. You see, Exchange will clean up after itself, while it does a thing called an Online Maintenance, but this only happens every once in a while and tends to kill performance, which is something we don’t want to happen. So the other option is to offline the database and use ESEUTIL (Ahhh, ESEUTIL, you’ve given me more nightmares than I care to admit.) which requires that they offline a database so ew… and it also means that they need enough disk space to house the database twice, which doesn’t give you much time to get it together. So we had to get inventive.

As always on this blog, inventive means one thing! (You know what time it is! TO THE CRAYON CORNER!):

$databaseNameA = "Mailbox Database 1"
$databaseNameB = "Mailbox Database 2"
$exchServer = "ExchangeServer42"

$databaseA = Get-Mailbox -Database $databaseNameA
$databaseB = Get-Mailbox -Database $databaseNameB
if($databaseA)
    {
    $count = $databaseA.Count
    foreach($mailbox in $databaseA)
        {
        New-MoveRequest -Identity $mailbox -TargetDatabase $databaseNameB
        }
    }
if($databaseB)
    {
    $count = $databaseB.Count
    foreach($mailbox in $databaseB)
        {
        New-MoveRequest -Identity $mailbox -TargetDatabase $databaseNameA
        }
    }
$check = (Get-MoveRequest -MoveStatus Completed).Count
while($check -lt $count)
    {
    $check = Get-MoveRequest -MoveStatus Completed
    }
Get-MoveRequest -MoveStatus Completed | Remove-MoveRequest -Confirm:$false
Stop-Service "Process"
Stop-Process Process
Start-Service "Process"
$check = $null
if($databaseA)
    {
    $check = Get-Mailbox -Database $databaseNameA
    if($check)
        {
        Write-Host -ForegroundColor Red "There is still a mailbox on $databaseNameA, please verify mailbox moves worked correctly"
        }
    else
        {
        Dismount-Database $databaseNameA -Confirm:$false
        Remove-MailboxDatabase $databaseNameA -Confirm:$false
        Remove-Item F:\database\$($databaseNameA).edb
        Remove-Item F:\database\LogFiles\$($databaseNameA) -Force -Confirm:$false -Recurse
        New-Item -Name $databaseNameA -Path F:\database\LogFiles -ItemType Directory
        New-MailboxDatabase $databaseNameA -edbfilepath F:\database\$($databaseNameA).edb -logfolderpath F:\database\LogFiles\$($databaseNameA) -Server $exchServer
        Set-MailboxDatabase $databaseNameA -DeletedItemRetention 0 -MailboxRetention 0 -ProhibitSendReceiveQuota 500GB -ProhibitSendQuota 500GB -CircularLoggingEnabled $true
        Mount-Database $databaseNameA
        }
    }
if($databaseB)
    {
    $check = Get-Mailbox -Database $databaseNameB
    if($check)
        {
        Write-Host -ForegroundColor Red "There is still a mailbox on $databaseNameB, please verify mailbox moves worked correctly"
        }
    else
        {
        Dismount-Database $databaseNameB -Confirm:$false
        Remove-MailboxDatabase $databaseNameB -Confirm:$false
        Remove-Item F:\database\$($databaseNameB).edb
        Remove-Item F:\database\LogFiles\$($databaseNameB) -Force -Confirm:$false -Recurse
        New-Item -Name $databaseNameB -Path F:\database\LogFiles -ItemType Directory
        New-MailboxDatabase $databaseNameB -edbfilepath F:\database\$($databaseNameB).edb -logfolderpath F:\database\LogFiles\$($databaseNameB) -Server $exchServer
        Set-MailboxDatabase $databaseNameB -DeletedItemRetention 0 -MailboxRetention 0 -ProhibitSendReceiveQuota 500GB -ProhibitSendQuota 500GB -CircularLoggingEnabled $true
        Mount-Database $databaseNameB
        }
    }
Expand

I changed some of the names here and there, but by and large you can just modify the top variables to names that you want and you are good to go. Some cool notes are that it will not try to dismount the database until all the mailboxes have finished moving off. It does this with a trick of counting move requests.

Another thing is it will error out and break if it does still detect mailboxes. (This is where I should put another white person joke… But I am not that low brow… Seriously people, what do you think this is…?)

A key point with this though was that you had to create two databases for each database, which we appended with DBA and DBB so that it could switch back and forth.

Anyway, I thought it was a fun little script, and I’m going to be adding a post soon with a ‘Get to da chopper’ style evacuation of a database followed by a deleted and recreate. I might even go so far as to delete and recreate it in the exact same way so that it can be used in an enterprise environment to just recover disk space.

As always let me know what you think in the comments below! (Unless it’s bad, I have a really fragile sense of self here, and I would be crushed if you didn’t like it. Really I would.)

Leave a Reply

Your email address will not be published. Required fields are marked *