What this book covers
Chapter 1, PowerShell Key Concepts, introduces several PowerShell core concepts such as command syntax and parameters, working with the pipeline, and flow control with loops and conditional logic. The topics covered in this chapter lay the foundation for the remaining code samples in each chapter.
Chapter 2, Exchange Management Shell Command Tasks, covers day-to-day tasks and general techniques for managing Exchange from the command line. The topics include configuring manual remote shell connections, exporting reports to external files, sending e-mail messages from scripts, and scheduling scripts to run with the Task Scheduler.
Chapter 3, Managing Recipients, demonstrates some of the most common recipient-related management tasks, such as creating mailboxes, distribution groups, and contacts. You’ll also learn how to manage server-side inbox rules, out of office settings, and import user photos into the Active Directory.
Chapter 4, Managing Mailboxes, shows you how to perform various mailbox management tasks that include moving mailboxes, importing and exporting mailbox data, and the detection and repair of corrupt mailboxes. In addition, you’ll learn how to delete and restore items from a mailbox, manage the new public folders, and generate some basic reports.
Chapter 5, Distribution Groups and Address Lists, takes you deeper into distribution group management. The topics include distribution group reporting, distribution group naming policies, and allowing end users to manage distribution group membership. You’ll also learn how to create address lists and hierarchal address books.
Chapter 6, Mailbox Database Management, shows how to set database settings and limits. Report generation for mailbox database size, average mailbox size per database, and backup status is also covered in this chapter.
Chapter 7, Managing Client Access, covers the managing of ActiveSync, OWA, POP, and IMAP. It also covers the configuration of these components in Exchange 2013. We’ll also take a look at controlling connections from various clients, including ActiveSync devices.
Chapter 8, Managing Transport Service, explains the various methods used to control mail flow within your Exchange organization. You’ll learn how to create, send, and receive connectors, allow application servers to relay mail, and manage transport queues.
Chapter 9, High Availability, covers the implementation and management tasks related to Database Availability Groups (DAGs). Topics include creating DAGs, adding mailbox database copies, and performing maintenance on DAG members. It also covers the new feature called automatic reseed.
Chapter 10, Exchange Security, introduces the new Role Based Access Control (RBAC) permissions model. You’ll learn how to create custom RBAC roles for administrators and end users, and also how to manage mailbox permissions and implement SSL certificates.
Chapter 11, Compliance and Audit Logging, covers the new compliance and auditing features included in Exchange 2013. Topics such as archiving mailboxes and discovery search are covered here, as well as administrator and mailbox audit logging.
Chapter 12, Server Monitoring and Troubleshooting, shows you how to monitor and report on service availability and resource utilization using PowerShell core cmdlets and WMI. Event log monitoring and Exchange server role troubleshooting tactics are also covered.
Chapter 13, Scripting with the Exchange Web Services Managed API, introduces advanced scripting topics that leverage Exchange Web Services. In this chapter, you’ll learn how to write scripts and functions that go beyond the capabilities of the Exchange Management Shell cmdlets.
Appendix A, Common Shell Information, is a reference for the variables, scripts, and the filtering functions. These references will help you when writing scripts or running interactive.
Appendix B, Query Syntaxes, is a reference for the Advanced Query Syntax (AQS). Here are lots of different examples that can be used in the real world.
What you need for this book
To complete the recipes in this book, you’ll need the following:
- PowerShell v3, which is already installed by default on Windows 8 and Windows Server 2012.
- A fully operational lab environment with an Active Directory forest and Exchange organization.
- Ideally, your Exchange Servers will run Windows Server 2012, but they can run Windows Server 2008 R2, if needed.
- You’ll need to have at least one Microsoft Exchange 2013 server.
- It is assumed that the account you are using is a member of the Organization Management role group. The user account used to install Exchange 2013 is automatically added to this group.
- If possible, you’ll want to run the commands, scripts, and functions in this book from a client machine. The 64-bit version of Windows 8 with the Exchange 2013 Management Tools installed is a good choice. You can also run the tools on Windows 7. Each client will need some additional prerequisites in order to run the tools, see Microsoft’s TechNet documentation for full details.
- If you don’t have a client machine, you can run the Exchange Management Shell from an Exchange 2013 server.
- Chapter 13 requires the Exchange Web Services Managed API version 2.0, which can be downloaded fromhttp://www.microsoft.com/en-us/download/details.aspx?id=35371.
The code samples in this book should be run in a lab environment and fully tested before deployed into production. If you don’t have a lab environment setup, you can download the software from http://technet.microsoft.com/en-us/exchange/. Then build the servers on your preferred virtualization engine.
Who this book is for
This book is for messaging professionals who want to learn how to build real-world scripts with Windows PowerShell 3.0 and the Exchange Management Shell. If you are a network or systems administrator responsible for managing and maintaining the on-premise version of Exchange Server 2013, then this book is for you.
The recipes in this Cookbook touch on each of the core Exchange 2013 server roles, and require a working knowledge of the supporting technologies, such as Windows Server 2008, 2008 R2 or 2012, Active Directory, and DNS.
All of the topics in this book are focused on the on-premises version of Exchange 2013, and we will not cover Microsoft’s hosted version of Exchange Online through Office 365. However, the concepts you’ll learn in this book will allow you to hit the ground running with that platform since it will give you an understanding of PowerShell’s command syntax and object-based nature.
In this book, you will find a number of styles of text that distinguish between different kinds of information. Here are some examples of these styles, and an explanation of their meaning.
Code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles are shown as follows: “We can read the content of an external file into the shell using the
Commands and blocks of code are set as follows:
Get-Mailbox –ResultSize Unlimited | Out-File C:\report.txt
Commands like this can be invoked interactively in the shell, or from within a script or function.
Most of the commands you’ll be working with will be very long. In order for them to fit into the pages of this book, we’ll need to use line continuation. For example, here is a command that creates a mailbox:
New-Mailbox -UserPrincipalName email@example.com ` -FirstName John ` -LastName Smith ` -Alias jsmith ` -Database DB1 ` -Password $password
Notice that the last character on each line is the backtick (
`) symbol, also referred to as the grave accent. This is PowerShell’s line continuation character. You can run this command as is, but make sure there aren’t any trailing spaces at the end of each line. You can also remove the backticks and carriage returns and run the command on one line. Just ensure the spaces between the parameters and arguments are maintained.
You’ll also see long pipeline commands formatted like the following example:
Get-Mailbox -ResultSize Unlimited | Select-Object DisplayName,ServerName,Database | Export-Csv c:\mbreport.csv -NoTypeInformation
PowerShell uses the pipe character (
|) to send object output from a command down the pipeline so it can be used as input by another command. The pipe character does not need to be escaped. You can enter the previous command as is, or you can format the command so that everything is on one line.
Any command-line input or output that must be done interactively at the shell console is written as follows:
[PS] C:\>Get-Mailbox administrator | ft ServerName,Database -Auto ServerName Database ---------- -------- mbx1 DB01
New terms and important words are shown in bold. Words that you see on the screen, in menus or dialog boxes for example, appear in the text like this: “Click on the Exchange Management Shell shortcut”.
Warnings or important notes appear in a box like this.
Feedback from our readers is always welcome. Let us know what you think about this book—what you liked or may have disliked. Reader feedback is important for us to develop titles that you really get the most out of.
To send us general feedback, simply send an e-mail to
<firstname.lastname@example.org>, and mention the book title via the subject of your message.
If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, see our author guide on www.packtpub.com/authors.
Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase.
Downloading the example code
You can download the example code files for all Packt books you have purchased from your account athttp://www.PacktPub.com. If you purchased this book elsewhere, you can visit http://www.PacktPub.com/support and register to have the files e-mailed directly to you.
Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books—maybe a mistake in the text or the code—we would be grateful if you would report this to us. By doing so, you can save other readers from frustration and help us improve subsequent versions of this book. If you find any errata, please report them by visiting http://www.packtpub.com/support, selecting your book, clicking on the errata submission form link, and entering the details of your errata. Once your errata are verified, your submission will be accepted and the errata will be uploaded on our website, or added to any list of existing errata, under the Errata section of that title. Any existing errata can be viewed by selecting your title from http://www.packtpub.com/support.
Piracy of copyright material on the Internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works, in any form, on the Internet, please provide us with the location address or website name immediately so that we can pursue a remedy.
Please contact us at
<email@example.com> with a link to the suspected pirated material.
We appreciate your help in protecting our authors, and our ability to bring you valuable content.
You can contact us at
<firstname.lastname@example.org> if you are having a problem with any aspect of the book, and we will do our best to address it.
Chapter 1. PowerShell Key Concepts
In this chapter, we will cover the following:
- Using the help system
- Understanding command syntax and parameters
- Understanding the pipeline
- Working with variables and objects
- Formatting output
- Working with arrays and hash tables
- Looping through items
- Creating and running scripts
- Using flow control statements
- Creating custom objects
- Creating PowerShell functions
- Setting up a profile
So, your organization has decided to move to Exchange Server 2013 to take advantage of the many exciting new features such as integrated e-mail archiving, discovery capabilities, and high availability functionality. Like it or not, you’ve realized that PowerShell is now an integral part of Exchange Server management and you need to learn the basics to have a point of reference for building your own scripts. That’s what this book is all about. In this chapter, we’ll cover some core PowerShell concepts that will provide you with a foundation of knowledge for using the remaining examples in this book. If you are already familiar with PowerShell, you may want to use this chapter as a review or as a reference for later on after you’ve started writing scripts.
If you’re completely new to PowerShell, its concept may be familiar if you’ve worked with Unix command shells. Like Unix-based shells, PowerShell allows you to string multiple commands together on one line using a technique called pipelining. This means that the output of one command becomes the input for another. But, unlike Unix shells that pass text output from one command to another, PowerShell uses an object model based on the .NET Framework, and objects are passed between commands in a pipeline, as opposed to plain text. From an Exchange perspective, working with objects gives us the ability to access very detailed information about servers, mailboxes, databases, and more. For example, every mailbox you manage within the shell is an object with multiple properties, such as an e-mail address, database location, or send and receive limits. The ability to access this type of information through simple commands means that we can build powerful scripts that generate reports, make configuration changes, and perform maintenance tasks with ease.
Performing some basic steps
To work with the code samples in this chapter, follow these steps to launch the Exchange Management Shell:
- Log on to a workstation or server with the Exchange Management Tools installed.
- You can connect using remote PowerShell if you for some reason don’t have Exchange Management Tools installed. Use the following command:
$Session = New-PSSession -ConfigurationName Microsoft.Exchange ` -ConnectionUri http://tlex01/PowerShell/ ` -Authentication Kerberos ` Import-PSSession $Session
- Open the Exchange Management Shell by clicking on Start | All Programs | Microsoft Exchange Server 2013. Or if you’re using Windows 2012 Server, it can be found by pressing the Windows key.
- Click on the Exchange Management Shell shortcut.
Remember to start the Exchange Management Shell using Run As Admin to avoid permission problems.
In the chapter, notice that in the examples of cmdlets, I have used the back tick (
`) character for breaking up long commands into multiple lines. The purpose with this is to make it easier to read. The back ticks are not required and should only be used if needed.
Using the help system
The Exchange Management Shell includes over 750 cmdlets (pronounced command-lets), each with a set of multiple parameters. For instance, the New-Mailbox cmdlet accepts more than 60 parameters, and the Set-Mailbox cmdlet has over 160 available parameters. It’s safe to say that even the most experienced PowerShell expert would be at a disadvantage without a good help system. In this recipe, we’ll take a look at how to get help in the Exchange Management Shell.
How to do it…
To get help information for a cmdlet, type Get-Help, followed by the cmdlet name. For example, to get help information about the Get-Mailbox cmdlet, run the following command:
Get-Help Get-Mailbox -full
Downloading the example code
You can download the example code files for all Packt books you have purchased from your account at http://www.PacktPub.com. If you purchased this book elsewhere, you can visit http://www.PacktPub.com/support and register to have the files e-mailed directly to you.
How it works…
When running Get-Help for a cmdlet, a synopsis and description for the cmdlet will be displayed in the shell. The Get-Help cmdlet is one of the best discovery tools to use in PowerShell. You can use it when you’re not quite sure how a cmdlet works or what parameters it provides.
You can use the following switch parameters to get specific information using the Get-Help cmdlet:
Detailed: The detailed view provides parameter descriptions and examples, and uses the following syntax:
Examples: You can view multiple examples of how to use a cmdlet by running the following syntax:
Full: Use the following syntax to view the complete contents of the help file for a cmdlet:
Some parameters accept simple strings as input, while others require an actual object. When creating a mailbox using the New-Mailbox cmdlet, you’ll need to provide a secure string object for the -Password parameter. You can determine the data type required for a parameter using Get-Help:
You can see from the command output that we get several pieces of key information about the -Password parameter. In addition to the required data type of <SecureString>, we can see that this is a named parameter. It is required when running the New-Mailbox cmdlet and it does not accept wildcard characters. You can use Get-Help when examining the parameters for any cmdlet to determine whether or not they support these settings.
You could run Get-HelpNew-MailboxExamples to determine the syntax required to create a secure string password object and how to use it to create a mailbox. This is also covered in detail in the recipe entitled Adding, modifying, and removing mailboxes in Chapter 3, Managing Recipients.
There will be times when you’ll need to search for a cmdlet without knowing its full name. In this case, there are a couple of commands you can use to find the cmdlets you are looking for.
To find all cmdlets that contain the word “mailbox”, you can use a wildcard, as shown in the following command:
You can use the -Verb parameter to find all cmdlets starting with a particular verb:
Get-Command -Verb Set
To search for commands that use a particular noun, specify the name with the -Noun parameter:
Get-Command -Noun Mailbox
The Get-Command cmdlet is a built-in PowerShell core cmdlet, and it will return commands from both Windows PowerShell as well as the Exchange Management Shell. The Exchange Management Shell also adds a special function called Get-Ex command that will return only Exchange-specific commands.
In addition to getting cmdlet help for cmdlets, you can use GetHelp to view supplementary help files that explain general PowerShell concepts that focus primarily on scripting. To display the help file for a particular concept, type Get-Helpabout_ followed by the concept name. For example, to view the help for the core PowerShell commands, type the following:
You can view the entire list of conceptual help files using the following command:
Don’t worry about trying to memorize all the Exchange or PowerShell cmdlet names. As long as you can remember GetCommand and Get-Help, you can search for commands and figure out the syntax to do just about anything.
Getting help with cmdlets and functions
One of the things that can be confusing at first is the distinction between cmdlets and functions. When you launch the Exchange Management Shell, a remote PowerShell session is initiated to an Exchange server and specific commands, called proxy functions, are imported into your shell session. These proxy functions are essentially just blocks of code that have a name, such as GetMailbox, and that correspond to the compiled cmdlets installed on the server. This is true even if you have a single server and when you are running the shell locally on a server.
When you run the Get-Mailbox function from the shell, data is passed between your machine and the Exchange server through a remote PowerShell session. The Get-Mailbox cmdlet is actually executing on the remote Exchange server, and the results are being passed back to your machine. One of the benefits of this is that it allows you to run the cmdlets remotely regardless of whether your servers are on-premise or in the cloud. Additionally, this core change in the tool set is what allows Exchange 2010 and 2013 to implement its new security model by allowing and restricting which cmdlets administrators and end users can actually use through the shell or the web-based control panel.
We’ll get into the details of all this throughout the remaining chapters in the book. The bottom line is that, for now, you need to understand that, when you are working with the help system, the Exchange 2013 cmdlets will show up as functions and not as cmdlets.
Consider the following command and the output:
Here we are running GetCommand against a PowerShell v3 core cmdlet. Notice that the CmdletType shows that this is a Cmdlet.
Now try the same thing for the Get-Mailbox cmdlet:
As you can see, the CommandType for the Get-Mailbox cmdlet shows that it is actually a Function. So, there are a couple of key points to take away from this. First, throughout the course of this book, we will refer to the Exchange 2013 cmdlets as cmdlets, even though they will show up as functions when running GetCommand. Second, keep in mind that you can run Get-Help against any function name, such as Get-Mailbox, and you’ll still get the help file for that cmdlet. But if you are unsure of the exact name of a cmdlet, use Get-Command to perform a wildcard search as an aid in the discovery process. Once you’ve determined the name of the cmdlet you are looking for, you can run GetHelp against that cmdlet for complete details on how to use it.
Try using the help system before going to the Internet to find answers. You’ll find that the answers to most of your questions are already documented within the built-in cmdlet help.
The Understanding command syntax and parameters recipe
The Manually configuring remote PowerShell connections recipe in Chapter 2, Exchange Management Shell Common Tasks
The Working with Role Based Access Control (RBAC) recipe in Chapter 10, Exchange Security
Understanding command syntax and parameters
Windows PowerShell provides a large number of built-in cmdlets that perform specific operations. The Exchange Management Shell adds an additional set of PowerShell cmdlets used specifically for managing Exchange. We can also run these cmdlets interactively in the shell, or through automated scripts. When executing a cmdlet, parameters can be used to provide information, such as which mailbox or server to work with, or which attribute of those objects should be modified. In this recipe, we’ll take a look at basic PowerShell command syntax and how parameters are used with cmdlets.
How to do it…
When running a PowerShell command, you type the cmdlet name, followed by any parameters required. Parameter names are preceded by a hyphen (-) followed by the value of the parameter. Let’s start with a basic example. To get mailbox information for a user named testuser, use the following command syntax:
Get-Mailbox –Identity testuser
Alternatively, the following syntax also works and provides the same output, because the –Identity parameter is a positional parameter:
Most cmdlets support a number of parameters that can be used within a single command. We can use the following command to modify two separate settings on the testuser mailbox:
Set-Mailbox testuser –MaxSendSize 5mb –MaxReceiveSize 5mb
How it works…
All cmdlets follow a standard verb-noun naming convention. For example, to get a list of mailboxes you use the Get-Mailbox cmdlet. You can change the configuration of a mailbox using the Set-Mailbox cmdlet. In both examples, the verb (Get or Set) is the action you want to take on the noun (Mailbox). The verb is always separated from the noun using the hyphen (-) character. With the exception of a few Exchange Management Shell cmdlets, the noun is always singular.
Cmdlet names and parameters are not case sensitive. You can use a combination of upper and lowercase letters to improve the readability of your scripts, but it is not required.
Parameter input is either optional or required, depending on the parameter and cmdlet you are working with. You don’t have to assign a value to the c parameter since it is not required when running the Get-Mailbox cmdlet. If you simply run Get-Mailbox without any arguments, the first 1,000 mailboxes in the organization will be returned.
If you are working in a large environment with more than 1,000 mailboxes, you can run the Get-Mailbox cmdlet setting the -ResultSize parameter to Unlimited to retrieve all of the mailboxes in your organization.
Notice that in the first two examples we ran Get-Mailbox for a single user. In the first example, we used the -Identity parameter, but in the second example we did not. The reason we don’t need to explicitly use the -Identity parameter in the second example is because it is a positional parameter. In this case, -Identity is in position 1, so the first argument received by the cmdlet is automatically bound to this parameter. There can be a number of positional parameters supported by a cmdlet, and they are numbered starting from one. Other parameters that are not positional are known as named parameters, meaning we need to use the parameter name to provide input for the value.
The -Identity parameter is included with most of the Exchange Management Shell cmdlets, and it allows you to classify the object you want to take an action on.
The -Identity parameter used with the Exchange Management Shell cmdlets can accept different value types. In addition to the alias, the following values can be used: ADObjectID, Distinguished name, Domain\Username, GUID, LegacyExchangeDN, SmtpAddress, and User principal name (UPN).
Unlike the Get-Mailbox cmdlet, the -Identity parameter is required when you are modifying objects, and we saw an example of this when running the Set-Mailbox cmdlet. This is because the cmdlet needs to know which mailbox it should modify when the command is executed. When you run a cmdlet without providing input for a required parameter, you will be prompted to enter the information before execution.
In order to determine whether a parameter is required, named, or positional, supports wildcards, or accepts input from the pipeline, you can use the Get-Help cmdlet which is covered in the next recipe in this chapter.
Multiple data types are used for input depending on the parameter you are working with. Some parameters accept string values, while others accept integers or Boolean values. Boolean parameters are used when you need to set a parameter value to either true or false. PowerShell provides built-in shell variables for each of these values using the $true and $false automatic variables.
For a complete list of PowerShell v3 automatic variables, run Get-Help about_automatic_variables. Also see Appendix A, Common Shell Information, for a list of automatic variables added by the Exchange Management Shell.
For example, you can enable or disable a send connector using the Set-SendConnector cmdlet with the -Enabled parameter:
Set-SendConnector Internet -Enabled $false
Switch parameters don’t require a value. Instead they are used to turn something on or off, or to either enable or disable a feature or setting. One common example of when you might use a switch parameter is when creating an archive mailbox for a user:
Enable-Mailbox testuser -Archive
PowerShell also provides a set of common parameters that can be used with every cmdlet. Some of the common parameters, such as the risk mitigation parameters (-Confirm and -Whatif), only work with cmdlets that make changes.
For a complete list of common parameters, run Get-Helpabout_CommonParameters.
Risk mitigation parameters allow you to preview a change or confirm a change that may be destructive. If you want to see what will happen when executing a command without actually executing it, use the -WhatIfparameter :
When making a change, such as removing a mailbox, you’ll be prompted for confirmation, as shown in the following screenshot:
To suppress this confirmation set the -Confirm parameter to false:
Remove-Mailbox testuser -Confirm:$false
Notice here that when assigning the $false variable to the -Confirm parameter, we had to use a colon immediately after the parameter name and then the Boolean value. This is different to how we assigned this value earlier with the -Enabled parameter when using the Set-SendConnector cmdlet. Remember that the -Confirm parameter always requires this special syntax, and while most parameters that accept a Boolean value generally do not require this, it depends on the cmdlet with which you are working. Fortunately, PowerShell has a great built-in help system that we can use when we run into these inconsistencies. When in doubt, use the help system, which is covered in detail in the next recipe.
Cmdlets and parameters support tab completion. You can start typing the first few characters of a cmdlet or a parameter name and hit the tab key to automatically complete the name or tab through a list of available names. This is very helpful in terms of discovery and can serve as a bit of a time saver.
In addition, you only need to type enough characters of a parameter name to differentiate it from another parameter name. The following command using a partial parameter name is completely valid:
Set-Mailbox -id testuser –Office Sales
Here we’ve used id as a shortcut for the -Identity parameter. The cmdlet does not provide any other parameters that start with id, so it automatically assumes you want to use the -Identity parameter.
Another helpful feature that some parameters support is the use of wildcards. When running the Get-Mailbox cmdlet, the -Identity parameter can be used with wildcards to return multiple mailboxes that match a certain pattern:
Get-Mailbox -id t*
In this example, all mailboxes starting with the letter “t” will be returned. Although this is fairly straightforward, you can refer to the help system for details on using wildcard characters in PowerShell by running Get-Help about_Wildcards.
Parameter values containing a space need to be enclosed in either single or double quotation marks. The following command would retrieve all of the mailboxes in the Sales Users OU in Active Directory. Notice that since the OU name contains a space, it is enclosed in single quotes:
Get-Mailbox -OrganizationalUnit ‘contoso.com/Sales Users/Phoenix’
Use double quotes when you need to expand a variable within a string:
$City = ‘Phoenix’
Get-Mailbox -OrganizationalUnit “contoso.com/Sales Users/$City”
You can see here that we first create a variable containing the name of the city, which represents a sub OU under Sales Users. Next, we include the variable inside the string used for the organizational unit when running the Get-Mailbox cmdlet. PowerShell automatically expands the variable name inside the double quoted string where the value should appear and all mailboxes inside the Phoenix OU are returned by the command.
Quoting rules are documented in detail in the PowerShell help system. Run Get-Helpabout_Quoting_Rules for more information.
The Using the help system recipe
The Working with variables and objects recipe