2. Running and Using the Exchange Management Shell
After you've installed the Exchange management tools on a computer,
you can start to use the Exchange Management Shell by clicking Start,
pointing to All Programs, clicking Microsoft Exchange Server 2010, and
then clicking Exchange Management Shell.
Tip
Selecting the shell in this way starts the Exchange Management Shell
using your user credentials. This enables you to perform any
administrative tasks allowed for your user account. As a result, you
don't need to run the Exchange Management Shell in elevated,
administrator mode, but you can. To do so, right-click Exchange
Management Shell, and then click Run As Administrator.
This starts PowerShell and loads the Exshell.psc1 console file and the RemoteExchange.ps1
profile file. These files are used to initialize the working
environment for Exchange Server. The console file loads the
Microsoft.Exchange.Management.PowerShell.E2010 snap-in. The profile file
sets aliases, initializes Exchange global variables, and loads .NET
assemblies for Exchange. It also modifies the standard PowerShell prompt
so that it is scoped to the entire Active Directory forest and defines
the following Exchange-specific functions:
-
Functions Allows you to list all available functions by typing functions.
-
Get-Exbanner
Displays the Exchange Management Shell startup banner whenever you type get-exbanner.
-
Get-Exblog
Opens Internet Explorer and accesses the Exchange blog at Microsoft whenever you type get-exblog.
-
Get-Excommand
Allows you to list available Exchange commands by typing get-excommand.
-
Get-Pscommand
Allows you to list available PowerShell commands by typing get-pscommand.
-
Get-Tip
Displays the tip of the day whenever you type get-tip.
-
Quickref
Opens Internet Explorer and allows you to download the Exchange Management Shell quick start guide whenever you type quickref.
The RemoteExchange.ps1 profile loads the ConnectFunctions.ps1
script, which defines a number of functions that enable AutoDiscover
and Connect features. The functions include the following:
These functions are available for you to use at this point as well as
whenever you work with the Exchange Management Shell or have loaded the
ConnectFunctions.ps1 script. However, only Connect-ExchangeServer and Discover-ExchangeServer are meant to be called directly. The other functions are helper
functions. When you are working with the Exchange Management Shell or
have run ConnectFunctions.ps1, you can view the source for a function by
typing functions followed by the name of the function, such as functions connect-exchangeserver.
If you want to access Exchange features from a standard PowerShell prompt or within scripts, you need to load the Excshell.psc1 console file and the RemoteExchange.ps1
profile file. You can find an example of the command required to do
this by right-clicking the menu shortcut for the Exchange Management
Shell and then selecting Properties. In the Properties dialog box, the
Target text is selected by default. Press Ctrl+C to copy this text so
that you can use it. For example, if you copy the Target text and paste
it into an elevated command prompt (cmd.exe), you can access the
Exchange Management Shell and work with Exchange Server. If you copy the
Target text and paste it into a script, you can be sure that the
Exchange environment is loaded when you run the script.
An extra command is added to the Target text of the menu item. This
additional command is Connect-ExchangeServer –Auto, a command enabled
when the ConnectFunctions.ps1 script runs.
When you use Connect-ExchangeServer with the –Auto parameter,
PowerShell attempts to discover the best Exchange server to connect to
automatically and then tries to create a new remote PowerShell session
with this Exchange server. PowerShell first attempts to connect to a
local server and then to Client Access servers in the local site. After
that, PowerShell tries to connect to Hub, Mailbox, and Unified Messaging
servers. You also can automatically connect to and create a remote
session by typing connect-exchangeserver –auto. A remote session is a runspace that establishes a common working environment for executing commands on remote computers.
To customize the initialization of remote sessions, other parameters are available:
-
–ClearCache A troubleshooting option that allows you to clear registry entries and
exported modules and then re-create the registry settings and import
modules again. After you clear the cache, you can try to connect again
using options you need.
connect-exchangeserver -clearcache
-
–Forest Allows you
to specify a single part name or the fully qualified domain name (FQDN)
of the Active Directory forest in which to perform discovery. You must
be able to authenticate in the forest. User credentials you provide for the –Username parameter are not used for discovery. Use with –Auto.
connect-exchangeserver -auto -forest ForestName
-
–Prompt Prompts
you for the FQDN of the Exchange server to connect to. If you use
–Prompt with –Auto, you are prompted only if PowerShell cannot connect
automatically. If you use –Prompt with –ServerFqdn, you are prompted
only if PowerShell cannot connect to the specified server.
connect-exchangeserver -auto -prompt
-
–ServerFqdn Allows you to specify the FQDN of the Exchange server to connect to.
connect-exchangeserver -serverfqdn ExServerFQDN
-
–Username Allows
you to specify the user name to use for authentication. You will be
prompted for the user's password. You can also pass in a Credential
object. Use with –ServerFqdn or –Auto.
connect-exchangeserver -serverfqdn ExServerFQDN
-username UserName
Note
REAL WORLD When you are working with some cmdlets and objects in PowerShell, you might need to specify a credential for authentication. To do this, use Get-Credential to obtain a Credential object and save the result in a variable for later use. Consider the following example:
$cred = get-credential
When PowerShell reads this command, PowerShell prompts you for a user
name and password and then stores the credentials provided in the $cred
variable. You also can specify that you want the credentials for a
specific user in a specific domain. In the following example, you request the credentials for the ExAdmin account in the Adatum domain:
$cred = get-credential -credential adatum\exadmin
A Credential object has UserName and Password properties that you can
work with. Although the user name is stored as a regular string, the
password is stored as a secure, encrypted string. Simply pass in the
credential instead of the user name as shown in this example:
$cred = get-credential -credential adatum\exadmin
get-hotfix -credential $cred -computername mailserver18
When you call Connect-ExchangeServer, one of the final things the
function does is call _OpenExchangeRunSpace to establish a remote
session with an Exchange server. In turn, _OpenExchangeRunSpace does one
of two things: it opens a remote session using implicit credentials
(the credentials of the user who is running Exchange Management Shell)
or by using specified credentials (credentials you've explicitly
provided). In the script, the code for using implicit credentials is
similar to the following:
$global:remoteSession = new-pssession -connectionURI
https://$fqdn/powershell?serializationLevel=Full
-ConfigurationName Microsoft.Exchange -SessionOption $sessionOption
The code for explicit credentials is similar to the following:
$global:remoteSession = new-pssession -connectionURI
https://$fqdn/powershell?serializationLevel=Full
-ConfigurationName Microsoft.Exchange -Authentication Kerberos
-Credential $credential -SessionOption $sessionOption
These examples create a global variable named $remoteSession to hold
the remote session. A global variable is used to ensure that the session
remains active and available when the script exits. The session is
established using New-PSSession with a connection URI for a particular
Exchange server. For example, if the Exchange server's FQDN is
MailServer15.Cpandl.com, the connection URI is https://mailserver15.cpandl.com/powershell.
The –ConfigurationName parameter sets the configuration namespace as
Microsoft.Exchange (in place of the default Microsoft.PowerShell). The
–Authentication parameter is set to use Kerberos authentication with
explicit credentials. The –SessionOption parameter sets session options
that were defined previously using the New-PSSessionOption cmdlet. The
session options include the operation timeout value, the idle timeout
value, and the open session timeout value. By default, all three are set
to 180,000 milliseconds (180 seconds) via the $sessionOptionsTimeout
variable defined in the first section of the ConnectFunctions.ps1
script.
You can use the MsExchEmsTimeout environment
variable to set the default timeout values. If you set this environment
variable to a value of 900,000 milliseconds or less (15 minutes or
less), the timeouts are set accordingly. If you set this environment
variable to a value greater than 900,000 milliseconds, the timeout
values revert to the 3 minute default value.
Managing the PowerShell Application
Microsoft Internet Information Services (IIS) handles every incoming
request to a Web site within the context of a Web application. A Web
application is a software program that delivers Web content to users
over HTTP or HTTPS. Each Web site has a default Web application and one
or more additional Web
applications associated with it. The default Web application handles
incoming requests that aren't assigned to other Web applications.
Additional Web applications handle incoming requests that specifically
reference a particular application.
When you connect to a server using a URL, such as https://mailserver15.cpandl.com/powershell, you are performing remote operations via the PowerShell application running on the Web server providing Exchange services. Like all Web applications, the PowerShell application has a virtual
directory associated with it. The virtual directory sets the
application name and maps the application to the physical directory that
contains the application's content.
You can manage the PowerShell application using IIS Manager and the Exchange Management Shell. The related commands for the Exchange Management Shell are:
-
Get-PowerShellVirtualDirectory
Displays information about the PowerShell application running on the Web server providing services for Exchange.
Get-PowerShellVirtualDirectory [-Identity 'AppName
']
[-DomainController 'DomainControllerName
']
Get-PowerShellVirtualDirectory -Server 'ExchangeServerName
'
[-DomainController 'DomainControllerName
']
-
New-PowerShellVirtualDirectory
Creates a new PowerShell application running on the Web server providing services for Exchange.
New-PowerShellVirtualDirectory -Name 'AppName
'
[-AppPoolId 'AppPoolName
'] [-BasicAuthentication <$true | $false>]
[-CertificateAuthentication <$true | $false>] [-DomainController
'DomainControllerName
'] [-ExternalUrl 'URL
'] [-InternalUrl 'URL
']
[-Path 'PhysicalDirectoryPath
']
[-WindowsAuthentication <$true | $false>]
-
Remove-PowerShellVirtualDirectory
Removes a specified PowerShell application running on the Web server providing services for Exchange.
Remove-PowerShellVirtualDirectory -Identity 'AppName
'
[-DomainController 'DomainControllerName
']
-
Set-PowerShellVirtualDirectory
Modifies the
configuration settings for a specified PowerShell application running on
the Web server providing services for Exchange.
Set-PowerShellVirtualDirectory -Identity 'AppName
'
[-BasicAuthentication <$true | $false>] [-CertificateAuthentication
<$true | $false>] [-DomainController 'DomainControllerName
']
[-ExternalUrl 'URL
'] [-InternalUrl 'URL
']
[-LiveIdBasicAuthentication <$true | $false>]
[-WindowsAuthentication <$true | $false>]
At the Exchange Management Shell prompt, you can confirm the location of the PowerShell application by typing get-powershellvirtualdirectory
.
Get-PowerShellVirtualDirectory lists the name of the application, the
associated directory and Web site, and the server on which the
application is running, as shown in the following example:
Name Server
------- -------
PowerShell (Default Web Site) CorpServer45
In this example, a standard configuration is being used where the application named PowerShell
is running on Default Web Site on CorpServer45. You can use
Set-PowerShellVirtualDirectory to specify the internal and external URL
to use as well as the permitted authentication types. Authentication types you can enable or disable include basic authentication, Windows authentication, certificate authentication, and Live
ID basic authentication. You can use New-PowerShellVirtualDirectory to
create a new PowerShell application on the Web server providing services
for Exchange and Remove-PowerShellVirtualDirectory to remove a
PowerShell application.
Note
REAL WORLD Any change you make to the PowerShell virtual
directory configuration requires careful pre-planning. For every
potential change, you'll need to determine whether you need to modify
the Windows RM configuration and the PowerShell path in
ConnectFunctions.ps1 scripts on management computers and Exchange
servers as well as the specific changes you'll need to make with regard
to IIS on your Client Access servers.
Microsoft cautions against modifying the default configuration for
the PowerShell virtual directory as any mistakes you make could prevent
you from managing
Exchange Server. Because Exchange configuration data is stored in Active
Directory and the affected IIS metabase, you would need to be able to
restore Exchange data in Active Directory and the affected IIS metabase
to a previous state to recover.
Customizing Exchange Management
Now that you know how the Exchange Management Shell environment
works, you can more easily customize the shell to work the way you want
it to. One way to do this is to modify the menu shortcut that starts the
Exchange Management Shell or create copies of this menu shortcut to
change the way the Exchange Management Shell starts. For example, if you
want to connect to a named Exchange server rather than any available
Exchange server, you can do the following:
-
Right-click the menu shortcut for the Exchange Management Shell and then select Properties.
-
In the Properties dialog box, the Target text is selected by default.
Press the right arrow key to move to the end of the command text.
-
Delete –Auto" and type –ServerFqdn followed by the FQDN of the Exchange server, such as –ServerFQDN MailServer12.Cpandl.com, and then type ". Click OK.
That said, this entire sequence of tasks is meant to simplify the
task of establishing an interactive remote session with a single
Exchange server. As implemented in the default configuration, you have a
one-to-one, interactive approach for remote management, meaning you
establish a session with a specific remote server and work with that
specific server simply by executing commands.
When you are working with PowerShell outside of Exchange Management Shell, you might want to use the Enter-PSSession
cmdlet to start an interactive session with an Exchange server or any
other remote computer. The basic syntax is Enter-PSSession ComputerName, where ComputerName is the name of the remote computer, such as the following:
enter-pssession maileserver15
After you enter this command, the command prompt changes to show that
you are connected to the remote computer, as shown in the following
example:
[Server49]: PS C:\Users\wrstanek.cpandl\Documents>
Now, the commands that you type run on the remote computer just as if
you had typed them directly on the remote computer. In most cases, you
need to ensure you are running an elevated, administrator shell and that
you pass credentials along in the session. When you connect to a server
in this way, you use the standard PowerShell remoting configuration and
do not go through the PowerShell application running on a Web server.
You can end the interactive session by using the command Exit-PSSession
or typing exit.
To access an Exchange server in the same way as the
ConnectFunctions.ps1 script, you need to use the –ConnectionURI
parameter to specify the connection URI, the –ConfigurationName
parameter to specify the configuration namespace, the –Authentication
parameter to set the authentication type to use, and optionally, the
–SessionOption parameter to set session options. Consider the following
example:
enter-pssession -connectionURI http://mailserver12.cpandl.com/powershell
-ConfigurationName Microsoft.Exchange -Authentication Kerberos
Here, you set the connection URI as https://mailserver12.cpandl.com/powershell,
set the configuration namespace as Microsoft.Exchange, and use Kerberos
authentication with the implicit credentials of your user account. If
you don't specify the authentication method,
the default authentication method for WinRM is used. If you want to use
alternate credentials, you can pass in credentials as shown in this
example:
$cred = get-credential -credential adatum\williams
enter-pssession -connectionURI https://mailserver12.cpandl.com/powershell
-ConfigurationName Microsoft.Exchange -credential $cred
-Authentication Kerberos
Here, you set the connection URI as https://mailserver12.cpandl.com/powershell,
set the configuration namespace as Microsoft.Exchange, and use
alternate credentials. When PowerShell reads the Get-Credential command,
you are prompted for the password for the specified account. Because
the authentication type is not defined, the session uses the default
authentication method for WinRM.
To put this all together, one way to create a script that runs on an
Exchange server is to load the
Microsoft.Exchange.Management.PowerShell.E2010 snap-in, run the
RemoteExchange.ps1 profile file, and then run the ConnectFunctions.ps1
script to autoconnect to Exchange. The commands you insert into your
script to do this are the following:
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
$s = $env:ExchangeInstallPath + "bin\RemoteExchange.ps1"
&$s
$t = $env:ExchangeInstallPath + "bin\ConnectFunctions.ps1"
&$t
Here, you use the Add-PSSnapin command to load the Exchange snap-in.
Next, you define variables that point to the RemoteExchange.ps1 and
ConnectFunctions scripts in the Exchange installation path, and then you
use the & operator to invoke the scripts. The environment variable
ExchangeInstallPath stores the location of the Exchange installation. If
you enter the full path to a script, you don't need to assign the path
to a variable and then invoke it. However, you then have a fixed path
and might need to edit the path on a particular Exchange server. Be sure
to run the script at an elevated, administrator PowerShell prompt.
If you want to create a script that runs on your management computer
and then executes commands remotely on an Exchange server, you'll
probably want to insert commands
in your script to create a new session and then invoke commands in the
session using the techniques discussed in the next section.
Performing One-to-Many Remote Management
PowerShell also lets you perform one-to-many remote management. Here,
you must work with an elevated, administrator shell and can either
invoke remote commands on multiple computers or establish remote
sessions with multiple computers. When you remotely invoke commands,
PowerShell runs the commands on the remote computers, returns all output
from the commands, and establishes connections to the remote computers
only for as long as is required to return the output. When you establish
remote sessions, you can create persistent connections to the remote
computers and then execute commands within the session. Any command you
enter while working in the session is executed on all computers to which
you are connected, whether this is 1 computer, 10 computers, or 100
computers.
Tip
WinRM must be appropriately configured on any computer you want to
remotely manage. While WinRM is configured on Exchange servers and most
others computers running Windows 7 and Windows Server 2008 Release 2,
WinRM listeners generally are not created by default. You can create the
required listeners by running winrm quickconfig.
The following command entered as a single line invokes the Get-Service and Get-Process commands on the named servers:
invoke-command -computername MailServer12, MailServer21, MailServer32
-scriptblock {get-service; get-process}
The following command establishes a remote session with the named computers:
$s = new-PSSession -computername MailServer12, MailServer21, MailServer32
-Credential Cpandl\WilliamS
When you connect to a server in this way, you use the standard
PowerShell remoting configuration and are not going through the
PowerShell application running on a Web server. After you establish the
session, you can then use the $s session with Invoke-Command to return
commands on all remote computers you are connected to. In this example,
you look for stopped Exchange services on each computer:
invoke-command -session $s
-scriptblock {get-service mse* | where { $_.status -eq "stopped"}}
In this example, you pipe the output of Get-Service to the
Where-Object cmdlet and filter based on the Status property. As the $_
automatic variable operates on the current object in the pipeline,
PowerShell examines the status of each service in turn and lists only
those that are stopped in the output.
In addition to working with remote
commands and remote sessions, some cmdlets have a –ComputerName
parameter that lets you work with a remote computer without using
Windows PowerShell remoting. PowerShell supports remote background
jobs as well. A background job is a command that you run asynchronously
in an interactive or noninteractive session. When you start a
background job, the command prompt returns immediately and you can
continue working while the job runs.
Finally, compared to all the behind-the-scenes tasks that are performed when you work with the Exchange Management Shell, the Forefront
Management Shell is very simple. When you select the related menu item,
Windows runs PowerShell and loads the FSSPSnapin. Because PowerShell is
run with no security context, you won't be able to perform
administrative tasks. To resolve this, you need to right-click the
Forefront Management Shell and then select Run As Administrator to open
an elevated, administrator shell. If you want to run Forefront commands
while working with the Exchange Management Shell, all you need to do is
type the following command:
Add-PSSnapin FSSPSSnapin
Adding this command to your scripts allows you to work with Forefront Security in your scripts as well.
Troubleshooting Exchange Management
Note that the ConnectionFunctions.ps1 script relies on your
organization having a standard Exchange Server configuration. By
default, Exchange is configured for management using HTTP with the URL http://ServerName/powershell.
If you've modified the Web Server configuration on your Exchange
servers to use a different path, such as might be required to enhance
security, you need to update the connection URIs used in the
ConnectionFunctions.ps1 script.
When you invoke the PowerShell application, the Web server to which you connect runs the PowerShell plug-in (Pwrshplugin.dll) and the Exchange
Authorization plug-in (Microsoft.Exchange.AuthorizationPlugin.dll). The
PowerShell plug-in runs as a Microsoft.Exchange shell and has the
following initialization parameters:
-
PSVersion, which sets the PowerShell version as 2.0
-
ApplicationBase, which sets the base path for the Exchange server as %ExchangeInstallPath%Bin
-
AssemblyName, which sets the name of the .NET assembly to load as Microsoft.Exchange.Configuration.ObjectModel.dll
The Authorization plug-in handles Exchange
authorization and authentication. Together, these plug-ins create an
authorized shell environment for the remote session.
The physical directory for the PowerShell application is
%ExchangeInstallPath%\ClientAccess\PowerShell. This application runs in
the context of an application pool named MSExchangePowerShellAppPool.
In the %ExchangeInstallPath%\ClientAccess\PowerShell directory on
your server, you'll find a web.config file that defines the settings for
the PowerShell application. This file contains a role-based access
control (RBAC) configuration section that loads the assemblies and Web
controls for the application.
Tip
Microsoft recommends against changing the PowerShell application configuration. However, there's nothing magical or mystical about
the PowerShell application or MSExchangePowerShellAppPool. You can
re-create these features to enable remote management in alternate
configurations, such as on nondefault Web sites or Web sites with
alternate names. However, be sure to copy the PowerShell application's
web.config file to the physical directory for your base application.
Before you make any changes to a live production environment, you should
plan and test your changes in a nonproduction test environment.
The Web Server to which you connect processes your remote actions via
the Exchange Control Panel (ECP) application running on the default Web
site. The physical directory for this application is
%ExchangeInstallPath%\ClientAccess\Ecp. This application runs in the
context of an application pool named MSExchangeECPAppPool.
In the %ExchangeInstallPath%\ClientAccess\ECP directory on your
server, you'll find a web.config file that defines the settings for the
ECP application. This file contains an RBAC configuration section that
loads the assemblies and Web controls for the application.
Because of the interdependencies created by accessing Exchange via
Web applications, you'll want to examine related features as part of troubleshooting any issues you experience with remote sessions. Generally, your troubleshooting should follow these steps:
-
Examine the status and configuration of the WinRM on your local
computer and the target Exchange server. The service must be started and
responding.
-
Check the settings of any firewall running on your local computer,
the target Exchange server, or any device in between the two, such as a
router with a firewall.
-
Check the status of the World Wide Web Publishing Service on the Exchange server. The service must be started and responding.
-
Check the configuration settings of the PowerShell and ECP
applications on the Web server. By default, the applications don't have
access restrictions, but another administrator could have set
restrictions.
-
Check the status of MSExchangePowerShellAppPool and
MSExchangeECPAppPool. You might want to recycle the application pools to
stop and then start them.
-
Check the configuration settings of MSExchangePowerShellAppPool and
MSExchangeECPAppPool. By default, the application pools are configured
to use only one worker process to service requests.
-
Check to ensure the PowerShell application's web.config file is
present in the physical directory for the application, and also that the
file has the appropriate settings.
-
Check to ensure the ECP application's web.config file is present in
the physical directory for the application and also that the file has
the appropriate settings.
3. Working with Exchange Cmdlets
When you are working with the Exchange
Management Shell, additional Exchange-specific cmdlets are available.
As with Windows PowerShell cmdlets, you can get help information on
Exchange cmdlets:
-
To view a list of all Exchange cmdlets, type get-excommand
at the shell prompt.
-
To view Exchange cmdlets related to a specific server role, type get-help –role
RoleName, where RoleName is the name of the server role you want to examine. You can use the following role names:
-
*UM* for cmdlets related to the Unified Messaging server role
-
*Mailbox* for cmdlets related to the Mailbox server role
-
*ClientAccess* for cmdlets related to the Client Access server role
When you work with the Exchange
Management Shell, you'll often work with Get, Set, Enable, Disable,
New, and Remove cmdlets (the groups of cmdlets that begin with these
verbs). These cmdlets all accept the –Identity parameter, which
identifies the unique object with which you are working.
Typically, a cmdlet that accepts the –Identity parameter has this
parameter as its first parameter, allowing you to specify the identity,
with or without the parameter name. When identities have names as well
as aliases, you can specify either value as the identity. For example,
you can use any of the following techniques to retrieve the mailbox
object for the user William Stanek with the mail alias Williams:
get-mailbox -identity williams
get-mailbox -identity 'William Stanek'
get-mailbox Williams
get-mailbox "William Stanek"
With Get cmdlets, you typically can return an object set containing
all related items simply by omitting the identity. For example, if you
type get-mailbox at
the shell prompt without specifying an identity, you get a list of all
mailboxes in the enterprise (up to the maximum permitted to return in a
single object set).
By default, all cmdlets return data in table format. Because there
are often many more columns of data than you can fit across the screen,
you might need to switch to Format-List output to see all of the data.
To change to the Format-List output, redirect the output using the pipe
symbol (|) to the Format-List cmdlet, as shown in this example:
get-mailbox -identity williams | format-list
You can abbreviate Format-List as fl, as in this example:
get-mailbox -identity williams | fl
Either technique typically ensures that you see much more information
about the object or the result set than if you were retrieving
table-formatted data.