Как вызвать команду powershell с конвейером «format-list» и «out-file» из c #? - PullRequest
2 голосов
/ 11 июля 2011

Привет, я работаю над программой на C # для вызова командлетов Exchange 2010 powershell в удаленном пространстве выполнения.Команда ps:

"Get-MailboxDatabase -Server EX2010SVR1 -Status | Идентификатор формата списка, Guid, смонтировано, CircularLoggingEnabled, Recovery | Out-File 'C: \ db.txt' -EncodingUTF8 -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;
}

Когда я запускаю программу c # на Win2008 R2, где размещается сервер Exchange 2010, я всегда получаю исключение:


    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.Я также подтвердил, что в системе установлен PowerShell 2.0.

Может ли кто-нибудь помочь понять, что происходит?Любая помощь очень ценится.

Том

Ответы [ 3 ]

1 голос
/ 12 июля 2011

У меня та же проблема с первым встроенным 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

В примере, который я использую конвейер, возможно, ваша проблема связана с тем, как вы передаете команду.

0 голосов
/ 02 сентября 2015

Я понимаю, что это старая ветка, но я хотел представить свои выводы, какими бы короткими они ни были.

Я столкнулся с той же проблемой совсем недавно с моим коллегой.Нам удалось отследить проблему до недостающих пространств выполнения.Нам также пришлось подключиться к пространству выполнения Microsoft.Exchange, и когда мы это сделаем, командлет Format-List станет недоступен.Если мы не используем пространство выполнения, командлет работает нормально.

Мы еще не дошли до его решения, но я собираюсь изучить возможность использования RunspacePool вместо Runspace., что позволяет выполнять оба командлета в конвейере.

0 голосов
/ 23 июля 2013

Вы можете попробовать работать с объектом Command.

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();

См. Также здесь: Вызов командлетов powershell из C #

...