Командлет PowerShell вызывается, но не отвечает

Invoke-MyFunction — это написанный мной командлет, который берет входной файл, изменяет его и создает новый выходной файл в указанном месте. Если я открою PowerShell на своем рабочем столе, импортирую MyCommandlet.ps1 и запущу

Invoke-MyFunction -InputPath path\to\input -OutputPath path\to\output

все работает как положено. Но когда я пытаюсь импортировать и вызывать команду из программы C# с помощью приведенного ниже кода, командлет не запускается, не записывает выходные данные и не создает выходной файл. Он не генерирует исключение CommandNotFoundException, поэтому я предполагаю, что объект PowerShell распознает мой командлет. Но я не могу понять, почему он не выполняет его.

    //set up the PowerShell object
    InitialSessionState initial = InitialSessionState.CreateDefault();
    initial.ImportPSModule(new string[] { @"C:\path\to\MyCommandlet.ps1" });
    Runspace runspace = RunspaceFactory.CreateRunspace(initial);
    runspace.Open();
    PowerShell ps = PowerShell.Create();
    ps.Runspace = runspace;

    //have MyFunction take input and create output
    ps.AddCommand("Invoke-MyFunction");
    ps.AddParameter("OutputPath", @"C:\path\to\output");
    ps.AddParameter("InputPath", @"C:\path\to\input");
    Collection<PSObject> output = ps.Invoke();

Кроме того, после вызова MyFunction объект ps PowerShell не может выполнить никакие другие команды. Даже известные.


person dmeyerson    schedule 10.07.2014    source источник
comment
Я пробовал вызывать Copy-Item вместо Invoke-MyFunction, и это работает. Итак, я предположил, что проблема связана с Invoke-MyFunction.   -  person dmeyerson    schedule 11.07.2014


Ответы (1)


Это работает для меня:

//set up the PowerShell object
var initial = InitialSessionState.CreateDefault();
initial.ImportPSModule(new string[] { @"C:\Users\Keith\MyModule.ps1" });
Runspace runspace = RunspaceFactory.CreateRunspace(initial);
runspace.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = runspace;

//have MyFunction take input and create output
ps.AddCommand("Invoke-MyFunction");
ps.AddParameter("OutputPath", @"C:\path\to\output");
ps.AddParameter("InputPath", @"C:\path\to\input");
var output = ps.Invoke();
foreach (var item in output)
{
    Console.WriteLine(item);
}

С MyModule.ps1 из:

function Invoke-MyFunction($InputPath, $OutputPath) {
   "InputPath is '$InputPath', OutputPath is '$OutputPath'"
}

Одна вещь, которая вызвала у меня сбой, заключается в том, что в Visual Studio 2013 (возможно, и в 2012 году) приложения AnyCPU фактически будут работать 32-разрядными в 64-разрядной ОС. Вы должны установить политику выполнения для PowerShell x86, чтобы разрешить выполнение скрипта. Попробуйте открыть оболочку PowerShell x86 в режиме администратора и запустить Get-ExecutionPolicy. Если установлено значение Restricted, используйте Set-ExecutionPolicy RemoteSigned, чтобы разрешить выполнение сценариев.

person Keith Hill    schedule 11.07.2014
comment
Проблема для меня, как оказалось, заключалась в ошибке в MyCommandlet.ps1, а не в моем коде C#. Чего я не заметил, так это того, что Invoke-MyFunction работает только при вызове из определенного каталога (поскольку некоторые файлы, от которых он зависит, находятся в этом каталоге). При вызове из С# рабочий каталог был неправильным, и поэтому он не работал. Решением стало изменение командлета, чтобы его можно было вызывать из любого места. - person dmeyerson; 23.07.2014
comment
Рад слышать, что ты разобрался. - person Keith Hill; 23.07.2014