How to call Exchange 2010 cmdlet's using Remote Powershell in code
I have seen this question posed a lot so I decided that I would post a quick code sample here and the complete sample on my samples site.
In my sample I created a managed client and a native client which both call into a managed DLL that runs the Get-ExchangeServer cmdlet using Remote Powershell. Here is the method that actually does the work if you don't want to download the entire sample:
private const string SHELL_URI = "schemas.microsoft.com/powershell/Microsoft.Exchange";
public void GetExchangeServers(string serverName, string userName, string password, out string[] servers)
{
System.Uri serverUri = new Uri(String.Format("{0}/powershell?serializationLevel=Full", serverName));
string[] retVal = null;
System.Security.SecureString securePassword = new System.Security.SecureString();
foreach (char c in password.ToCharArray())
{
securePassword.AppendChar(c);
}
System.Management.Automation.PSCredential creds = new System.Management.Automation.PSCredential(userName, securePassword);
RunspaceConfiguration rc = RunspaceConfiguration.Create();
WSManConnectionInfo wsManInfo = new WSManConnectionInfo(serverUri, SHELL_URI, creds);
using (Runspace rs = RunspaceFactory.CreateRunspace(wsManInfo))
{
rs.Open();
PowerShell psh = PowerShell.Create();
psh.Runspace = rs;
psh.AddCommand("Get-ExchangeServer");
Collection<PSObject> results = psh.Invoke();
if (psh.Streams.Error.Count > 0)
{
foreach (ErrorRecord err in psh.Streams.Error)
{
// handle the error some how
}
rs.Close();
servers = null;
return;
}
retVal = new string[1];
foreach (PSObject result in results)
{
if (null == retVal[0] || retVal[0].Length == 0)
{
retVal[0] = result.Members["Name"].Value as string;
}
else
{
string[] newVal = new string[retVal.Length + 1];
retVal.CopyTo(newVal, 0);
newVal[retVal.Length] = result.Members["Name"].Value as string;
retVal = newVal;
}
}
rs.Close();
}
rc = null;
servers = retVal;
}
Comments
Anonymous
October 11, 2010
The account being used needs to be in an appropriate RBAC role under 2010 in order to have the appropriate permissions. The links below cover some information in this area which you may find helpful. Understanding Role Based Access Control technet.microsoft.com/.../dd298183.aspx Understanding Management Roles technet.microsoft.com/.../dd298116.aspxAnonymous
February 13, 2011
The comment has been removedAnonymous
April 28, 2011
@VS6 - On the surface that may be true, however if you want to interact with the returned results in an object oriented way I don't think your command will do.Anonymous
July 21, 2011
Thanks for the sample! I downloaded the complete sample but it won't compile because the type WSManConnectionInfo is not found in the 64-bit version of the reference assembly System.Management.Automation.dll (C:Program FilesReference AssembliesMicrosoftWindowsPowerShellv1.0System.Management.Automation.dll). If I change the reference to the 32-bit version of the assembly (C:Program Files (x86)Reference AssembliesMicrosoftWindowsPowerShellv1.0System.Management.Automation.dll), it compiles and runs. However, my process is now running as 32-bit (as indicated by DebugDiag v1.2), and I would like it to be a 64-bit process. Any ideas? Regards, MarkGAnonymous
July 21, 2011
Hi Mark, It should be available in the 64 bit version. I will check to confirm; in the meantime I would suggest pulling the automation DLL from the GAC. Look for the 64 bit version in there and be sure that you have RTM version of Powershell 2.0 installed.Anonymous
August 23, 2011
The correct 64-bit (only) 2,0 version of System.Management.Automation is located at: C:WindowsassemblyGAC_MSILSystem.Management.Automation1.0.0.0__31bf3856ad364e35System.Management.Automation.dll. Check out this post, I found it very helpful: scorpiotek.com/blogAnonymous
March 08, 2012
Good example, but how to do this by impersonating the person who is running the code, instead of using hardcoded user ID and password?Anonymous
March 08, 2012
Hi Petri X, Please see my article : blogs.msdn.com/.../how-to-use-windows-authentication-with-the-pscredential-class.aspxAnonymous
March 11, 2012
Thanks Dave, but does your example means that you need to have own login screen on your application? And you cannot use e.g. Windows Integrated authentication? I see the Windows Integrated authentication is the better way to go forward, or what do you think?Anonymous
March 11, 2012
The link above to my other article shows you how to use Windows Integrated Authentication which means that it will impersonate the user who is logged into the application. Therefore, you wouldn't need a login screen provided that you are using Windows Authentication for your application.Anonymous
March 11, 2012
Ah, just realize it was windows application, I'm looking for an web app application instead. But let see if I can find some useful lines from your code, thanks,Anonymous
October 20, 2014
Hi ~ i read your code. i think this code that i found . it very useful to me. so i want download your complete code. thank you very much.Anonymous
October 29, 2014
The comment has been removed