1. Why Use PowerShell?
Based on discussions in Internet newsgroups, web
forums, and classrooms about the decision to put the management
architecture of Exchange 2007 on top of PowerShell, you would think
that this was one of the most controversial decisions that Microsoft
has ever made. Indeed, there has been enthusiastic debate (and
name-calling) on both sides of the fence. Depending on who you ask,
some experienced Exchange administrators will tell you that the
Exchange Management Shell (EMS) is the best improvement Microsoft has
made after Exchange 2003.
We have to admit to becoming big supporters of the
EMS. All it took was spending a bit of time with it and getting to know
some of the basic functionality. The biggest fear that many
administrators have is that they will have to learn not only some of
the shell's commands (called cmdlets) but also a scripting language
just to manage Exchange Server 2010. That is not the case.
The intent of the EMS is to provide a consistent
interface for performing management tasks for Exchange 2010 servers,
whether performing automation tasks, writing scripts, or extending the
management capabilities. Tasks or operations that once required
multiple programming APIs and hundreds of lines of scripting can now be
accomplished in a single command. Single commands can be joined
together — the output of one command can be piped to another command as
input — to perform extremely powerful functions.
The base PowerShell provides more than 120 built-in
cmdlets; PowerShell v2 and Windows Server 2008 and Windows Server 2008
R2 add even more cmdlets. In total, there are over 600 additional
Exchange-related cmdlets that you can use in the EMS; the goal is to
cover all Exchange-related administrative tasks. You will find cmdlets
that manipulate other data in the Active Directory (such as cmdlets for
managing user accounts) and control Exchange-related data in the
Registry or Internet Information Services, but the cmdlets will only
manipulate or manage data related to Exchange. The Exchange team is
expecting other internal Microsoft teams such as the Active Directory
or Internet Information Server team to provide their own extensions to
the management shell.
There are a lot of very good reasons for
Microsoft to create this management layer across all its products. It
provides a consistent management and scripting interface for all server
products, develops a secure method for remote scripting, improves
batching, and provides you with an easy way to automate and repeat
anything you can do in the GUI.
2. Understanding the Command Syntax
The problem with a lot of scripting languages and
command shells is that as they get more complex and powerful, the
command syntax gets more and more cryptic. PowerShell and the EMS seek
to make using the command-line interface and scripting more intuitive.
To this end, most of PowerShell and EMS cmdlets consist of two
components: a verb and a noun.
PowerShell cmdlets and the EMS extensions for
PowerShell are case insensitive. That means that you can type
everything in uppercase, everything in lowercase, or mix and match the
case of the letters in your commands.
|
2.1. Verbs and Nouns
The verb identifies the action that is being taken,
and the noun indicates the object on which the action is being taken.
The verb always comes first, and the verb and noun are separated by a
hyphen (such as Get-Mailbox). Table 1
shows some of the common verbs you'll use in the EMS; some of these are
specific to the EMS, but most are generic to the Windows PowerShell.
Table 1. Common EMS Cmdlet Verbs
Verb | Description |
---|
Get | Get is probably the most common verb that you will use. Get retrieves information about the specified object and outputs information about the object. |
Set | Set is probably the second most common verb that you will use. Set allows you to update properties of the object specified in the noun. |
New | New creates new instances of the object specified in the noun. |
Enable | Enable activates or enables a configuration on the object specified, such as enabling an existing user account. |
Add | Add can be used to add items to an object, or to add properties of an object. |
Remove | Remove deletes an instance of the object specified in the noun. |
Disable | Disable
disables or deactivates the object specified in the noun. An example of
this is removing a mailbox from an existing user (but not deleting the
user account). |
Mount | Mount is used to mount an Exchange 2007 mailbox or public folder database. |
Dismount | Dismount is used to dismount an Exchange 2007 mailbox or public folder database. |
Move | Move can be used to activate a database copy on a mailbox server. |
Test | Test performs diagnostic tests against the object specified by the noun and the identity option. |
Update | Update is used to update specified objects. |
The actual nouns that are used in conjunction with these verbs are too numerous to mention in even a few pages of text. Table 2
lists some of the common nouns. The nouns in
Table 2 can be used in conjunction with verbs, such as the ones in Table 1,
to manipulate the properties of Exchange-related objects. However, not
all verbs work with all nouns, and unfortunately it sometimes requires
some trial and error to determine what works and what doesn't.
One important thing to keep in mind with cmdlets is
that they are not individual executables, but rather .NET classes that
are only accessible from within PowerShell and only if the Exchange
extensions to PowerShell are loaded.
|
Table 2. Common EMS Cmdlet Nouns
Noun | Description |
---|
ActiveSyncMailboxPolicy | Properties of ActiveSync policies that can be assigned to a mailbox |
CASMailbox | Properties of a mailbox relating to client features such as OWA and MAPI |
ClientAccessServer | Properties specific to an Exchange Client Access server role |
DistributionGroup | Properties relating to mail-enabled distribution groups. |
DynamicDistributionGroup | Properties relating to a dynamic distribution group |
EmailAddressPolicy | Properties relating to the policies that are used to define email addresses |
ExchangeServer | Properties related to Exchange servers |
Mailbox | Properties related to user mailboxes |
MailboxDatabase | Properties related to mailbox databases |
MailboxServer | Properties specific to an Exchange Mailbox server role |
MailContact | Properties relating to mail-enabled contact objects |
MailPublicFolder | Properties relating to mail-enabled public folder objects |
MailUser | Properties relating to a user that has an email address but not a mailbox |
MoveRequest | Properties and actions related to move mailbox requests |
ReceiveConnector | Properties relating to Receive connectors |
SendConnector | Properties relating to Send connectors |
TransportServer | Properties specific to an Exchange Hub Transport server role |
UMMailbox | Properties relating to Unified Messaging |
UMServer | Properties specific to an Exchange Unified Messaging server role |
User | Properties relating to user objects |
2.2. Help
At any time you can use the Get-Help cmdlet to show what parameters any cmdlet takes. This is much like the man command on Linux systems:
Get-Help Get-Mailbox
2.3. The -Identity Parameter
For cmdlets that require input, usually the first parameter provided is the -Identity
parameter. For example, if you want to retrieve information about a
mailbox called Tyler Swartz in the Corporate Organizational Unit (OU),
you would type this:
Get-Mailbox -Identity 'ithicos.local/Corporate/Tyler Swartz'
However, you will quickly find that the -Identity
parameter is not required. And, if your aliases or account names are
unique, even the domain and organizational unit (OU) information is not
required. For example, this command would yield the same result:
Get-Mailbox 'fourthcoffee.com/Corporate/Tyler Swartz'
As long as there is only one Tyler Swartz in the
Active Directory, you can even drop the domain and the OU name and this
cmdlet will yield the same result:
Get-Mailbox 'Tyler Swartz'
Anytime the identity you are using has a space in
it, you must use quotes. Either single or double quotes will work as
long as you are consistent.
|
The -Identity parameter is optional by
design. As you will find shortly, the input for one cmdlet can even be
piped in from the output of another cmdlet.
If you are not sure what input can be specified for
the identity parameter, you can easily look up this information either
in the Exchange online help or by using the EMS command-line help . For now, let's look at one small piece
of the Get-Mailbox help screen that shows the different values that can be used to identify a mailbox:
-Identity <MailboxIdParameter>
The Identity parameter identifies the mailbox. You can use one of the
following values:
* GUID
* Distinguished name (DN)
* Domain\Account
* User principal name (UPN)
* LegacyExchangeDN
* SmtpAddress
* Alias
Required? false
Position? 1
Default value
Accept pipeline input? True
Accept wildcard characters? true
There, you can see that the -Identity
parameter will take the mailbox GUID, the user's distinguished name,
the domain name and account, the UPN name, the legacy Exchange
distinguished name, the SMTP address, or the Exchange alias.
2.4. Cmdlet vs. Command
You will notice that sometimes we use "command" and
sometimes we use "cmdlet" when talking about PowerShell. There is a
subtle difference:
A cmdlet is the verb-noun combination that
performs a specific task; it is the base Power-Shell object that takes
input, does something to it, and produces some output.
A
complete command is the cmdlet along with any necessary options that
the task might require. The command necessary to retrieve information
about a specific mailbox looks like this:
Get-Mailbox "JulieR.Samante"
2.5. Cmdlet Parameters
PowerShell and EMS cmdlets also support a number of
command-line parameters that are useful. Parameters can be categorized
as mandatory or not, and as positional or not. When a parameter is mandatory,
PowerShell will require you to add the parameter with a given cmdlet
and specify a value for it. If the use of a parameter is not mandatory,
you are allowed to include it, but you don't have to. The cmdlet New-Mailbox illustrates this behavior nicely. When creating a new mailbox-enabled user, you have to include the parameter UserPrincipalName, but you are free to include the parameter OrganizationalUnit.
The EMS will prompt you for the value of any mandatory parameter you
forgot to specify. Next to being mandatory or not, it is not always
necessary to include the parameter name. When a parameter is so-called
positional, you can just add the value and leave out the parameter
name. The cmdlet Get-Mailbox has no mandatory parameters, but does have a positional parameter, namely -Identity.
If we run the following EMS line, the shell will return the properties
of a mailbox-enabled user whose Exchange alias is Michael.Brown:
Get-Mailbox Michael.Brown
Name Alias ServerName ProhibitSendQuota
---- ----- ---------- ---------------
Michael.Brown Michael.Brown hnlmbx01 unlimited
which is the same as running this:
Get-Mailbox Michael.Brown
Name Alias ServerName ProhibitSendQuota
---- ----- ---------- ---------------
Michael.Brown Michael.Brown hnlmbx01 unlimited
However, if we run the following line, the shell
will complain that it doesn't know any mailbox-enabled user by the name
of hnlmbx01, because the parameter Server is not positional.
Get-Mailbox hnlmbx01
The operation couldn't be performed because object 'hnlmbx01' couldn't be
found on 'dc01.exchange.local'.
+ CategoryInfo : NotSpecified: (:) [Get-Mailbox],
ManagementObjectNotFoundException
+ FullyQualifiedErrorId : 3FEDEA30,Microsoft.Exchange.Management.
RecipientTasks.GetMailbox
as opposed to
Get-Mailbox -Server HNLMBX01
Name Alias ServerName ProhibitSendQuota
---- ----- ---------- -----------------
Administrator Administrator hnlmbx01 unlimited
DiscoverySearchMailbox... DiscoverySearchMa... hnlmbx01 unlimited
Clayton Kamiya Clayton.Kamiya hnlmbx01 unlimited
Jordan Chang JordanChang hnlmbx01 unlimited
Tyler M. Swartz Tyler.Swartz hnlmbx01 unlimited
Anita Velez AnitaVelez hnlmbx01 unlimited
John Rodriguez JohnRodriguez hnlmbx01 unlimited
Jonathan Core JonathanCore hnlmbx01 unlimited
Kevin Wile KevinWile hnlmbx01 unlimited
John Park JohnPark hnlmbx01 unlimited
Julie R. Samante JulieR.Samante hnlmbx01 unlimited
David Elfassy DavidElfassy hnlmbx01 unlimited
Chuck Swanson ChuckSwanson hnlmbx01 unlimited
Kelly Siu KellySiu hnlmbx01 unlimited
Gerald Nakata GeraldNakata hnlmbx01 unlimited
Table 3
shows some of the parameters that cmdlets accept. Not all cmdlets will
accept all of these parameters; these are usually optional, and, of
course, some of them will not be relevant.
If you are piping output of one cmdlet into another,
the parameters must be within the cmdlet that you want the parameter to
affect.
2.6. Tab Completion
In order to be descriptive and helpful, some of the cmdlets are actually pretty long. Consider if you had to type Get-DistributionGroupMember
several times! However, PowerShell includes a feature called tab
completion. If we type part of a command and then press the Tab key,
PowerShell will complete the cmdlet with the first matching cmdlet it
can find. For example, if we type Get-Distri and press Tab, PowerShell will automatically fill out Get-DistributionGroup. If we press Tab again, PowerShell will move on to the next matching cmdlet, or in this case Get-DistributionGroupMember.
The tab completion feature also works for cmdlet parameters. If you type a cmdlet followed by a space and a hyphen, such as Get-Mailbox
-, and then press Tab, you will cycle through all the parameters for
that particular cmdlet. When you include parameters with your cmdlet,
it is not necessary to specify their full names. It is sufficient to
enter enough letters to make sure the EMS can figure out which
parameter you meant to define. For example, if you enter Get-Mailbox -Se server1
you will be given a list of all mailboxes homed on server server1. But
tab completion can be useful to help you keep an overview of your EMS
lines.
2.7. Alias
PowerShell and the EMS also include aliases that
allow you to invoke cmdlets using a familiar synonym. A typical example
here is entering Dir to get a list of all files in the
directory that you are in and all subdirectories after that directory,
which is in fact an alias for the cmdlet Get-ChildItem. Table 4 shows some common aliases that are built into PowerShell.
Table 3. PowerShell Cmdlet Parameters
Parameter | Description |
---|
-Identity | -Identity specifies a unique object on which the cmdlet is going to act. The -Identity
parameter is a positional parameter, which means that it does not
necessarily have to be on the command line; PowerShell will prompt you
for the identity if it is not specified. As noted previously, in most
cases you do not need to specify the -Identity parameter but just the unique object name. |
-WhatIf | -WhatIf tells the cmdlet to simulate the action that the cmdlet would actually perform, but not actually make the change. |
-Confirm | -Confirm asks the cmdlet to prompt for confirmation
prior to starting the action. This option type is Boolean so you need
to include either $True or $False. Some cmdlets (such as New-MoveRequest-) ask for confirmation by default, so you could specify -Confirm:$false if you did not want the confirmation request to occur. |
-Validate | -Validate
will check the prerequisites of the cmdlet to verify that it will run
correctly and let you know if the cmdlet will run successfully. |
-Credential | -Credential allows you to specify alternate credentials when running a PowerShell command. |
-DomainController | -DomainController allows you to specify the FQDN of a specific domain controller that you want to perform a PowerShell task against. |
-ResultSize | The -ResultSize option allows you to specify a maximum number of results when working with Get- cmdlets. |
-SortBy | The -SortBy option allows you to specify a sorting criteria when outputting data that is usually the result of a Get- cmdlet. |
-Verbose | -Verbose instructs Get- cmdlets to return more information about the execution of the cmdlet. |
-Debug | -Debug instructs the cmdlet to output more information and to proceed step by step through the process of performing a task. -Debug returns more information than a typical administrator needs to perform daily tasks. |
But it is important to remember that entering an
alias in the end is like entering a cmdlet, thus imposing some
constraints that do not apply when entering the listed aliases in Table 4
in a command prompt. If you would like to get a list of all files, and
files located in subdirectories, you would be inclined to enter dir /s, but when doing so in you will be faced with the following error message:
dir /s
Get-ChildItem : Cannot find path 'C:\s' because it does not exist.
At line:1 char:4
+ dir <<<< /s
Table 4. PowerShell Common Aliases
Alias | Definition |
---|
Dir | Get-ChildItem |
Ls | Get-ChildItem |
Type | Get-Content |
Cat | Get-Content |
Write | Write-Output |
Echo | Write-Output |
cd | Set-Location |
sl | Set-Location |
cls | Clear-Host |
Using the PowerShell, you know you need to include any parameter by adding a hyphen followed by the parameter name.
dir -Recurse:$True