简体   繁体   English

如何在创建的 powershell shell 中包含 Write-Host 命令的代码中执行脚本?

[英]How can I execute scripts in a code created powershell shell that has Write-Host commands in it?

I have a script that I am writing which relies on functions in an imported module.我正在编写一个脚本,它依赖于导入模块中的函数。 This script takes a while due to IO (web requests) and I would like to parallize it for hundreds of thousands of iterations of a script block.由于 IO(网络请求),这个脚本需要一段时间,我想将它并行化为脚本块的数十万次迭代。

After attempting several different methods (with little success due to restrictions with Start-Job and other things) the current implementation relies on pre-creating a pool of powershell "shells" created via $shell = [Powershell]::Create() .在尝试了几种不同的方法(由于Start-Job和其他事情的限制而收效甚微)之后,当前的实现依赖于预先创建一个通过$shell = [Powershell]::Create()的 powershell “shell”池。

One of the module methods I have to call to bootstrap the shell (so it's in a correct state) has a call to Write-Host in it.我必须调用其中一个模块方法来引导 shell(因此它处于正确状态)在其中调用了Write-Host When I call $shell.Invoke() the following error occurs:当我调用$shell.Invoke()时,会发生以下错误:

Write-Host: A command that prompts the user failed because the host program or the command type does not support user interaction. Write-Host:提示用户失败的命令,因为宿主程序或命令类型不支持用户交互。 Try a host program that supports user interaction, such as the Windows PowerShell Console or Windows PowerShell ISE, and remove prompt-related commands from command types that do not support user interaction, such as Windows PowerShell workflows. Try a host program that supports user interaction, such as the Windows PowerShell Console or Windows PowerShell ISE, and remove prompt-related commands from command types that do not support user interaction, such as Windows PowerShell workflows.

Now, since the module is custom I can remove the Write-Host calls, but that reduces user friendliness when it is run directly by end users.现在,由于模块是自定义的,我可以删除Write-Host调用,但这会降低最终用户直接运行时的用户友好性。 I can create a switch parameter that does not execute Write-Host if the parameter is true, but to do that down the line is a good bit of work (feasible, but I'd rather not).如果参数为真,我可以创建一个不执行 Write-Host 的switch参数,但要做到这一点是一项很好的工作(可行,但我宁愿不这样做)。

Is there any way I can get Write-Host to not error out in this scenario?有什么方法可以让Write-Host在这种情况下不出错? I don't actually care about the input in this scenario, I just don't want the errors.我实际上并不关心这种情况下的输入,我只是不想要错误。

The fastest way to get this to work is to define a dummy write-host function in your script, or to simply define it in the runspace independently before running your script.让它工作的最快方法是在脚本中定义一个虚拟的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

Simple as that.就那么简单。 The reason you're getting that error is because programmatic invocation like that does not expect user interaction.您收到该错误的原因是因为这样的程序调用不期望用户交互。 There are ways to make this work but it employs different APIs.有很多方法可以使这项工作发挥作用,但它使用不同的 API。

If you need the output, you can use:如果需要输出,可以使用:

$ps.addscript("function write-host($out) {write-output $out}").invoke()
$ps.commands.clear()

尝试将您的 WMF 版本更改为 5.1 - https://www.microsoft.com/en-us/download/details.aspx?id=54616

If you want to keep using the Pipeline class, you can use the Command.MergeMyResults [method][1].如果您想继续使用管道 class,您可以使用Command.MergeMyResults [方法][1]。 For example, to redirect all type of streams to pipeline output:例如,要将所有类型的流重定向到管道 output:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在包含Host.Ui.prompt命令的代码创建的Powershell外壳中执行脚本? - How can I execute scripts in a code created powershell shell that has Host.Ui.prompt commands in it? 如何在 Powershell DSC 中查看脚本资源的 Write-Host 输出? - How can I see the Write-Host output of a script resource in Powershell DSC? 如何更正PowerShell脚本/ WebAdministration foreach循环的Write-Host结果? - How can I correct the Write-Host results of my PowerShell script / WebAdministration foreach loops? PowerShell:如何捕获(或抑制)写主机 - PowerShell: how to capture (or suppress) write-host PowerShell写主机-NoNewLine - PowerShell Write-Host -NoNewLine Powershell Add_Click代码仅写主机工作 - Powershell Add_Click code only write-host working PowerShell 写主机背景颜色继续过去的代码 - PowerShell write-host background color continuing past the code 在“代码+测试”中运行Azure中的PowerShell时在日志中看不到write-host output - Can't see write-host output in the log when running PowerShell in Azure in "Code + Test" 在 PowerShell 中,您可以为外部命令写入调用和 arguments 吗? - In PowerShell can you Write-Host the invocation and arguments for an external command? PowerShell:如何在“ ROLLBACK TRANSACTION”之前将“ Write-Host”放置在SQL代码中 - PowerShell: How to place “Write-Host” inside SQL code before “ROLLBACK TRANSACTION”
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM