The Joy of PowerShell for Exchange Administrators

My recent post outlining how important PowerShell is to Microsoft Exchange Server and how some of the concepts established in the implementation of Remote PowerShell in Exchange 2010 are finding their way into Windows Server 8 provoked a flurry of email messages, some of which posed the excellent question, “I’m struggling to master (or even understand) PowerShell; how do I make progress?”

Of course, such a question is impossible to answer, if only because the situations that we all find ourselves in vary so much. Those who are moving servers from Exchange 2003 to Exchange 2010 (or even Exchange 2007 or Office 365) are in a different place than those who already run Exchange 2007 or Exchange 2010 servers. Exchange 2003 doesn’t have a scripting language, so PowerShell is a real challenge for these administrators. I suspect that Exchange 2007 and Exchange 2010 administrators have at least opened up the Exchange Management Shell (EMS) and experimented with PowerShell, perhaps by running a few cmdlets to examine details of the Exchange configuration or by setting mailbox properties. This marks the high-water mark for many, who then escape back to the comfort of the GUI management environment provided by the Exchange Management Console (EMC).

The pity is that these folks might be missing the opportunity to mine the ever-increasing supply of wonderful PowerShell scripts and other snippets that populate the Internet. Exchange 2007 was released in late 2006, so there’s over five years worth of contributions from many talented people available free of charge to those who care to research, download, and test their work. Unlike a programming language such as C#, PowerShell scripts come ready to go. All of their secrets are exposed in the open and are available to be immediately turned to good use to improve how Exchange servers are managed by filling in the gaps that Microsoft has left in their tools. Although it’s true that some of the code written by those familiar with PowerShell will cause furrowed brows for newcomers, it’s also true that PowerShell is relatively easy to comprehend once you apply yourself.

For example, here’s a script posted by Exchang Server MVP Mike Pfeiffer on his blog. This script might look complex, but when you boil it down to its basics, the script accepts an input parameter of one or more Client Access Servers (CAS) and then interrogates those servers to discover the number of unique users who are currently connected to the servers via RPCs (for example, Outlook users) or HTTP (Outlook Web App).

function Get-CASActiveUsers {
      [Parameter(Position=0, ParameterSetName="Value", Mandatory=$true)]
      [Parameter(Position=0, ParameterSetName="Pipeline", ValueFromPipelineByPropertyName=$true, Mandatory=$true)]

process {
      switch($PsCmdlet.ParameterSetName) {
               "Value" {$servers = $ComputerName}
                "Pipeline" {$servers = $Name}
      $servers | %{
           $RPC = Get-Counter "\MSExchange RpcClientAccess\User Count" -ComputerName $_
           $OWA = Get-Counter "\MSExchange OWA\Current Unique Users" -ComputerName $_
          New-Object PSObject -Property @{
          Server = $_
          "RPC Client Access" = $RPC.CounterSamples[0].CookedValue
           "Outlook Web App" = $OWA.CounterSamples[0].CookedValue

This script is valuable because it allows you to figure out the load that a CAS is under before you remove it from production to perform maintenance such as applying a service pack or roll-up update. There’s no equivalent function in any of Microsoft’s management tools provided for Exchange so this is an example of how some relatively straightforward code can add real value. Best of all, it’s available free of charge and can easily be changed in whatever way you choose. And hopefully, if you improve the code, you’ll let Mike know and he can post the update on his blog. (You can also support Mike's work by buying a copy of his new Microsoft Exchange 2010 PowerShell Cookbook).  

Sometimes I even take my own advice (really!). Last weekend, I was helping a company to do some work to split off part of its IT infrastructure as a result of a corporate acquisition. The requirement arose to dump all of the membership of distribution groups before and after the event so that any unwanted entries in groups could be removed. Conceptually meeting this requirement seems simple enough: find all groups, expand group membership, dump to file. But groups can be nested and the task is more complex than it seems. A quick search turned up a script by Karl Mitschke to extract distribution group membership to an Excel file. After testing the script to ensure that it did what it claimed (always, but always, test scripts downloaded from the Internet), it didn't take long to wrap some code around the script to find all groups and create a unique file name for the output. Truly a great example of the usefulness of PowerShell in solving problems.

Still not convinced? Well, let’s take a look at the work of Pat Richard, another Exchange MVP, who recently posted an update to his New-PasswordReminder script. I think this script is great because it delivers real value out-of-the-box by scanning Active Directory for users whose passwords are soon to expire and then sends email to prompt the recipients to reset their password. There’s lots of good stuff to be mined from this script, including how to interrogate Active Directory with PowerShell, how to construct HTML format text, and how to create and send messages. I can easily imagine how these “chunks” of functionality could be repurposed.

Finally, we should acknowledge that Microsoft includes a number of very nice scripts in the Exchange kit. My personal favorite is ReDistributeActiveDatabases.ps1, which you can find in the scripts directory (the default location is C:\Program Files\Microsoft\Exchange\V14\Scripts) on any Exchange 2010 SP1 server. ReDistributeActiveDatabases is designed to move databases around within servers in a Database Availability Group (DAG) so that the active copy of each database is running on its preferred server. The idea is that, over time, database transitions will cause databases to end up on servers that might not be the best (for example, one server will host more active databases than it should) and that running this script will restore order to the situation. A good overview of how to run the script can be found in a post by Paul Cunningham. Again, you can amend the script to serve your own purpose if you think that it’s missing a feature. After all, the code is just PowerShell and can be edited with any text editor, including NotePad.

PowerShell might seem complex at the start, and there’s certainly hundreds of Exchange cmdlets to get to know over time (Exchange 2010 SP1 includes over six hundred). However, the joy of PowerShell is in the ability to discover, repurpose, and triumph with code that you or others write. That code can be anything from a one-liner to the type of scripts discussed here. And while you might conclude that you don’t need any of this because you’re heading to use Exchange Online in Office 365, you’ll soon discover that PowerShell offers lots of power and flexibility to Office 365 administrators, if you but care to use it.

By the way, if you're inspired to look for some books to learn about PowerShell, I previously posted my list of recommended PowerShell reading to get you started.

Hide comments


  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.