【问题标题】:how to invoke the powershell command with "format-list" and "out-file" pipeline from c#?如何从 C# 调用带有“格式列表”和“输出文件”管道的 powershell 命令?
【发布时间】:2011-07-11 19:49:19
【问题描述】:

您好,我正在开发一个 C# 程序,以在远程运行空间中调用 exchange 2010 powershell cmdlet。 ps 命令是:

"Get-MailboxDatabase -Server EX2010SVR1 -Status | Format-List Identity,Guid,mounted,CircularLoggingEnabled,Recovery |输出文件 'C:\db.txt' -Encoding UTF8 -Width 8192".

我的代码类似于:


static int Main(string[] args)
{

    const string SHELL_URI = "http://schemas.microsoft.com/powershell/Microsoft.Exchange";
    const string COMMAND = "Get-MailboxDatabase -Server EX2010SVR1 -Status | Format-List Identity,Guid,mounted,CircularLoggingEnabled,Recovery | Out-File 'C:\db.txt' -Encoding UTF8 -Width 8192";

    System.Uri serverUri = new Uri("http://EX2010SVR1/powershell?serializationLevel=Full");
    PSCredential creds = (PSCredential)null; // Use Windows Authentication
    WSManConnectionInfo connectionInfo = new WSManConnectionInfo(serverUri, SHELL_URI, creds);

    try
    {
        using (Runspace rs = RunspaceFactory.CreateRunspace(connectionInfo))
        {
            rs.Open();
            PowerShell psh = PowerShell.Create();
            psh.Runspace = rs;
            psh.AddCommand(COMMAND);
            Collection results = psh.Invoke();
            rs.Close();
        }
    }
    catch (Exception ex)
    {
        System.Console.WriteLine("exception: {0}", ex.ToString());
    }
    return 0;
}

当我在托管 Exchange 2010 服务器的 Win2008 R2 上运行 c# 程序时,我总是遇到异常:


    System.Management.Automation.RemoteException: The term 'Format-List' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
    at System.Management.Automation.PowerShell.CoreInvoke[TOutput](IEnumerable input, PSDataCollection`1 output, PSInvocationSettings settings)
    at System.Management.Automation.PowerShell.Invoke(IEnumerable input, PSInvocationSettings settings)
    at System.Management.Automation.PowerShell.Invoke()
    at RemotePS.Program.Main(String[] args)

在没有“Format-List”和“Out-File”管道的情况下,程序运行良好。整个命令在 exchange 2010 管理 shell 中也可以正常工作。我还确认它是系统上的 powershell 2.0。

任何人都可以帮助弄清楚发生了什么吗?非常感谢任何帮助。

汤姆

【问题讨论】:

  • 如果您在没有 Format-List cmdlet 的情况下执行命令会发生什么情况,最后这是“格式化”cmdlet,您可以出于测试原因尝试放弃它。 ?
  • 另一件事:查看在线文档,您可以找到 Format-List 适用于:Windows PowerShell 2.0。可能在“服务器端”命令外壳不是 2.0
  • 程序在没有“格式列表”和“输出文件”管道的情况下运行良好。整个命令在 exchange 2010 管理 shell 中也可以正常工作。

标签: c# powershell exchange-server-2010


【解决方案1】:

我写的第一个嵌入式 PowerShell 也遇到了同样的问题。我在寻找踪迹,但我再也找不到了。

这里有一些对我有用的东西,我适应了你的代码:

static void Main(string[] args)
{
  const string SHELL_URI = "http://schemas.microsoft.com/powershell/Microsoft.PowerShell";
  const string COMMAND = @"get-process | format-List | Out-File -file c:\temp\jpb.txt";
  System.Uri serverUri = new Uri("http://WM2008R2ENT/powershell?serializationLevel=Full");
  PSCredential creds = (PSCredential)null; // Use Windows Authentication
  WSManConnectionInfo connectionInfo = new WSManConnectionInfo(false,
                                                               "WM2008R2ENT",
                                                               5985,
                                                               "/wsman",
                                                               SHELL_URI,
                                                               creds);
  try
  {
    using (Runspace rs = RunspaceFactory.CreateRunspace(connectionInfo))
    {
      rs.Open();

      Pipeline pipeline = rs.CreatePipeline();

      string cmdLine;
      cmdLine = string.Format("&{{{0}}}", COMMAND);

      pipeline.Commands.AddScript(cmdLine);

      Collection<PSObject> results = pipeline.Invoke();

      rs.Close();
    }
  }
  catch (Exception ex)
  {
    System.Console.WriteLine("exception: {0}", ex.ToString());
  }
  return; 
}

小心,我没有使用 Exchange PowerShell

在我使用管道的示例中,您的问题可能来自您传递命令的方式。

【讨论】:

  • 所以你可以把问题作为回答?
【解决方案2】:

您可以尝试使用“命令”对象。

Runspace rs = RunspaceFactory.CreateRunspace();
PowerShell ps = PowerShell.Create();

Pipeline pipeline = rs.CreatePipeline();

Command cmd1 = new Command("Get-MailboxDatabase");
cmd1.Parameters.Add("Server", "EX2010SVR1");
cmd1.Parameters.Add("Status");
pipeline.Commands.Add(cmd1);

Command cmd2 = new Command("Format-List");
cmd2.Parameters.Add("Property", "Identity, Guid, mounted, CircularLoggingEnabled, Recovery");
pipeline.Commands.Add(cmd2);

Command cmd3 = new Command("Format-List");
cmd3.Parameters.Add("FilePath", "C:\db.txt");
cmd3.Parameters.Add("Encoding", "UTF8");
cmd3.Parameters.Add("Width", "8192");
pipeline.Commands.Add(cmd3);

Collection<PSObject> output = pipeline.Invoke();

参见此处:Invoking powershell cmdlets from C#

【讨论】:

    【解决方案3】:

    我意识到这是一个旧线程,但我想展示我的发现,不管它们有多短。

    我最近和我的一位同事遇到了同样的问题。我们设法将问题追溯到丢失的运行空间。我们还必须连接到Microsoft.Exchange 运行空间,当我们这样做时,Format-List 命令行开关变得不可用。如果我们不使用运行空间,命令行开关就可以正常工作。

    我们还没有解决这个问题,但我打算探索使用RunspacePool 而不仅仅是Runspace 的可能性,从而允许在管道中执行两个命令行开关。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-10
      • 1970-01-01
      • 2021-08-04
      • 1970-01-01
      • 2014-08-30
      • 2018-12-26
      • 2020-04-04
      相关资源
      最近更新 更多