Как выполнить сценарии в оболочке powershell, созданной с помощью кода, в которой есть команды Write-Host?
У меня есть сценарий, который я пишу, который опирается на функции в импортированном модуле. Этот сценарий занимает некоторое время из-за ввода-вывода (веб-запросов), и я хотел бы парализовать его для сотен тысяч итераций блока сценария.
После попытки нескольких различных методов (с небольшим успехом из-за ограничений с Start-Job
и другие вещи) текущая реализация опирается на предварительное создание пула "оболочек" powershell, созданных с помощью $shell = [Powershell]::Create()
,
Один из методов модуля, который мне нужно вызвать для начальной загрузки оболочки (так что она находится в правильном состоянии), имеет вызов Write-Host
в этом. Когда я звоню $shell.Invoke()
возникает следующая ошибка:
Write-Host: команда, которая запрашивает у пользователя ошибку, потому что хост-программа или тип команды не поддерживают взаимодействие с пользователем. Попробуйте хост-программу, которая поддерживает взаимодействие с пользователем, такую как Windows PowerShell Console или Windows PowerShell ISE, и удалите связанные с приглашением команды из типов команд, которые не поддерживают взаимодействие с пользователем, таких как рабочие процессы Windows PowerShell.
Теперь, поскольку модуль настроен, я могу удалить Write-Host
звонки, но это уменьшает удобство для пользователя, когда он запускается непосредственно конечными пользователями. Я могу создать switch
параметр, который не выполняет Write-Host, если параметр имеет значение true, но сделать это по ходу дела - хорошая работа (выполнимо, но я бы предпочел, чтобы этого не было).
Есть ли способ, которым я могу получить Write-Host
не ошибиться в этом сценарии? Я на самом деле не забочусь о входных данных в этом сценарии, я просто не хочу ошибок.
4 ответа
Самый быстрый способ заставить это работать - определить пустышку write-host
функция в вашем скрипте, или просто определить его в пространстве выполнения независимо перед запуском вашего скрипта.
$ps.addscript("function write-host {}").invoke()
$ps.commands.clear()
# now you can invoke scripts that use write-host
# feel free to implement a write-host that writes to a log file
Просто как тот. Причина, по которой вы получаете эту ошибку, заключается в том, что такой программный вызов не ожидает взаимодействия с пользователем. Есть способы заставить это работать, но это использует различные API.
Если вам нужен вывод, вы можете использовать:
$ps.addscript("function write-host($out) {write-output $out}").invoke()
$ps.commands.clear()
Если вы хотите продолжать использовать класс Pipeline, вы можете использоватьCommand.MergeMyResults
[метод][1]. Например, чтобы перенаправить потоки всех типов на вывод конвейера:
private string RunScript(string scriptText) {
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript("Write-Host Test");
pipeline.Commands[pipeline.Commands.Count-1]
.MergeMyResults(PipelineResultTypes.All, PipelineResultTypes.Output)
Collection < PSObject > results = pipeline.Invoke();
runspace.Close();
foreach(PSObject obj in results) {
Console.WriteLine(obj.ToString());
}
}
Попробуйте изменить версию WMF на 5.1 - https://www.microsoft.com/en-us/download/details.aspx?id=54616