Приложение C # запускает несколько удаленных команд PowerShell - PullRequest
0 голосов
/ 10 октября 2011

У меня есть простое консольное приложение, пытающееся создать группу рассылки в Exchange через PowerShell и добавить в нее несколько участников.

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. Запускает ли среда выполнения только одну команду за раз?

Когда я пробую следующий код, я сталкиваюсь с этой ошибкой: Синтаксис не поддерживается этим пространством выполнения. Это может быть потому, что в языковой режим.

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 Ответ

2 голосов
/ 10 октября 2011

System.Management.Automation.Powershell:

Предоставляет методы, которые используются для создания конвейера команд и вызывать эти команды синхронно или асинхронно в пределах пространство выполнения. Этот класс также обеспечивает доступ к выходным потокам, которые содержит данные, которые генерируются при вызове команд.

Важная часть - 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()) и добавить следующую команду, вызвать ее и т. Д.

...