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:

Add-PSsnapin Microsoft.Exchange.Management.PowerShell.E2010

 

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

Import-PSSession $Session 

(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

Import-PSSession $Session

 

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.

Remove-PSSession $Session

 

 

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

Checking Windows Remote Management Port

 

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.
 
 
 
Exchange 2010 PowerShell Remoting Runspaces
 

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.

Cheers,

Rhoderick

 
 
 
Comments (10)

  1. anonymouscommenter says:

    great
    as always

  2. anonymouscommenter says:

    In this post we will look at some of the mechanics behind creating a profile file which will customise

  3. anonymouscommenter says:

    One item that is very prevalent is people directly loading the Exchange PowerShell snapin into the Integrated

  4. anonymouscommenter says:

      As a bookmark, my buddy Rhoderick Milne has written an excellent article about the best way to

  5. Satyajit321 says:

    Thanks Rhoderick, helped me understand someting that was not clearer else where. But I still have a doubt, does HTTPS with Kerberos Authentication work (Without basic enabled)?
    Why is it "If you try and force the PowerShell virtual directory to enforce SSL then you will not be able to connect."

  6. That’s how the admin tools are written when connecting in the same forest. They expect to use HTTP.

    You could probably get that going with a manual PowerShell session.

    Cheers,
    Rhoderick

  7. anonymouscommenter says:

    One question…

    How do you dynamically identify the Exchange server to use in the FQDN?

    Compared to the add-pssnapin technique I see this lacks the ability to dynamically connect to the Exchange organisation without explicitly defining the hostname.

    e.g.
    I run Add-PSSnapin microsoft.exchange.management.powershell.e2010 and I can then run a get-exchangeserver.

    But I can’t run the new-possession without already knowing the Exchange server to connect to.

  8. Exchange powershell remoting has one huge hole. If you run a job remotely (for instance to spread out a set of tasks across multiple servers) you cannot pass any variables to it because the remote session for Exchange doesn’t allow it. You could change that in the IIS PS vDIR, but I am willing to bet that is not supported by MS either.

    Adding the snapin AFTER the Param command fixes that issue.

  9. warren says:

    #Add Exchange snapin if not already loaded
    $loaded = (Get-PSSnapin | where {$_.Name -eq “Microsoft.Exchange.Management.PowerShell.E2010”} | select Name)
    if ($loaded -like “*Exchange.Management.PowerShell*”)
    {
    Write-Host “Exchange Loaded Already”
    }
    Else
    {

    Write-Verbose “Loading the Exchange snapin”

    Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction SilentlyContinue

    . $env:ExchangeInstallPath\bin\RemoteExchange.ps1

    Connect-ExchangeServer -auto -AllowClobber
    }

  10. Boudicca0308 says:

    I know this post is getting a bit long in the tooth but thought I’d post my experience. I’ve tried this method on a script I’m running as a scheduled task. The script uses EWS impersonation to add a mailbox folder for members of a group. The script would run fine interactively but when running as a schedtask it would fail on the EWS portion of the script. I had added the PSSnapin in the script and that resolved the problem. But I learned that Add-PSSnapin isn’t supported any longer so I tried creating the remote PSSession in the script instead of from the schedtask -command line. This caused the script to fail again on the EWS folder creation portion of the script. I reverted back to using Add-PSSnapin. If anyone has a solution that will allow running a script that executes EWS tasks using impersonation from a scheduled task it would be appreciated.

Skip to main content