Directly Loading Exchange 2010 or 2013 SnapIn Is Not Supported
It is always interesting to see how certain constructs are carried over from previous versions of Exchange without being re-evaluated. The case in point here, is how access is provided to Exchange 2010/2013 PowerShell. Exchange 2010 introduced mail admins to remote PowerShell. At this time we should all be using remote PowerShell for Exchange 2010 and 2013 servers.
However there still seems to be a trend not to use PowerShell remoting and directly load up the Exchange 2010 or 2013 snapin. An example of what we should not be doing for Exchange 2010 and 2013 is something like:
If we look at the Exchange 2010 or Exchange 2013 documentation for connecting to Exchange PowerShell there is no mention of directly loading up the PowerShell SnapIn. The same is also true for Exchange Online (EXO).
How should we connect to Exchange PowerShell? Use PowerShell Remoting!
Unless you are following a specific process that is documented by Microsoft or are working with a Microsoft support representative, the only way you should be connecting to Exchange is the method documented above. One example of an exception to this rule is in the Exchange 2013 release notes. Note that the page also cautions:
Loading the Microsoft.Exchange.Management.PowerShell.SnapIn Windows PowerShell snap-in and running cmdlets other than the *-TransportAgent cmdlets is not supported and may result in irreparable damage to your Exchange deployment.
Connecting Using Remote PowerShell
As noted above, TechNet only documents that PowerShell remoting should be used. Typically this means that we will use the following process to connect to an on-premises Exchange 2010 or 2013 server.
In the below examples we provide credentials and store them in the $UserCredentials variable. They are then presented as part of the configuration of the PowerShell $Session. Finally the PowerShell session is imported.
Sample code would look like the below examples.
Prompting For Authentication On Domain Joined Machine
$UserCredential = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://<ServerFQDN >/PowerShell/ -Authentication Kerberos -Credential $UserCredential
(Please note they are three separate lines which may wrap)
Using Logged On Credentials On Domain Joined Machine
An example of leveraging logged on credentials could look like this:
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://<ServerFQDN >/PowerShell/ -Authentication Kerberos
With each of the above examples, the commands can be executed one line at a time, or saved into a PowerShell .PS1 script.
Disconnecting Using Remote PowerShell
Once we have completed our work, the PowerSession should be removed to clean it up.
Additional Remote PowerShell Bits
Exchange 2010 requires PowerShell version 2.0 and Windows Remote Management 2.0 (WinRM) at a minimum as that was the first version of PowerShell to support remoting. As far as base PowerShell is concerned, the remoting endpoint can be hosted in either the WinRM service or IIS. Exchange leverages IIS for its remoting capabilities. It is worth pointing out that while you may be able to use Exchange remoting, it is separate from Windows remoting. Windows remoting is not enabled by default. You will need to manually enable Windows remoting. Different TCP endpoints are also used. Exchange remoting uses TCP 80, and Windows remoting uses 5985 TCP. To see the WinRM port you could use something like this:
WinRM E Winrm/Config/Listener
Since Exchange 2010 and 2013 use remote PowerShell, this means that even if you open up the Exchange Management Shell (EMS) on an Exchange server you are in effect connecting to PowerShell remotely. An exception is the Exchange 2010 Edge role, where PowerShell remoting is not used to minimise the attack surface since the Exchange remoting endpoint requires IIS.
Exchange 2010 and 2013 host the remoting endpoint within IIS, and this is the server side runspace. The server side runspace contains the cmdlets that RBAC allows for the individual in question, and they are made available in the client side runspace. This is the reason that Exchange 2010/2013 cmdlets are listed as functions when administrators run a Get-Command cmdlet. We can see a graphic representation of this in the stock Microsoft image below.
One common question that arises, is why is TCP 80 used? Does this not mean that the traffic is not secure since that is the HTTP port rather than the HTTPS port? Yes this is the well known HTTP port, but the traffic is protected using the Kerberos authentication of the person connecting. If you look closely at the PowerShell remoting code included at the top of this post you will see that the authentication type is indeed Kerberos. If you try and force the PowerShell virtual directory to enforce SSL then you will not be able to connect. Administrators normally discover this when cascading settings down from the root of the web site. When we connect between different forests Kerberos authentication is not available, for example from on-premises to Office 365. In such cases the connection must be HTTPS and basic authentication is used. The credentials are protected with the SSL stream so there are no security issues.
For examples on connecting to local and remote Exchange forests please review this post.