【问题标题】:Write synchronously to the command line inside a foreach with a pipelined command使用流水线命令同步写入 foreach 内的命令行
【发布时间】:2019-07-01 15:44:58
【问题描述】:

我有以下代码:

Get-ResourcePool -Server 1.1.1.1 | Where-Object {$_.Name -like 'XX*'} | foreach {
    Write-Host $_.Name -ForegroundColor Red
    Get-ResourcePool -Name $_.Name | Get-VM
}

由于管道的原因,它是异步执行的 - 所以所有的 Write-Host 输出都会出现在控制台上,只有在那之后我才能从 Get-ResourcePool 获得结果。

问题:如何使其同步 - 如何在执行下一个 foreach 循环之前等待管道完成。

附:我能够确定问题出在管道上,因为当我移除 for each 内部的管道时,我得到了我期望的结果。

P.P.S 我尝试了Start-Job -ScriptBlock { Get-ResourcePool -Name $Input | Get-VM } -InputObject "$_.Name",然后等待作业完成 - 但这不起作用,因为在此命令运行时我需要连接到 vCenter,所以我得到:

7/1/2019 6:37:49 PM Get-ResourcePool        You are not currently connected to any servers. Please connect first using a Connect cmdlet.    
    + CategoryInfo          : ResourceUnavailable: (:) [Get-ResourcePool], ViServerConnectionException
    + FullyQualifiedErrorId : Core_BaseCmdlet_NotConnectedError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetResourcePool
    + PSComputerName        : localhost

附录: 添加带有一些建议的屏幕截图 - 不幸的是,它们都不起作用:

reddit 的建议也不起作用:https://www.reddit.com/r/PowerShell/comments/8hvjyn/output_delay/

在结尾添加暂停:

在末尾添加 pause 和 Out-Host:

【问题讨论】:

  • 您看到的是在 psv3 中添加的 output stream to host delay。 [sigh ...] 每当您将直接和间接输出混合到屏幕上时,间接输出都会延迟 [约 300 毫秒],以允许 PoSh 对“相似”的事物进行分组。通常的解决方法是 [A] 不要这样做 [混合直接主机输出和间接输出流输出] ...或 ... [B] 使用-Host cmdlet 之一强制直接输出。 ///// 我怀疑您可以将Out-Host 添加到要添加到即时主机显示的任何行中。
  • 写输出而不是写主机?写主机 6>&1?
  • 我不确定我是否听懂了你所说的。如果我复制您的代码,减去服务器参数,我看不到相同的输出。示例:``` PS /Users/kruddy> Get-ResourcePool | Where-Object {$_.Name -notlike 'Resources'} | foreach { >> 写入主机 $_.Name -ForegroundColor Red >> Get-ResourcePool -Name $_.Name | Get-VM >> } Development Name PowerState Num CPUs MemoryGB ---- ---------- -------- -------- aaaaaa PoweredOff 4 7.859 Management zzzzzzz PoweredOn 4 16.000 ```
  • 今天将尝试Out-Host 后者并让您知道!
  • @MindaugasBernatavičius - 现在,尝试在| Get-VM 之后添加| Out-Host,看看是输出流延迟还是其他什么... [grin]跨度>

标签: powershell powercli


【解决方案1】:

如何在执行下一个 foreach 循环之前等待管道完成。

您可以使用Out-Default 强制同步输出到主机应用程序:

Get-ResourcePool -Server 1.1.1.1 | Where-Object {$_.Name -like 'XX*'} | ForEach-Object {
    Write-Host $_.Name -ForegroundColor Red
    Get-ResourcePool -Name $_.Name | Get-VM | Out-Default
}

【讨论】:

  • 对不起,但它的工作原理是一样的——首先打印所有的名字,然后是他们的信息:pastebin.com/raw/gSgAmbrM
【解决方案2】:

解决了这个问题:这是我个人的错误。我正在使用资源池进行测试,其中唯一具有任何 VM 的资源池是最后一个。在我将其更改为包含多个 VM 的资源池并对其进行测试后,我能够看到它运行良好。

【讨论】:

    猜你喜欢
    • 2019-01-22
    • 1970-01-01
    • 2014-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-20
    • 2021-10-26
    • 1970-01-01
    相关资源
    最近更新 更多