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;
}