Connecting to Exchange 2010 with PowerShell


One of Microsoft’s goals for Exchange 2010 is to provide administrators with the ability to manage servers from workstations without requiring the installation of the Exchange 2010 management components. Obviously some pre-requisites exist in that PowerShell 2.0 and Windows Remote Management must be installed on the workstation before you can even think about installing the Exchange 2010 management components, so that’s the first step to take care of. Assuming all the prerequisites are in place, you should be able to install the Exchange 2010 management components and then fire up the Exchange Management Shell (EMS) to connect to an Exchange 2010 in your local site.

If the Exchange 2010 management components are not installed on a workstation, then the EMS initialization script is not available and you have to perform the tasks that the initialization script performs to create the remote session, identify your account to Exchange with the necessary credentials to log onto the account, and import the set of cmdlets permitted for your role.

The first step in a do-it-yourself EMS session is to start PowerShell and use the Get-Credential cmdlet to input the username and password that we need to connect to the target Exchange organization. These credentials should be for a privileged account as otherwise you won’t be able to do very much.

$Credentials = Get-Credential

PowerShell displays a dialog to allow you to put in the username and password that we will use to connect. We then create a new remote PowerShell session and connect to the remote Exchange organization. Note that Kerberos is specified as the authentication method.

$ExSession = New-PSSession –ConfigurationName Microsoft.Exchange –ConnectionUri ‘http://ExServer1.contoso.com/PowerShell/?SerializationLevel=Full’ -Credential $Credentials –Authentication Kerberos

After we establish a session, we can import the set of Exchange cmdlets that our account is allowed to access. As shown in the screen shot below, EMS responds with an acknowledgement that it has imported the specified command set into the session.

Import-PSSession $ExSession

Connecting to Exchange 2010 with remote PowerShell

After the cmdlets are loaded into your session, you can work remotely in exactly the same manner as if you were logged onto the server. The Get-Command cmdlet will list the cmdlets loaded into the session and the Get-Help cmdlet can be run to show the help that is available for any of the cmdlets that are loaded into the session. Unfortunately, even though the EMS startup screen indicates that you can use wildcards with the Get-Help cmdlet, due to some issues with the operating system, the advent of Remote PowerShell has removed this ability that exists in Exchange 2007.

Once your session is established and you’re connected to Exchange 2010, all transactions flow across HTTP via IIS to be executed on the target server. When you are finished, you can terminate the session with the Remove-PSSession cmdlet.

Remove-PSSession $ExSession

Why would you create such a connection to Exchange? Well, you might want to use the PowerShell Integrated Scripting Environment (ISE) as your preferred tool to write and test scripts to automate aspects of your Exchange deployment. When you start ISE, it won’t connect to Exchange 2010 unless you instruct it to, so if you want to use any of the Exchange cmdlets in code, you have to connect to Exchange by running the commands described above (with the exception of retrieving your credentials as ISE will use the credentials of your logged-on session). You could do this by running a script (perhaps one that defines variables that you find useful) or you could create a custom menu option for ISE that runs the commands to connect to Exchange. The easiest way to do this is to edit your ISE profile to include the commands. See http://technet.microsoft.com/en-us/library/dd819492.aspx for details about how to credit and edit ISE profiles.

Most administrators probably do the simple thing and click on the EMS icon in the menu on a workstation where the Exchange 2010 management components are installed. Invoking EMS causes Windows to run this command:

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -noexit -command ". 'C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1'; Connect-ExchangeServer -auto"

The initialization script is RemoteExchange.ps1, which does what’s indicated by its name and creates a remote PowerShell connection to Exchange 2010. Interestingly, the Connect-ExchangeServer command immediately afterwards is the one that connects EMS to an Exchange 2010 server in the site. Note that it uses the -Auto parameter, meaning that EMS will attempt to connect to the local system (if it is a server running Exchange 2010) followed by other servers running in the local site (CAS servers first, then mailbox servers).

You can run the Connect-ExchangeServer cmdlet in an EMS session to force EMS to connect to a specific server. This is a useful thing to do if you want to connect to a specific server such as one in another Active Directory site. For example:

Connect-ExchangeServer -Server exserver1.contoso.com

Switching the connected server with the Connect-ExchangeServer cmdlet

In the screen shot you see that EMS initializes and connects as normal – in this case to server ExServer1. We then run Connect-ExchangeServer and specify exserver2.contoso.com as the target server. EMS connects to this Exchange 2010 server and loads in the cmdlets permitted by the RBAC roles held by the user. As you can see, any cmdlet that is already available for the session is skipped. After connecting to server exserver2, all future cmdlets run in the session are executed on that server. This won’t matter if you are working with organization-wide configuration data but it does if you run cmdlets that do things like change OWA virtual directory settings and don’t specify a target server.

It’s worth saying that remote PowerShell is one of the more fragile components of Exchange 2010 because it depends on so many moving parts to work together before you can connect. IIS must be configured correctly with the right modules and setting; WinRM has to permit the HTTP requests to pass; WSMan must be able to communicate with the servers; and your mailbox has to be authorized to run PowerShell (the default setting). If you run into problems, you should consult the post on Troubleshooting Exchange 2010 management tools startup issues to provide a good starting point for where you need to look to make everything right.

Hope this helps!

– Tony

Follow Tony @12Knocksinna

This is material that isn’t included in my Microsoft Exchange Server 2010 Inside Out book, mostly because I had to cut pages to fit the book into the prescribed limit of 1,300 pages set by Microsoft Press. If this is an example of stuff that’s been cut, you can imagine the value of the material that’s been retained! The book is also available from Amazon.co.uk.

*** Update December 7, 2010: Microsoft has released the Exchange Management Troubleshooter (EMT), a utility designed to look for common problems that might cause Remote PowerShell (and by design, all of the Exchange 2010 management tools) not to work properly on a server. You can read all about EMT on EHLO.

About Tony Redmond

Lead author for the Office 365 for IT Pros eBook and writer about all aspects of the Office 365 ecosystem.
This entry was posted in Exchange, Exchange 2010 and tagged , , , , , . Bookmark the permalink.

30 Responses to Connecting to Exchange 2010 with PowerShell

  1. Simon Walsh says:

    Hi Tony

    Excellent blog!

    There is one small limitation of connecting to Exchange in this way. By using EMS you get access to Exchange datatypes but they are not present when connecting to Exchange using this method.
    An example:
    $mbx = Get-MailboxStatistics “administrator”
    This will retrieve the mailbox statistics but it will not give you access to the specific datatypes.
    $mbx.TotalItemSize.ToMB() will fail for example
    Method invocation failed because [System.String] doesn’t contain a method named ‘ToMB’
    I usually load the Exchange Data dll to get round this
    $EXdll = “C:\Program Files\Microsoft\Exchange Server\V14\Bin\Microsoft.Exchange.Data.dll”
    [Reflection.Assembly]::LoadFile($EXdll)
    Then you can explicitly set the correct data type. For example:
    $MbxDB = Get-MailboxDatabase DB01
    [Microsoft.Exchange.Data.ByteQuantifiedSize]$DBSize = $MbxDB.DatabaseSize
    Now you can us the ToMB(), ToGB() etc

    There are probably easier ways to this (maybe by using a PSSnapin) but I have found this work pretty well when writing scripts.

    /Simon

    • Ronald Top says:

      Hi Simon,

      Thanks for your addition. I struggled with the same thing. However, when I cast the type

      I get the following error below. I have the common.dll in the same dir as the exchange.data.dll. I also tried to importthe common.dll in the ps session, however, no success. Any ideas ? I really need the remoting, I cannot install the Exchange 2010 admin tools.

      BR,

      Ronald

      Cannot convert value “514.8 MB (539,818,929 bytes)” to type “Microsoft.Exchange.Data.ByteQuantifiedSize”. Error: “Could
      not load file or assembly ‘Microsoft.Exchange.Data.Common, Version=8.0.681.0, Culture=neutral, PublicKeyToken=31bf3856
      ad364e35’ or one of its dependencies. The system cannot find the file specified.”
      At line:1 char:97
      + [Microsoft.Exchange.Data.ByteQuantifiedSize](Get-MailboxStatistics -Identity j.beton@derco.com). <<<< TotalItemSize
      + CategoryInfo : NotSpecified: (:) [], RuntimeException
      + FullyQualifiedErrorId : RuntimeException

  2. Nicholas says:

    I have a question in regards enumerating what Exchange powershell sessions are still open, be it local or remote.
    In our evironment support staff have access to Exchange 2010 servers through remote powershell. It’s typical that most support staff don’t remove their sessions for what ever reason. I don’t wish to increase the possible sessions available to each user. How can I therfore enumerate what sessions are still open and further more how would I go about closing them off on behalf of the support staff member?

  3. Do Tuan says:

    Hi,
    I execute C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -noexit -command “. ‘C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1′; Connect-ExchangeServer -auto” command from javaprogram but fail ’emoteExchange.ps1” is not recognized as an internal or external command. Do you help me?

    Source java

    String[] command = new String[4];

    command[0] = “cmd”;

    command[1] = “C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -noexit -command \”. ‘C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1’; Connect-ExchangeServer -auto\””;

    command[2] = “$Temp = ConvertTo-SecureString 123456 -asPlainText –Force”;
    command[3] = “New-Mailbox -Name tuandm -UserPrincipalName tuandm@metfone.com.kh -OrganizationalUnit metfone.com.kh/metfone/Users -Database metfone -Password $Temp | Set-Mailbox -IssueWarningQuota 136314889 -ProhibitSendReceiveQuota 157286400 -UseDatabaseQuotaDefaults $false”;
    Process p = Runtime.getRuntime().exec(command );
    p.getOutputStream().close();

    • I wish I could help you, but I am not a Java programmer – or even much of a programmer now as the last code I wrote was with Visual Basic some 15 years ago. I doubt that my experience with VAX COBOL and VAX BASIC will help much here. But maybe some other reader of the blog can help…

      TR

  4. Tony, I’m a bit off-topic here with my post, but I didn’t know where else to put it. I’m having a big problem trying to get the Administrative Tools for Exchange 2010 SP1 to install on my Windows 7 64 bit machine. I know I have all prerequisites in place, yet when I start the install, it aborts early on with a Powershell error:

    setup.com /R:MT

    The type initializer for ‘Microsoft.Exchange.Management.PowerShell.CmdletConfigurationEntries’ threw an exception.
    The type initializer for ‘Microsoft.Exchange.Data.Directory.ADSession’ threw an exception.

    Exchange Server setup encountered an error.

  5. Are you running Setup as an Administrator on a domain joined machine?

    TR

  6. BTW, it is not good to blast a question to several forums looking for a response. I note that you asked the same question on http://forums.msexchange.org/m_1800551654/mpage_1/key_/tm.htm#1800551654. The problem is that if people seeing you do this, they will assume that the question will be answered elsewhere and simply ignore the question here.

    TR

  7. First of all, I’m sorry for the poor forum etiquette.

    Yes, I’m using a machine joined to the domain. I’m using the same account I used when I installed made the schema updates and installed Exchange on the server.

  8. Maybe you should download and try running the Exchange Management Tools troubleshooter from http://gallery.technet.microsoft.com/Exchange-Management-b9d918b1 to see whether it can help find the problem. If you’ve been able to install Exchange (and the Exchange Setup log looks OK with no obvious errors) from the same account, it maybe that something isn’t started…

    TR

  9. Tim Orange says:

    Hi Tony,

    This was an excellent post. I lke using the PSE tool, but when I go to the servers, I cannot use it. I am wondering if it is still safe for me to connect and do everything with my 32 bit version of Windows 7. I am thinking that it is since I am running a remote session on our server.

    I just want to say thanks for the help. This was a good one!

  10. Mvd says:

    I did have this nice procedure working for remoting an exchange script from a scheduled task. Today this script isn`t working anymore.
    When doing troubleshooting i did find after starting remoteExchange.ps1, not any exchange-command will work –> the term ‘get-mailbox’ is not recognized as the name of a cmdlet.

    What is the problem?

    Thx

    • Who knows what the problem is? Seriously, you haven’t provided much data to allow any serious debugging to occur. However, if not even Get-Mailbox is available to the session, it points to the Exchange snap-in not being loaded for some reason. The question then is what has changed between the time when the procedure worked and now. Was a software update performed? Did some aspect of the system change?
      TR

  11. iczer1 says:

    I’ve noticed (in my enviroment at least) that I can’t use the FQDN of the CAS array for the -ServerFqdn parameter of Connect-ExchangeServer. I can connect to individual CAS servers and the -Auto and -Forest parameters work as well. Is this just something with my enviroment or is this how the cmdlet works?

  12. Alan says:

    Can you offer any advice please?

    I created a user with Exchange View Only rights. If l logon as that user on an Windows 2008 server where the Exchange 2010 management tools are installed, I can manually run the following without any problems:

    C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -noexit -command “. ‘C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1’; Connect-ExchangeServer -auto”

    However, if I run that in a scheduled task, the task itself runs without error. But the Connect-ExchangeServer throws an “internal error” and “CreateRemoteRunSpace” exception. Using “auto” or specifying a CAS server doesn’t help. Making the user a domain-admin and/or Exchange Organizational Admin doesn’t help either.

    I’ve reproduced this on two different systems. Slàn.

  13. subhakar says:

    Hi Tony, good insight into Exchange PowerShell. One small requirement want to check how this can be achieved. Want to run “Set-AdServerSettings -ViewEntireForest $true” command at startup while connecting to Exchange online from a multiple remote workstation which does not have EMC tools installed.
    Thank you,

  14. Pingback: Adapting Exchange on-premises scripts for Exchange Online | Thoughtsofanidlemind's Blog

  15. Martín Larrosa says:

    Is it possible to send username and password inside the script instead of typing it into the dialog box?

  16. N.Hamaydeh says:

    Hi ..
    Thanks all for your kind comments and help
    i ran through the procedure above, then i get an error when running the command “Import-PSSession $ExSession”

    [PS] C:\Windows\system32>$Credentials = Get-Credential

    cmdlet Get-Credential at command pipeline position 1
    Supply values for the following parameters:
    Credential

    [PS] C:\Windows\system32>$ExSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri `http://MYSERVER/PowerShell/?SerializationLevel=Full’ -Credential $Credentials -Authentication Kerberos
    [PS] C:\Windows\system32>Import-PSSession $ExSession
    WARNING: Proxy creation has been skipped for the following command: ‘Add-DistributionGroupMember,
    Add-MailboxFolderPermission, Clear-ActiveSyncDevice, Clear-TextMessagingAccount, Compare-TextMessagingVerificationCode,
    Disable-InboxRule, Enable-InboxRule, Get-ActiveSyncDevice, Get-ActiveSyncDeviceStatistics, Get-CalendarNotification,
    Get-CalendarProcessing, Get-CASMailbox, Get-DistributionGroup, Get-DistributionGroupMember, Get-Group, Get-InboxRule,
    Get-Mailbox, Get-MailboxAutoReplyConfiguration, Get-MailboxCalendarConfiguration, Get-MailboxCalendarFolder,
    Get-MailboxFolder, Get-MailboxFolderPermission, Get-MailboxJunkEmailConfiguration, Get-MailboxMessageConfiguration,
    Get-MailboxRegionalConfiguration, Get-MailboxSentItemsConfiguration, Get-MailboxSpellingConfiguration,
    Get-MailboxStatistics, Get-MessageCategory, Get-MessageClassification, Get-MessageTrackingReport, Get-Recipient,
    Get-TextMessagingAccount, Get-UMMailbox, Get-User, New-InboxRule, New-MailboxFolder, New-MailMessage,
    Remove-ActiveSyncDevice, Remove-DistributionGroupMember, Remove-InboxRule, Remove-MailboxFolderPermission,
    Search-MessageTrackingReport, Send-TextMessagingVerificationCode, Set-CalendarNotification, Set-CalendarProcessing,
    Set-CASMailbox, Set-InboxRule, Set-Mailbox, Set-MailboxAutoReplyConfiguration, Set-MailboxCalendarConfiguration,
    Set-MailboxCalendarFolder, Set-MailboxFolderPermission, Set-MailboxJunkEmailConfiguration,
    Set-MailboxMessageConfiguration, Set-MailboxRegionalConfiguration, Set-MailboxSentItemsConfiguration,
    Set-MailboxSpellingConfiguration, Set-MailUser, Set-TextMessagingAccount, Set-UMMailbox, Set-UMMailboxPIN, Set-User’,
    because it would shadow an existing local command. Use the AllowClobber parameter if you want to shadow existing local
    commands.
    Import-PSSession : No command proxies have been created, because all of the requested remote commands would shadow exis
    ting local commands. Use the AllowClobber parameter if you want to shadow existing local commands.
    At line:1 char:17
    + Import-PSSession <<<

  17. ronal says:

    estimado consultarle si hay forma de hacer una conexión remota mediante powershell sin tener un relación de confianza…

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.