PowerShell 在运行 Import-Module 时忽略 Write-Verbose

Igo*_*gor 5 powershell module verbose

为了解决这个问题,我将这个简单的脚本保存为 PowerShell 模块 ( test.psm1)

Write-Verbose 'Verbose message'
Run Code Online (Sandbox Code Playgroud)

在现实生活中,它包括导入附加功能的命令,但目前无关紧要。

如果我跑,Import-Module .\test.psm1 -Verbose -Force我只会得到

VERBOSE: Loading module from path 'C:\tmp\test.psm1'.
Run Code Online (Sandbox Code Playgroud)

我的Write-Verbose被忽略

我尝试添加cmdletbinging但它也不起作用。

[cmdletbinding()]
param()

Write-Verbose 'Verbose message'
Run Code Online (Sandbox Code Playgroud)

任何线索如何在导入 PowerShell 模块时提供详细输出?

PS我不想总是显示详细信息,但只有在-Verbose指定时才显示。这是我对这两种不同情况的预期输出:

PS C:\> Import-Module .\test.psm1 -Verbose -Force # with verbose output
VERBOSE: Loading module from path 'C:\tmp\test.psm1'.
VERBOSE: Verbose message

PS C:\> Import-Module .\test.psm1 -Force # without verbose output

PS C:\>
Run Code Online (Sandbox Code Playgroud)

Mar*_*ara 5

这是一个有趣的情况。我有一个理论,但如果有人能证明我是错的,我会非常高兴。

简短的回答是:你可能无法-Verbose仅仅通过玩来做到你想做的事。可能有一些解决方法,但最短路径可以设置$VerbosePreference


首先,我们需要了解模块导入时的生命周期:

当导入模块时,会为该模块创建一个新的会话状态,并System.Management.Automation.PSModuleInfo在内存中创建一个对象。为每个导入的模块创建会话状态(这包括根模块和任何嵌套模块)。然后,将从根模块导出的成员(包括由任何嵌套模块导出到根模块的任何成员)导入到调用方的会话状态中。[..]要将输出发送到主机,用户应运行Write-Hostcmdlet。

最后一行是第一个提示,它向我指出了解决方案:导入模块时,会创建一个新的会话状态,但只有导出的元素会附加到全局会话状态。这意味着test.psm1代码在与您运行的会话不同的会话中执行Import-Module,因此-Verbose不会传播与该单个命令相关的选项。

相反,这是我的假设,因为我在文档中没有找到它,全局会话状态的配置对所有子会话都是可见的。为什么这很重要?因为有两种方法可以打开详细程度:

  • -Verbose选项,在这种情况下不起作用,因为它是命令的本地选项
  • $VerbosePreference,它使用首选项变量设置整个会话的详细程度。

我尝试了第二种方法,它起作用了,尽管不是那么优雅。

$VerbosePreference = "Continue" # print all the verbose messages, disabled by default
Import-Module .\test.psm1 -Force
$VerbosePreference = "SilentlyContinue" # restore default value
Run Code Online (Sandbox Code Playgroud)

现在一些注意事项:

  • -Verbose在命令上指定Import-Module是多余的

  • 您仍然可以通过使用来覆盖模块脚本中的详细配置

    Write-Verbose -Message "Verbose message" -Verbose:$false
    
    Run Code Online (Sandbox Code Playgroud)

    正如@Vesper 指出的,$false将始终抑制Write-Verbose输出。相反,您可能希望使用先前检查中分配的布尔变量来参数化该选项。就像是:

    if (...) 
    {
        $forceVerbose=$true
    } 
    else 
    { 
        $forceVerbose=$false
    }
    
    Write-Verbose -Message "Verbose message" -Verbose:$forceVerbose
    
    Run Code Online (Sandbox Code Playgroud)
  • 可能还有其他侵入性较小的解决方法(例如以Write-Host),甚至是真正的解决方案。正如我所说,这只是一个理论。