Add caching to mailbox creation load balancing script

In a previous post I instructed how to load balance new mailboxes across databases. In a large environment, however, this determination can take upwards of 90 seconds. Normally I don’t run the mailbox creation script at my company (our IT Security department does), but I ran it yesterday and it took 55 seconds to determine the database. That’s just too long for me.

So I decided to add what was going to be my fallback option in the first place: using a cached list. This code uses an xml file to keep track of the database to use at a given location and a timestamp of when that entry was last updated. The xml file uses the following format:

Set the $sourcexml variable to the full path to the file. The function that calls this code should set the $Location parameter to whatever value is stored in the id attribute of the site nodes. The xml file is opened, the timestamp for a given site name is returned, and compared to a time interval (in this case, 24 hours, but you can set it to anything you want). If less than 24 hours old, the database name in the site node is used. If more than 24 hours old, it will run the code to determine the database to use (from the other post). After the determination is made, it writes the database name and the current time back into the xml file and saves it.

The on-demand query for one site ran in 53 seconds through mailbox creation for the first run, but created the second mailbox in 11 seconds. That is much more tenable, at least for an impatient person like myself.

Load balance new mailbox creation across multiple databases and servers using PowerShell

I needed a way to have new mailboxes be automatically distributed across a list of databases on multiple servers, and I recalled seeing a script somewhere.  The blog post with those details can be found here [no longer available].  As the author points out, it can take a long time to build the hash table, too long for my requirements.  For example, one of my longer queries builds the table for 9 databases with over 5000 mailboxes in 58 seconds.  That is just way too  long for someone to feed a user account into to get a mailbox created.

So I broke down the query being used to find where efficiency could be improved.  The Get-ExchangeServer cmdlet slows the script down and can be avoided altogether by feeding the server list directly into the Get-MailboxDatabase cmdlet.  Additionally, I discovered just how inefficient the Exchange cmdlets are.  I already knew they were based on running other cmdlets for targets servers across a WAN that return not a lot of data, but this reinforced those findings.

To get away from the Exchange cmdlets, I query AD directly by instantiating ADSI in .NET manually.  Instead of slowly building the hash table I just take the record count of the search results and populate the table entry at once.  This reduced the time to completion from 58 seconds to 24 seconds.  These findings are consistent across different database counts and mailbox totals: 60% reduction in time.  While still too long for my taste, it certainly is much better than before and is within reason for the people at my company that make use of the script.

Since my script encompasses more than just the load balancing part (I create a GUI form where the location for the mailbox is selected, which feeds a list of appropriate servers to the function), this is just the part that creates the hash table with the database counts and returns the database with the lowest count:

Minor update to last backup report (1.3.1)

Version 1.3.1 fixes a small issue where the subject would still say everything is okay even though the threshold for the last backup had been exceeded.  (I didn’t set the scope of the variable correctly after moving part of the code into a function.)  Download.

Powershell one-liner to remotely get SSL certificate expiration

This is a quick and dirty way of retrieving the self-signed SSL certificate that Exchange 2007 servers use out of the box.  Get-ExchangeCertificate only works locally on the box that has the certificate…not fun when you have a long list to find out so you can build a list for renewing them.  This uses psexec to connect to the remote server and retrieve any personal certificates and display the expiration date.  Short and sweet.

Exchange 2007 backup script updated to v1.3

This update fixes reporting for public folder databases.  I failed to account for the fact that PF databases won’t be returned when using Get-MailboxDatabase.  The structure of the script has changed a little bit to accommodate that, but the resulting change in the output is only that PF databases will now be included (and storage groups that only had a PF database won’t report that no databases are present).  Download v1.3.

Exchange 2007 backup script updated to v1.2

I added notification of what the checkmark means, automatically load the Exchange snapin if not already, and append the subject of the email with a status summary.  If there are no backups that need attention, all okay is added.  If there are, it says that attention is needed.  This provides a quick way to know if anything needs attention.  Download the script here.