C#应用程序运行PowerShell多个远程命令

时间:2011-10-09 23:06:11

标签: powershell powershell-remoting

我有一个简单的控制台应用程序,试图通过PowerShell在Exchange中创建一个通讯组,并添加一些成员。

class Program
{
    static void Main(string[] args)
    {
        string userName = "foo";
        string password = "pwd";

        // Encrypt password using SecureString class
        SecureString securePassword = new SecureString();

        foreach (char c in password)
        {
            securePassword.AppendChar(c);
        }

        PSCredential credential = new PSCredential(userName, securePassword);

        // Connection information object required to connect to the service
        WSManConnectionInfo connectionInfo = new WSManConnectionInfo(
            new Uri("https://ps.outlook.com/powershell"), 
            "http://schemas.microsoft.com/powershell/Microsoft.Exchange", 
            credential);

        connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Basic;
        connectionInfo.MaximumConnectionRedirectionCount = 2;



        // Create runspace on remote Exchange server
        using (Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo))
        {
            runspace.Open();

            using(PowerShell ps = PowerShell.Create())
            {
                ps.Runspace = runspace;

                Command newDG = new Command("New-DistributionGroup");
                newDG.Parameters.Add(new CommandParameter("Name", "Test"));
                ps.Commands.AddCommand(newDG);

                Command addDGMember1 = new Command("Add-DistributionGroupMember");
                addDGMember1.Parameters.Add(new CommandParameter("Identity", "Test"));
                addDGMember1.Parameters.Add(new CommandParameter("Member", "testuser1@somecompany.com"));
                ps.Commands.AddCommand(addDGMember1);

                Command addDGMember2 = new Command("Add-DistributionGroupMember");
                addDGMember2.Parameters.Add(new CommandParameter("Identity", "Test"));
                addDGMember2.Parameters.Add(new CommandParameter("Member", "testuser2@somecompany.com"));
                ps.Commands.AddCommand(addDGMember2);


                try
                {
                    // Invoke command and store the results in a PSObject
                    Collection<PSObject> results = ps.Invoke();

                    if (ps.Streams.Error.Count > 0)
                    {
                        foreach (ErrorRecord error in ps.Streams.Error)
                        {
                            Console.WriteLine(error.ToString());
                        }
                    }

                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                finally
                {
                    Console.WriteLine("Operation completed.");
                }

            }
        }

        Console.ReadKey();
    }
}

当我运行我的应用程序时,它会抛出此错误:输入对象无法绑定到命令的任何参数,因为该命令不接受管道输入或输入及其属性与采用管道的任何参数不匹配输入

但实际上是创建了分发组。

另外,我注意到当我注释掉命令以创建新的通讯组并运行命令来添加通讯组成员时,只添加了第一个成员。我真的很困惑我应该如何继续这个,我有以下问题:

  1. 如何让我的代码成功运行所有命令?

  2. 执行多个远程PowerShell命令的最佳方法是什么?我是否单独运行每个命令,检查返回对象是否成功,然后继续执行下一个命令。是否有任何性能问题需要注意?

  3. 运行空间一次只运行一个命令吗?

  4. 当我尝试以下代码时,我遇到了这个错误: 此运行空间不支持该语法。这可能是因为它没有 - 语言模式。

    using (Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo))
            {
                runspace.Open();
    
                using(PowerShell ps = PowerShell.Create())
                {
                    ps.Runspace = runspace;
    
                    Pipeline pipe = runspace.CreatePipeline();
                    pipe.Commands.AddScript("New-DistributionGroup -Name Test2");
    
                    try
                    {
                        Collection<PSObject> results = pipe.Invoke();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                }
          }
    

1 个答案:

答案 0 :(得分:2)

System.Management.Automation.Powershell:

  

提供用于创建命令管道的方法   在a中同步或异步调用这些命令   运行空间。该类还提供对输出流的访问   包含调用命令时生成的数据。

重要的一部分 - create a pipeline。你正在做的是创建一个管道并使用ps.Commands.AddCommand向它添加命令,并且由于你添加它们的方式,以及你提供的其他参数,你会得到你看到的错误。因为New-DistributionGroup的输出对象无法输入Add-DistributionGroupMember,依此类推。

如此有效,管道中的第一个命令运行而下一个命令失败,因为你管道的对象不兼容(特别是在你添加的参数之后)。因此创建了通讯组,当您对其进行注释时,只会添加第一个成员。

您可以尝试使用Powershell.AddScript

string script = "New-DistributionGroup -Name Test; Add-DistributionGroupMember -Identity Test -Member testuser1@somecompany.com";
ps.AddScript(script);
ps.Invoke();

否则我认为你必须添加一个命令,调用它,清除命令(ps.Commands.Clear())并添加下一个命令,调用它等等。