3

我是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 不显示任何内容?

请原谅任何无知。

4

1 回答 1

0

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

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

请参阅GitHub 问题 #13816

解决方法是在调用之前设置首选项变量 $InformationPreference以打开信息流ForEach-Object -Parallel(见下文)。

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

  • 您将-Verbose公共参数传递给您的write-Test函数,但此函数未声明为高级函数(它需要块[CmdletBinding()]上方的属性param(...)和/或至少一个具有[Parameter(...)]属性的参数 - 请参阅about_Functions_Advanced),因此该参数将具有没有效果。

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

把它们放在一起。

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分开来自外部的函数(由于 PowerShell 的动态作用域,如果设置为调用者的范围内也会发生这种情况;请参阅此答案)。:-Verbose:($using:VerbosePreference -eq 'Continue')$VerbosePreference$using:'Continue'-Verbose$VerbosePreference'Continue'


有关 PowerShell 输出流的一般信息

  • Write-Verbose默认情况下,两者Write-Information都是静默Write-Debug

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

    • 每个命令,通过一个通用参数:添加-VerboseWrite-Verbose呼叫和InformationAction Continue呼叫Write-Information(就像您所做的那样)。

    • 在范围范围内,通过首选项变量:设置$VerbosePreference = 'Continue'$InformationPreference = 'Continue'- 但需要注意的是,默认情况下,存在于(其他)模块中的函数和运行在不同线程或进程中的代码都不会看到这些变量:

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

请参阅about_Redirectionabout_CommonParametersabout_Preference_Variables

于 2020-10-20T03:11:21.490 回答