【问题标题】:How do I exclude a block from -WhatIf processing?如何从 -WhatIf 处理中排除一个块?
【发布时间】:2016-04-15 05:18:04
【问题描述】:

我正在编写一个 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

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

如果:对目标“temp\path\to\tmp78A4.tmp”执行“输出到文件”操作

因为这个命令永远不会执行,内部处理也不会发生,并且我的 cmdlet 的其余部分具有实际副作用也不会执行,因为它不知道要使用哪些端口,这使得-WhatIf 在很大程度上没用。

我怎样才能绕过 -WhatIf 这个块而不在 cmdlet 的其余部分覆盖它?

【问题讨论】:

  • 我很好奇是否在$info = [IO.Path]::GetTempFileName()info-gather.exe 2>$info 之间(你要睡觉或暂停片刻)如果临时文件实际存在同时也发送了-WhatIf 开关。
  • @gravity,我不确定我是否理解您的评论。 GetTempFileName() 创建一个文件并返回其名称,因此当2>$info 发生时,保证该文件存在(但保证GetTempFileName 不会返回另一个已经存在的文件的名称)。
  • 此 cmdlet 是否有 [CmdletBinding(SupportsShouldProcess=$true)]?这个设置如何支持-WhatIf
  • @Matt,是的,这个 cmdlet 有 SupportsShouldProcess=$true。稍后在 cmdlet 中(在“具有严重副作用的严重事情”之后),我使用 $PSCmdlet.ShouldProcess

标签: powershell


【解决方案1】:

您可以使用try...finally 设置然后重置$WhatIfPreference variable

$script:oldWhatIfPrefernence = $WhatIfPreference
try {
    $WhatIfPreference = $false

    $info = [IO.Path]::GetTempFileName()
    info-gather.exe 2>$info
    Get-Content $info | ForEach-Object {
        # processing
    }
    Remove-Item $info
} finally {
    $WhatIfPreference = $script:oldWhatIfPreference
}

如果您没有使用2> 重定向,还有另一种方法。您可以将 -WhatIf 开关显式传递给许多 cmdlet,并仅针对该部分覆盖 -WhatIf

Remove-Item $info -WhatIf:$false

不过,不涉及临时文件的zneak's answer 也很优雅。

【讨论】:

  • 它可能需要在 try 块中的某个位置替换 $WhatIfPreference,不是吗?
  • 多哈。固定的。谢谢,@zneak。
【解决方案2】:

一种解决方案是将标准错误“重定向”到标准输出。为此,Powershell 将错误记录附加到标准输出,可以使用Out-String 将其转换为常规字符串。在我的情况下(YMMV 取决于程序),第一个错误记录说“这个程序有一个错误”,第二个错误记录是实际的完整 stderr 输出。这也简化了,因为该命令不向标准输出写入任何内容,因此无需进行过滤。

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

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

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

可能有一种更简单、更简洁的方法来执行此操作(例如,如果有一种方法可以将 stderr 直接通过管道传输到 Out-String)。

【讨论】:

    猜你喜欢
    • 2011-12-20
    • 1970-01-01
    • 2021-07-30
    • 1970-01-01
    • 2015-11-26
    • 2020-04-23
    • 2019-07-03
    • 2018-10-29
    • 1970-01-01
    相关资源
    最近更新 更多