#powershell #powershell-remoting
#powershell #powershell-удаленное управление
Вопрос:
У меня есть простое консольное приложение, пытающееся создать группу рассылки в 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();
}
}
Когда я запускаю свое приложение, оно выдает эту ошибку: объект ввода не может быть привязан к каким-либо параметрам для команды либо потому, что команда не принимает конвейерный ввод, либо потому, что ввод и его свойства не соответствуют ни одному из параметров, которые принимают конвейерный ввод.
Но группа распространения фактически создается.
Кроме того, я замечаю, что когда я комментирую команду для создания новой группы рассылки и запускаю команды для добавления членов группы рассылки, добавляется только первый член. Я действительно не понимаю, как мне следует поступить с этим, и у меня есть следующие вопросы:
-
Как я могу заставить свой код успешно выполнять все команды?
-
Каков наилучший способ выполнения нескольких удаленных команд PowerShell? Должен ли я запускать каждую команду отдельно, проверять возвращаемый объект, если он был успешным, а затем переходить к следующей команде. Какие-либо проблемы с производительностью, о которых следует знать?
-
Выполняет ли runspace только одну команду за раз?
Когда я пытаюсь выполнить следующий код, я сталкиваюсь с этой ошибкой: Синтаксис не поддерживается этим пространством выполнения. Это может быть связано с тем, что оно находится в режиме без языка.
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. @kiquenet библиотеку C # с полной реализацией можно найти здесь github.com/neutmute/exchange-client
Ответ №1:
Система.Управление.Автоматизация.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()
) и добавить следующую команду, вызвать ее и так далее.