Learn about Windows PowerShell
Summary: Learn how to use Windows PowerShell to run Exchange Server 2010 commands remotely by using implicit remoting.
Hey, Scripting Guy! I am having a problem with Exchange Server 2010. I have Windows PowerShell 2.0 installed on the server, but I am unable to connect and to do anything with it using Windows PowerShell remoting. I am forced to use RDP to make a remote desktop session, and then to launch the Exchange Server Management Shell to be able to do anything. I think this is rather stupid, especially when I can use Windows PowerShell remoting to establish a remote Windows PowerShell session on any other server in the domain, import whatever modules I need to use, and complete my work. I know that Exchange Server 2010 uses snap-ins, not modules; but still, it should work. I hate to rebuild my server, but I am about to do so because I am unable to fix whatever is broken. Can you help me? It will save me an entire weekend if you can.
Microsoft Scripting Guy, Ed Wilson, is here. Please do not FDISK your server! I say again, please do not FDISK your server. It will really be a waste of time. What you are no doubt experiencing is, in fact, the intended experience. You have no doubt discovered that the Exchange Server 2010 cmdlets are a little different—in fact, they are all functions. The great thing about this is that you can look at the content of every one of the functions to discover how they work.
One thing you need to know is that there is a difference between implicit remoting and explicit remoting. With explicit remoting, you create a remote session, enter a remote session, and you are dropped onto a Windows PowerShell console prompt on the remote computer. The Windows PowerShell prompt that you see is remote—it resides on the remote computer. Typing dir into the prompt displays the file system structure of the remote computer.
With implicit remoting, the commands from the remote session come to the local computer. Therefore, the Windows PowerShell prompt you see is local—it remains on your computer. Typing dir into the prompt displays the file system structure of the local computer.
If I make a remote connection to a server running Exchange Server 2010, and I add the three management snap-ins for Exchange Server, Windows PowerShell displays no errors. However, when I attempt to run a common Exchange Server command, such as Get-ExchangeServer, an error appears. The commands, and associated errors are shown in the image that follows.
The secret to using Windows PowerShell remoting to remotely manage a server running Exchange Server 2010 is to use implicit remoting instead of explicitly connecting to a remote Windows PowerShell session. Here are the steps required to create an implicit remote Windows PowerShell session.
The code that follows illustrates connection to a remote server running Exchange Server 2010 (named EX1) as the administrator from the iammred domain.
PS C:\> $cred = Get-Credential iammred\administrator
PS C:\> $session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri
http://ex1/powershell -Credential $cred
PS C:\> Import-PSSession $session
When the Import-PSSession command runs, a warning appears that states some of the imported commands use unapproved verbs. This is a normal warning for the Exchange Server commands, and can be safely ignored.
Note: The warning message is also why when one is writing Windows PowerShell modules, one should always use approved verbs. This avoids confusing users with the warning message. Display approved verbs by using the Get-Verb cmdlet.
When connected, the Exchange Server cmdlets appear in the local Windows PowerShell console and they work as if they locally installed. To obtain information about servers running Exchange Server, use the Get-ExchangeServer cmdlet. This command appears here.
Because there are several steps involved in making an implicit remoting session to a remote server running Exchange Server 2010, it becomes a good candidate for a function. Because the function is a bit long (with the comment-based Help), I also uploaded it to the Scripting Guys Script Repository. Here is the complete New-ExchangeSession function.
This function creates an implicit remoting connection to an Exchange Server
This function creates an implicit remoting session to a remote Exchange
Server. It has been tested on Exchange 2010. The Exchange commands are
brought into the local PowerShell environment. This works in both the
Windows PowerShell console as well as the Windows PowerShell ISE. It requires
two parameters: the computername and the user name with rights on the remote
New-ExchangeSession -computername ex1 -user iammred\administrator
Makes an implicit remoting connection to a remote Exchange 2010 server
named ex1 using the administrator account from the iammred domain. The user
is prompted for the administrator password.
The name of the remote Exchange server
The user account with rights on the remote Exchange server. The user
account is specified as domain\username
AUTHOR: ed wilson, msft
LASTEDIT: 01/13/2012 17:05:32
KEYWORDS: Messaging & Communication, Microsoft Exchange 2010, Remoting
#Requires -Version 2.0
$cred = Get-Credential -Credential $user
$session = New-PSSession -ConfigurationName Microsoft.Exchange `
-ConnectionUri http://$computername/powershell -Credential $cred
} #end function New-ExchangeSession
To gain access to the New-ExchangeSession function, I dot-source the script that contains the New-ExchangeSession function into my current Windows PowerShell session. When I run the function, a credential dialog box appears. This dialog box is shown in the image that follows.
When I enter the credentials, the implicit remoting session starts, and I can use cmdlets for Exchange Server as if they were installed on the local computer. In the following command, I retrieve information about Microsoft Exchange Server mailbox databases.
PS C:\> Get-MailboxDatabase
Name Server Recovery ReplicationType
---- ------ -------- ---------------
Mailbox Database 1301642447 EX1 False None
One command that is not available is the Get-ExCommand. I will talk about that tomorrow.
SW, that is all there is to using commands for Exchange Server 2010 from a remote computer. Join me tomorrow when I will talk about discovering imported commands for Exchange Server. I will also create a function to display the commands.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at firstname.lastname@example.org, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy
Thanks, Ed! Your timing was very serendipitous as just encountered this very problem last night! One question though: Does this mean that any Exchange 2010 functions run under those supplied credentials, but non-exchange commands would continue to run under the normal user context?
@JeremyEnbleWork I am glad the article was perfectly timed to meet your needs. While I would love to take credit for that aspect, alas I must mark it up to luck. However, I have seen many requests for this type of information, and therefore I wrote the article. You are absolutely correct. The remote connection credentials only apply to the proxy functions that appear after having made the remote connection to the Exchange Server. All other cmdlets, such as Get-Process or Get-Service will behave exactly as before -- they will refer to the local computer, and not to the remote Exchange server, and they will still operate within the original security context. This is one difference between implicit remoting (discussed here) and explicit remoting (discussed elsewhere on this blog) which actually creates a virtual PowerShell console on the local computer that thinks it is on the remote machine.
Nice one !! Thanks !!
I am getting the following error. Can you help me out with this?
PS H:\> $cred = Get-Credential send\senditadmin
PS H:\> $session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://send-xchange/powershell -Credential $cred
New-PSSession : A parameter cannot be found that matches parameter name 'ConnectionUri http'.
At line:1 char:84
+ $session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http: <<<< //send-xchange/powershell -Credential $cred
+ CategoryInfo : InvalidArgument: (:) [New-PSSession], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.NewPSSessionCommand
The first command worked perfectly. It asked for the credentials, which I gave it. The second command gives me the error.