C# 应用程序运行 PowerShell 多个远程命令
我有一个简单的控制台应用程序尝试通过 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", "[email protected]"));
ps.Commands.AddCommand(addDGMember1);
Command addDGMember2 = new Command("Add-DistributionGroupMember");
addDGMember2.Parameters.Add(new CommandParameter("Identity", "Test"));
addDGMember2.Parameters.Add(new CommandParameter("Member", "[email protected]"));
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 命令的最佳方法是什么?我是否单独运行每个命令,检查返回对象是否成功,然后继续执行下一个命令。有需要注意的性能问题吗?
运行空间一次只运行一个命令吗?
当我尝试以下代码时,遇到此错误: 此运行空间不支持该语法。这可能是因为它不 - 语言模式。
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);
}
}
}
I have a simple console app trying to create a distribution group in Exchange via PowerShell and add a few members to it.
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", "[email protected]"));
ps.Commands.AddCommand(addDGMember1);
Command addDGMember2 = new Command("Add-DistributionGroupMember");
addDGMember2.Parameters.Add(new CommandParameter("Identity", "Test"));
addDGMember2.Parameters.Add(new CommandParameter("Member", "[email protected]"));
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();
}
}
When I run my app it throws this error: The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.
But the distribution group actually gets created.
Also, I notice that when I comment out the command to create a new distribution group and run the commands to add the distribution group members, only the first member is added. I'm really confused as to how I should proceed on this and I have the following questions:
How can I get my code to run all the commands successfully?
What would be the best way to do multiple remote PowerShell commands? Do I run each command separately, check the return object if it was successful, and then proceed to the next command. Any performance issues to be aware of?
Does the runspace run only one command at a time?
When I try the following code, I run into this error:
The syntax is not supported by this runspace. This might be because it is in no-
language mode.
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);
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
系统.管理.自动化.Powershell:
重要的部分是 -
创建管道
。您正在做的是创建一个管道并使用 ps.Commands.AddCommand 向其添加命令,并且由于您添加命令的方式以及您提供的其他参数,您会收到以下错误:看。因为New-DistributionGroup
的输出对象无法提供给Add-DistributionGroupMember
等。因此,管道中的第一个命令运行,而下一个命令失败,因为您通过管道传输到它的对象不兼容(特别是在您添加的参数之后)。因此,通讯组已创建,当您将其注释掉时,仅添加第一个成员。
您可以尝试的一件事是使用 Powershell.AddScript:
否则我认为您将必须添加命令,调用它,清除命令(ps.Commands.Clear()) code>) 并添加下一个命令,调用它等等。
System.Management.Automation.Powershell:
Important part being -
create a pipeline
. What you are doing is creating a pipeline and adding commands to it using theps.Commands.AddCommand
and since the way you have added them, with additional parameters that you have supplied, you get the error that you see. Because the output object ofNew-DistributionGroup
cannot be fed toAdd-DistributionGroupMember
and so on.So effectively, the first command in the pipeline runs and the next one fails because the object you are piping to it is not compatible (especially after the parameters that you add). So the distribution group gets created and when you comment that out, only the first member gets added.
One thing that you can try is to use
Powershell.AddScript
:Otherwise I think you will have to add a command, invoke it, clear the command (
ps.Commands.Clear()
) and add the next command, invoke it and so on.