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

标签 powershell module verbose

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

Write-Verbose 'Verbose message'
在现实生活中,它包括导入附加功能的命令,但目前无关紧要。
如果我运行 Import-Module .\test.psm1 -Verbose -Force我只得到
VERBOSE: Loading module from path 'C:\tmp\test.psm1'.
我的 Write-Verbose被忽略😟
我尝试添加 cmdletbinging但它也没有用。
[cmdletbinding()]
param()

Write-Verbose 'Verbose message'
任何线索如何在导入 PowerShell 模块时提供详细输出?
附言我不想总是显示详细信息,但前提是 -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:\>

最佳答案

这是一个有趣的情况。我有一个理论,但如果有人能证明我错了,我会非常高兴。
简短的回答:你可能无法通过玩 -Verbose 来做你想做的事。只要。可能有一些解决方法,但最短路径可能是设置 $VerbosePreference .

首先我们要了解lifetime of a module导入时:

When a module is imported, a new session state is created for the module, and a System.Management.Automation.PSModuleInfo object is created in memory. A session-state is created for each module that is imported (this includes the root module and any nested modules). The members that are exported from the root module, including any members that were exported to the root module by any nested modules, are then imported into the caller's session state. [..] To send output to the host, users should run the Write-Host cmdlet.


最后一行是向我指出解决方案的第一个提示:导入模块时,新的 session state已创建,但只有导出的元素附加到全局 session 状态。这意味着 test.psm1代码在与运行 Import-Module 的 session 不同的 session 中执行,因此 -Verbose与该单个命令相关的选项不会传播。
相反,这是我的一个假设,因为我没有在文档中找到它,所以来自全局 session 状态的配置对所有子 session 都是可见的。为什么这很重要?因为有两种方法可以开启冗长:
  • -Verbose选项,在这种情况下不起作用,因为它是命令
  • 的本地选项
  • $VerbosePreference ,它使用首选项变量设置整个 session 的详细程度。

  • 我尝试了第二种方法并且它有效,尽管不是那么优雅。
    $VerbosePreference = "Continue" # print all the verbose messages, disabled by default
    Import-Module .\test.psm1 -Force
    $VerbosePreference = "SilentlyContinue" # restore default value
    
    现在有一些考虑:
  • 指定 -VerboseImport-Module命令是多余的
  • 您仍然可以通过使用覆盖模块脚本中的详细配置
    Write-Verbose -Message "Verbose message" -Verbose:$false
    
    正如@Vesper 指出的那样,$false将始终抑制 Write-Verbose输出。相反,您可能希望使用在先前检查中分配的 bool 变量来参数化该选项。就像是:
    if (...) 
    {
        $forceVerbose=$true
    } 
    else 
    { 
        $forceVerbose=$false
    }
    
    Write-Verbose -Message "Verbose message" -Verbose:$forceVerbose
    
  • 可能还有其他侵入性较小的解决方法(例如以 Write-Host 为中心),甚至是真正的解决方案。正如我所说,这只是一个理论。
  • 关于PowerShell 在运行 Import-Module 时忽略 Write-Verbose,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66368375/

    相关文章:

    azure - 找出在 ADF v1 中部署 Azure 数据工厂管道的用户

    powershell - 调用运算符 (&) 的语法问题

    java - 在java中打开/关闭println的任何方法(详细模式)

    powershell - 我可以在 PowerShell 的基于评论的帮助中隐藏某些评论吗?

    arrays - 一旦达到客户端选择的数字,Powershell 循环就会为变量分配一个值

    python - python 模块可以有 __repr__ 吗?

    javascript - 为什么 TypeScript 混合使用模块和原型(prototype)模式?

    perl - 当我使用模块时如何找到 Perl 加载的文件?

    mysql - 防止从 mysqldump 中取消详细输出

    java - 调试 Java 8 过滤器