PowerShell for Exchange 2007: Less Work, More Play

Get comfortable with PowerShell and the Exchange Management Shell using these tips and learning shortcuts.

I'd love to tell you that PowerShell is the easiest thing in the world to learn -- and that's just what many have been saying. I hate to be the bearer of bad news, but that's not exactly true. Are there some aspects of the technology that are easy to learn? Absolutely. Will it take some effort to master the product's complete range of capabilities? Certainly. So let's take it from the top with a look at how PowerShell can drive Exchange.

PowerShell and Exchange 2007
Before installing Exchange 2007, PowerShell must be installed first. For Windows Server 2003 you have to download PowerShell from Microsoft, whereas for Windows Server 2008 you can simply install it directly from the Add Features Wizard. Once PowerShell is installed you can begin using it immediately -- there's no need to wait until Exchange is installed.

You're welcome to try a few simple cmdlets -- pronounced command-lets -- to help you feel more comfortable. You might want to give your old cmdline favorites like cls, cd, del, dir and so forth, a whirl. At first, this may give you the feeling you're really using these actual commands from days of yore. But they're actually aliases for your common DOS commands that can help you get comfortable. Want to see more of these aliases? Just type in alias at the prompt and you'll see a list of the commands needed for actually porting to the PowerShell world.

So now you're settling in. You likely already understand PowerShell and its purpose -- that it's a command-line shell and a scripting language to be used by IT admins to perform administrative work, as well as by developers who do a lot of work through the use of commands. But how does PowerShell relate to Exchange?

If you've worked with previous versions of Exchange -- Exchange 2000, for example -- you may have noticed that locating settings can sometimes be impossible. An Exchange redesign, which was necessary, included the GUI but also allowed PowerShell to show its strength. Through PowerShell you can administer every aspect of Exchange 2007, while the GUI only allows you to perform roughly 80 percent of the same functionality. Upon installation of Exchange, there's a snap-in that extends PowerShell. To access the Exchange cmdlets you need to open the Exchange Management Shell (EMS), which you can quickly see offers a few extra goodies like a helpful Tip of the Day.

If you want to add the snap-in directly within the standard PowerShell type:

Add-Snapping *exchange* Or Add-Snapping 

If you wish to see a full list of cmdlets, type:


However, if you wish to see only Exchange cmdlets, type:

Figure 1
[Click on image for larger view.]
Figure 1. PowerShell and the Exchange Management Shell interfaces.

There are several aspects of the technology that are helpful within the EMS. The Welcome message, combined with reminders and the Tip of the Day -- all added by the EMS development team to help admins feel better about the experience -- will ease you back into the command-line world. To see the two side by side, take a look at Figure 1.

The Next Level
To get things started with the EMS, type get-mailbox to see a list of all mailboxes, their aliases, server names and quota limits. If you want to see a specific mailbox -- for jsmith, for instance -- you can type get-mailbox jsmith. If you only want to see mailboxes on a specific server you type get-mailbox -server servername. The table view is fine, but if you prefer to see items as a formatted list you can use the pipeline and format-list or fl for short. Now, your command might look something like get-mailbox | fl. You'll notice that this does more than show you the column headings we saw in the table format: in fact, it does a whole lot more.

Pipelining is the key to PowerShell's strength. It allows you to take the output from the first cmdlet and pipeline or assembly-line it into the next. For instance, if you want to set a quota limit of 500MB on sending for all the mailboxes on your server, it's as simple as get-mailbox | set-mailbox -prohibitsendquota 500MB.

You might be thinking, "I see how I might use this for all mailboxes or a single mailbox, but what if I want to filter it down to a grouping of users, or something specific to my needs for establishing this quota?" Well, you can perform simple username filters by typing in get-mailbox *John* or get-mailbox -filter "DisplayName -like '*John*'", which will give you all the mailboxes with John in the name. My guess is you'll need something a little more specific, perhaps for a department. Here you can use the -filter parameter. You might try get-user -filter "Department -like '*Shipping*'" to pull all mailboxes from the Shipping Department.

You may have noticed that we switched from the get-mailbox cmdlet to the get-user cmdlet. How did we know to do that? We know from trying the first one and getting a bright red error message, and then by investigating the cause of the problem. Microsoft provides plenty of assistance, and one of the TechNet links will show you the filterable properties for the release to manufacturing version, as well as filterable properties for Service Pack 1. It all starts here.

Notice in Table 1 how you can discern the proper parameters for the -filter settings and the cmdlets usable against them. You'll notice that the displayName property works with many different cmdlets, but that the department property only works with three. Therefore you need to use get-user in order to pull up users in the Shipping department.

PowerShell Hands-On

Learn directly from PowerShell experts by attending an upcoming TechMentor Conference. Here's a sample of the PowerShell sessions at our upcoming TechMentor shows:

  • "Securing PowerShell," Jeffery Hicks and Don Jones
  • "Understanding Scripting with PowerShell," Don Jones
  • "The Very Best Ways to Use Windows PowerShell," Don Jones
  • "Managing Active Directory Using Windows PowerShell," Jeffery Hicks

The next shows are in New York from Sept. 7-10, 2008, at the Marriott at the Brooklyn Bridge; and in Las Vegas, from Oct. 13-17, 2008, at the Mirage Hotel.

For more information or to register for an upcoming show, visit

You can see how this assists you in getting things done, but the EMS can also help you look at information quickly in your Exchange environment. Some developers, however, have a difficult time reading that information on the screen and want to pipe the information over to a file. This is easily done and there are several possible approaches. Let's say you want to pull all the users in Shipping into a simple .TXT file for easier viewing. You could type: get-user -filter "Department -like '*Shipping*'" | out-file c:\shipping.txt; and if you wanted it go to an .HTML file you could use |ConvertTo-Html > c:\shipping.html.

The Advanced Side of PowerShell
If this discussion has inspired you so far, you're probably itching to play around with PowerShell. You might even start to use the EMS when you have no other choice. In fact, there are some out tasks that can't be performed through the Exchange Management Console (EMC), like installing the anti-spam agents on the Hub Transport server role using the install-antispamagents.ps1 command. But what can we do to take the next step in your evolution with Exchange 2000 version 7?

To learn more about how EMS can duplicate nearly every action you perform in the EMC, take a look at the underlying one-liner PowerShell cmdlets, which are visible through the EMC itself. But more than that, they're easily copied using the Ctrl+C keys. This will allow you to study, tweak, re-use and master the commands and syntax.

For example, you can create a new distribution group through the EMC by opening the console and navigating to Recipient Configuration and then Distribution Group. In the Actions Pane select New Distribution Group. Then, select New Group or Existing Group, provide the name and alias information, view the Configuration Summary and click New. When you see that Completion screen, you'll notice the EMS cmdlet information with the option to hit Ctrl+C (as shown in Figure 2).

Figure 2
[Click on image for larger view.]
Figure 2. Using Ctrl+C can help you learn PowerShell syntax faster.

Capturing that information will yield the following perfect syntax that you can use in the future:

new-DistributionGroup -Name 'Shipping' 
-Type 'Distribution' -OrganizationalUnit '' 
-SamAccountName 'Shipping' -Alias 'Shipping'

Obviously, you can see PowerShell and the EMS are filled with cmdlets -- PowerShell ships with about 130 cmdlets, with Exchange adding another 360 -- and there are parameters to filter, pipeline and so forth.

There's one more syntax structure I need to explain: the use of the Where with things like {$_ characters. This may be what's holding you back from PowerShell, and I'll admit, it can seem scary at first.

For example, take a look at this command:

Get-MailboxStatistics | 
where {$_.DisconnectDate -ne $null} | 
Connect-Mailbox -Database "MB DB 1"

Essentially, this is a command that locates disconnected mailboxes found in the mailbox database called "MB DB 1" and then connects them. You aren't asking to be shown information regarding those mailboxes, although you could if you used a different variation of the command:

Get-MailboxStatistics -Database "MD DB 1" | 
where { $_.DisconnectDate -ne $null } 

The concept may be understandable visually: a cmdlet (Get-MailboxStatistics) a pipeline (|) and a Where construction (similar to an If-type statement).

Learn to Name Cmdlets

The way cmdlets are structured is with a "verb-noun" naming convention. Verbs to keep in mind include get, set, remove, test, enable, disable, install, uninstall, new, move and so forth. If you aren't sure of the noun portion of your cmdlet, just type in the first part and hit the Tab key; it will continue to scroll alphabetically through the cmdlets at your disposal. Once you're comfortable with the simple cmdlet structure, you can learn about pipelining -- although it's more of an assembly line in functionality. You start with a cmdlet and then pipeline the results, using the | character, over to a second cmdlet, which can process the results even further through filtering, sorting, grouping and so on.

Breaking this down, let's start with the DisconnectDate. Using the Get-MailboxStatistics you can query any number of different attributes like the DeletedItemCount, the LastLogonTime or LastLogoffTime. Simply put, if you want to know the Deleted Item Count and Last Logon Time for a user named John, you would type: get-mailboxstatistics -identity John | select DeletedItemCount,LastLogonTime

The -ne is a part of simple comparison operators, such as -eq for Equal To, -lt for Less Than and -ne for Not Equal To. In PowerShell, you can use these, logic operators or any other types of common conditional logic scripting you might already use.

Table 1
Property Name LDAP Display Name Description Cmdlets That Accept This Property
Department department This property contains the department of the user or contact Get-Contact
DisplayName displayName This property contains the ambiguous name resolution (ANR) search for the display name of the recipient. Get-CASMailbox
Get-Group Get-Mailbox

And to finish off the confusion, the {} is part of the Where clause and creates a block for your parameters, while the $_ is a special pipeline variable that acts as a placeholder for the current pipeline object. That may add to your confusion somewhat, but the point is that everything in the code you type is necessary and has a place.

Where to Go Next?
Through its one-liner aspects and pipelining, PowerShell is a powerful tool that's easy to script. But this new command-line interface, combined with the concept of scripting, scares some admins away from getting the most out of PowerShell and the EMS. Hopefully I've piqued your curiosity for more information and helped you overcome any fears you may have. The next step is to research additional sites and tools that can help you master PowerShell and the EMS.

Some great options include the following:


comments powered by Disqus

Subscribe on YouTube