Get DAG Database Distribution Function

PowerShell is great for repeatable administration shortcuts. I had created a script to a while ago that provided the mounted database distribution on each Database Availability Group server as part of a larger routine status reporting script. I found that this particular task of know the database distribution during the business day was helpful so I converted it to a function and included into my PowerShell profile. That way I could just run the Get-DagDbCount function without hunting around my various scripts directories trying find it and run it in script form.

It is really quite simple and makes use of an empty array populated with custom PSObjects with just server name and the number of mounted databases on it. Comments in the script should make everything clear on what is happening.


Using Search-Mailbox -SearchQuery

I had recently been given the task to search all mailboxes in an Exchange 2013 on premises organization for a specific keyword phrase. Naturally I attempted to use the eDiscovery and Litigation hold feature of the EAC but was severely limited by the number of mailboxes I could search at one time. As always I’m looking for a way to automate time consuming tasks. The PowerShell cmdlet New-MailboxSearch also didn’t help much either. After submitting a new search I attempted to view the status and I get a Watson error.


Enter the older but tried and true Search-Mailbox cmdlet. It took me a while to figure out how to use the -SearchQuery switch though. I had checked through the documentation on how to do Exchange Search using the Advanced Query Syntax (AQS) but nothing was very clear on my problem.

Read moreUsing Search-Mailbox -SearchQuery

Select A Random Transport Service

I’ve recently created a simple function to select a random transport service on Exchange 2013. My thoughts are that the cmdlet Send-MailMessage only allows specifying a single server and this has been bothering me for a while now. I have many scripts that provide output via email. So what if that server I’ve specified with Send-MailMessage is not available? The script is dead in the water when it comes to reporting. The ability to select a random transport service is nice if your messaging environment does not provide any other means (load balanced relay for example).

Read moreSelect A Random Transport Service

Customize the Outlook Web App Logon Page

Microsoft has provided some basic details on how to customize the Outlook Web App logon page (OWA) in Exchange 2013.  I’ve taken things a bit further and modified logon.aspx and logon.css to customize the OWA logon page with a PowerShell script.

It is important to note that at this time the script does not back up any of the files that it modifies.  Be warned, you should backup logon.aspx and logon.css.  As of Exchange 2013 SP1 CU6 they are located in the following directories:

Logon.aspx:  C:\Program Files\Microsoft\Exchange Server\V15\FrontEnd\HttpProxy\owa\auth

Logon.css:  C:\Program Files\Microsoft\Exchange Server\V15\FrontEnd\HttpProxy\owa\auth\15.0.995\themes\resources

Read moreCustomize the Outlook Web App Logon Page

Exchange DAG tuning

Deploying an Exchange DAG is the cornerstone of a highly available and site resilient messaging infrastructure. If you are reading this you should well know that an Exchange DAG is a group of no more than 16 mailbox servers that can exist in different subnets as well as different geographic regions.

In some environments there will likely be underlying network issues that are beyond your control as an application owner. Network issues such as latency and micro connectivity outages between data centers can prove to be an Exchange Administrators greatest headache. The results can result in unexpected failovers wreaking havoc on your SLA.

Read moreExchange DAG tuning

Exchange 2013 Mailbox Size Increases

Exchange 2013 mailbox size increase will occur when it is migrated from a previous version of Exchange.  This behavior is document in the Exchange 2013 release notes. The logic for this is explained extremely well on Tony Redmond’s Exchange Unwashed Blog where he states that it is a “store tax”.  The Exchange release notes describe the situation:

When you move a mailbox from a previous version of Exchange to Exchange 2013, the mailbox size reported may increase 30 percent to 40 percent. Disk space used by the mailbox database has not increased, only the attribution of space used by each mailbox has increased. The increase in mailbox size is due to the inclusion of all item properties into quota calculations, providing a more accurate computation of space consumed by items within their mailbox. This increase may cause some users to exceed their mailbox size quotas when their mailbox is moved to Exchange 2013.

The bottom line is that Exchange 2013 accurately identifies all of the information about mailbox items and counts it towards the mailbox quota.  Expect a 30 to 40 percent increase in mailbox size when moving to Exchange 2013!  You will certainly want to do some forecasting well ahead of any migrations as well as automating a quota increase for your users.

Send HTML email with PowerShell

Quite a few Exchange administrator like to send HTML email with PowerShell scripts for reporting to a group of people, and I’m no different. The code below is my solution to sending HTML email messages using the CSS style element to control all the formatting.  This includes font family, font size, table borders, and table header background color. The goal of the HTML design decisions here are an attempt to improve readability on smart phones by using a  smaller font size and color in the table headers to add some dimension.

Below is the head section of the HTML message and there a few things to take note of.  You will see at the end of each line there is an rn.  These are special characters used for formatting which creates a carriage return and new line.  On line 7 you will see the H3 tag which includes style for any H3 tag used in the HMTL messages.

When using the ConvertTo-HTML cmdlet and the -fragment tag you are only creating a table. Unfortunately there is no way to control the formatting of the HTML output and it is a bit of a mess. You can find additional information about the ConvertTo-HTML cmdlet on technet.

Finally you’ll want to put together various HTML sections and form the final HTML document that will be sent as a report. Be careful to make sure that your HTML document is well formed. As the complexity of your reports increases it become more likely you’ll make the mistake of adding extra HTML code that will cause some formatting headaches.

The body of the email message will appear as below:
PowerShell HTML table

The example script is below:


Recover from an Email Storm in Exchange Server

An important part of working with Exchange server is being prepared for and dealing with an email storm.  The term email storm has been associated with reply all behavior and NDR message loops.  An email storm can also be the result of a virus or worm infection causing a large number of messages to be sent within your Exchange organization.

Read moreRecover from an Email Storm in Exchange Server

Get DAG Mailboxes Faster with Start-Job

Have you ever needed to increase the speed of the get-mailbox cmdlet?   This Exchange PowerShell code is a building block that provides a way to get DAG mailboxes faster with start-job.  It will query the Database Availability Group within your Exchange organization and return all the mailbox databases.  Each mailbox database has an instance of get-mailbox run against it.

I’ve used the ForEach loop to process all mailbox databases individually and throttle how many jobs run at once.  This can be tuned to your liking and to the limits of what your environment can handle.  I’ve set the throttling to only run four jobs at a time in the code below.

The trick in this script is the IF and ELSE statements and the placement of the two start-job cmdlets.  The start-job cmdlet is necessary in the ELSE statement block otherwise the current pipeline object would get discarded before being processed once there are four jobs running.  Additionally, the wait-job -any cmdlet and switch will immediately start a new job when any currently running job is completed.

The very end of the script contains some cleanup code and uses the DO UNTIL statements to wait for all jobs to be completed before cleanup.  So just how much faster is this bit of code?  I’ve done a comparison between my code below and a single get-mailbox cmdlet that returns all mailboxes within the same DAG.

Get DAG Mailboxes Faster with Start-Job
Single Get-Mailbox cmdlet takes 10 minutes
Get DAG Mailboxes Faster with Start-Job
Start-Job takes three and a half minutes!

PowerGUI Script Editor