如何从-Wha​​tIf处理中排除块?

zne*_*eak 6 powershell

我正在编写一个Powershell cmdlet,它需要执行命令并将其stderr输出存储到临时文件中以供以后处理.此输出列出了cmdlet稍后可能使用的COM端口.

# mostly side-effect-free information gathering
$info = [IO.Path]::GetTempFileName()
info-gather.exe 2>$info
Get-Content $info | ForEach-Object {
    # processing
}
Remove-Item $info

# serious things with serious side effects start here
Run Code Online (Sandbox Code Playgroud)

我希望这个cmdlet能够实现,-WhatIf因为它会产生非平凡的副作用.但是,该-WhatIf行为将接管info-gather.exe命令,并且它永远不会被执行.相反,它打印:

如果:在目标"temp\path\to\tmp78A4.tmp"上执行"输出到文件"操作

因为永远不会执行此命令,所以内部处理也不会发生,并且我的cmdlet的其余部分都没有执行,因为它不知道要使用哪些端口,这-WhatIf在很大程度上是无用的.

如何绕过-WhatIf此块而不覆盖cmdlet的其余部分?

zne*_*eak 1

一种解决方案是将 stderr“重定向”到 stdout。这样做时,Powershell 将错误记录附加到标准输出,可以使用Out-String. 就我而言(YMMV 取决于程序),第一个错误记录显示“此程序出现错误”,第二个错误记录是实际的完整 stderr 输出。该命令不会向标准输出写入任何内容,因此无需进行任何过滤,这一事实也简化了这一点。

我能够更改 foreach 循环以使用它:

((info-gather.exe 2>&1)[1] | Out-String) -split "[`r`n]" | foreach-object
Run Code Online (Sandbox Code Playgroud)

由于这不会写入文件,因此-WhatIf不再覆盖它。

可能有一种更简单、更干净的方法来做到这一点(例如,如果有一种方法可以Out-String直接通过管道传输 stderr)。