Share via


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.aspx

  • Anonymous
    February 13, 2011
    The comment has been removed

  • Anonymous
    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, MarkG

  • Anonymous
    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/blog

  • Anonymous
    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.aspx

  • Anonymous
    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