【问题标题】:Write-Information does not appear to work in powershell foreach-object -parallel写入信息似乎在 powershell foreach-object -parallel 中不起作用
【发布时间】:2021-02-02 18:55:49
【问题描述】:

我是 powershell 新手,刚刚学习它。我在 C# 方面有一些经验。我正在尝试使用 foreach-object -Parallel 选项,但无法让所有 Write-* 函数正常工作。

function writeTest {
        1..1 | ForEach-Object -Parallel {
            Write-Host "host"
            Write-Output "Output"
            Write-Information "information" -InformationAction Continue
            Write-Verbose "verbose"
            Write-Warning "Warning"
            Write-Error "error"       
        }
}

函数调用如下:writeTest -verbose

输出:

host
Output
WARNING: Warning
Write-Error: error

我的问题是为什么 write-verbose 和 write-information 不显示任何内容?

请原谅我的无知。

【问题讨论】:

  • 默认情况下不会显示这两个流。使用Get-Variable -Name *prefer* ... [grin] 之类的内容查看相应的偏好 $vars

标签: powershell parallel-processing output powershell-7.0 foreach-object


【解决方案1】:

您在ForEach-Object -Parallel / Start-ThreadJob 中看到一个错误,至少存在 PowerShell Core 7.0:

您的Write-Information 输出应该显示,因为您已使用-InformationAction Continue 将其打开;虽然您的Write-Verbose 输出未显示是意料之中的,因为您没有使用-Verbose 打开它,但由于该错误,如果您确实使用了-Verbose,它也不会显示。

GitHub issue #13816

解决方法设置偏好变量$InformationPreference,以便在调用ForEach-Object -Parallel之前打开信息流(见下文)。

另外,您的代码存在概念问题

  • 您正在将 -Verbose 通用参数传递给您的 write-Test 函数,但该函数并未声明为 高级 函数(这需要在 @987654341 之上的 [CmdletBinding()] 属性@block 和/或至少一个带有[Parameter(...)] 属性的参数 - 请参阅about_Functions_Advanced),因此该参数将无效。

  • 即使它确实生效了,这意味着 PowerShell 将其转换为具有值 'Continue' 的函数局部 $VerbosePreference 变量,ForEach-Object -Parallel 块也不会看到该变量,因为需要$using: 范围来引用调用者范围中的变量值;见this answer

把它们放在一起。

function Write-Test {

  # Mark the function as an advanced one, so that it accepts 
  # common parameters such as -Verbose
  [CmdletBinding()]
  param()
  
  # WORKAROUND: Turn the information stream on 
  #             via its *preference variable* AS WELL:
  $InformationPreference = 'Continue'
  
  1..1 | ForEach-Object -Parallel {
    Write-Host "host"
    Write-Output "Output"
    Write-Information "information" -InformationAction Continue               
    Write-Verbose "verbose" -Verbose:($using:VerbosePreference -eq 'Continue')
    Write-Warning "Warning"
    Write-Error "error"       
  }

}
  
Write-Test -Verbose

注意传递给-Verbose 开关的表达式,必须用: - -Verbose:($using:VerbosePreference -eq 'Continue') 与开关名称分开 - 实际上只有在$VerbosePreference 时才会打开详细输出函数主线程 ($using:) 中的值设置为 'Continue',这反过来又发生在 -Verbose 从外部传递给高级函数时(如果将 $VerbosePreference 设置为 'Continue' 也会发生这种情况由于 PowerShell 的动态范围,在 调用者的范围内;请参阅 this answer)。


有关 PowerShell 输出流的一般信息

  • Write-VerboseWrite-Information 默认情况下静音Write-Debug 也是如此。

  • 您可以通过以下两种方式之一显示它们的输出:

    • 每条命令,通过一个通用参数:将-Verbose 添加到Write-Verbose 调用和InformationAction ContinueWrite-Information 调用(正如你所做的那样)。

    • 范围范围内,通过首选项变量:设置$VerbosePreference = 'Continue'$InformationPreference = 'Continue' - 但警告 是(其他)中的两个函数模块在不同线程或进程中运行的代码默认会看到这些变量:

      • 在模块情况下,您必须显式使用公共参数或在全局范围内设置首选项变量,这是不可取的;该问题在GitHub issue #4568 中讨论。
      • 在其他线程/进程情况下,$using: 范围是必需的,如上所示。

请参阅about_Redirectionabout_CommonParametersabout_Preference_Variables

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-17
    • 2019-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多