如何在C#中将PowerShell命令进行管道传递

7

目标是获取Exchange 2010站点的最小数据库,因此我正尝试从c#运行以下powershell命令:

Get-MailboxDatabase -server Exchange2010 -Status | select-object Name,DatabaseSize

我的翻译如下:

我正在困扰的问题是-如何管道化Select子句命令。

这是我的尝试,

WSManConnectionInfo wsConnectionInfo = new WSManConnectionInfo(new Uri("https://" + ExchangeSite + "/powershell?serializationLevel=Full"),
    "http://schemas.microsoft.com/powershell/Microsoft.Exchange", getCredential());
wsConnectionInfo.AuthenticationMechanism = AuthenticationMechanism.Basic;
wsConnectionInfo.SkipCACheck = true;
wsConnectionInfo.SkipCNCheck = true;

rsRemoteRunspace = RunspaceFactory.CreateRunspace(wsConnectionInfo);
rsRemoteRunspace.Open();
Pipeline pipeLine = rsRemoteRunspace.CreatePipeline();

Collection<PSObject> DatabaSize = null;

Command myCommand = new Command("Get-MailboxDatabase");
myCommand.Parameters.Add("Server", "Exchange2010");
myCommand.Parameters.Add("Status", null);
Command myCommand2 = new Command("Select-Object");
    myCommand.Parameters.Add("Name");
myCommand.Parameters.Add("DatabaseSize");
pipeLineMB.Commands.Add(myCommand);
pipeLineMB.Commands.Add(myCommand2);
DatabaSize = pipeLine.Invoke();

但是我正在接收到,
"A parameter cannot be found that matches parameter name 'Name'."

请记住,我无法使用 SnapIn,因为代码必须在执行 Exchange 服务器的 cmdlet 的客户端机器上运行。
欢迎任何建议。
编辑
我应用了 yamen 建议的修复方法,命令能够被调用,但当我尝试获取值时,我得到了这样的错误:"对象引用未设置到对象的实例。"
请注意,我可以获取 Servername 和 Name 的值,但在 DatabaseSize 中失败,所以我猜测 'Status' 标志没有被正确设置,因为这个标志是启用该值的标志。

"select" 是 Select-Object 的别名,我认为你不能在 "Command" 构造函数中使用别名(通常我不这样做)。 - Michael Edenfield
@MichaelEdenfield,如果我将其更改为Select-Object,则会出现“找不到与参数名'DatabaseSize'匹配的参数”。请注意,相同的命令在PowerShell ISE中运行良好,Get-MailboxDatabase -server exchange2010 -Status | select-object DatabaseSize。 - m0dest0
2个回答

4
我刚刚尝试了这个功能,以得到一个类似的场景。
dir | select Name

它不起作用。给我同样的错误,说“名称”不是有效的参数。然后我尝试了下面的方法,它可以工作。

dir | select -first 3

翻译成

        Runspace runspace = RunspaceFactory.CreateRunspace();
        runspace.Open();
        Pipeline pipeline = runspace.CreatePipeline();
        Command dir = new Command("dir");
        pipeline.Commands.Add(dir);
        Command select = new Command("select");
        select.Parameters.Add("first", 3);
        pipeline.Commands.Add(select);

我猜你需要找到DatabaseSize为其值的参数名称。


根据我的回答,该参数被称为“属性”。 - yamen

4

您是指这个吗:

Command myCommand2 = new Command("Select-Object");
myCommand2.Parameters.Add("DatabaseSize");

不要这样做:

Command myCommand2 = new Command("Select-Object");
myCommand.Parameters.Add("DatabaseSize");

注意第二行的myCommand2吗?

无论如何,你可能会发现你实际想要的参数是Property,即:

myCommand2.Parameters.Add("Property", "DatabaseSize");

而对于多个:

var props = new string[] { "DatabaseSize", "ServerName", "Name" };
myCommand2.Parameters.Add("Property", props);

我能够调用命令,但现在尝试获取该值时出现错误。我想猜测 -Status 标志没有正确应用,请确认一下是否我使用了正确的方式。请查看上面我的评论。 - m0dest0
尝试使用myCommand.Parameters.Add("Status", true);或者只使用myCommand.Parameters.Add("Status");,并回报结果。 - yamen
我刚刚意识到,标志必须以以下方式输入:myCommand.Parameters.Add("Status", true); 谢谢。 - m0dest0
亚门,我取消了答案的标记,只是为了引起你的注意,希望你能收到通知并在这个帖子上发表评论。谢谢。 - m0dest0
@m0dest0,我能建议您另开一个新问题吗?这将是一个不同的问题,而且您不应该使用一个问题来不断编辑解决不同的问题。如果人们解决了您的问题,然后您提出另一个问题并收回声望,他们可能不太可能回答您的问题。 - yamen
请注意,您可以在评论中只输入 @yamen 来提醒我。在新问题中这样做,我会查看并回复。 - yamen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接