如何将 -Verbose 传播到模块函数?
How to propagate -Verbose to module functions?
根据答案like this one和我自己的经验,Powershell 可以自动传播-Verbose(和-Debug),非常方便。然而,当我想要传播冗长的功能在一个模块中时,这将停止工作。用于测试的代码:
在某处创建一个名为Mod
的目录,假设在c:,并添加2个文件:
文件c:\Mod\Functions.ps1
:
function Show-VerbosityB { [cmdletbinding()]Param()
Write-Output "Show-VerbosityB called"
Write-Verbose "Show-VerbosityB is Verbose"
}
文件c:\Mod\Mod.psd1
:
@{
ModuleVersion = '1.0.0.0'
NestedModules = @('Functions.ps1')
FunctionsToExport = @('*-*')
}
现在创建主脚本,比如 c:\Foo.ps1
:
Import-Module c:\Mod
function Show-VerbosityA { [cmdletbinding()]Param()
Write-Output "Show-VerbosityA called"
Write-Verbose "Show-VerbosityA is Verbose"
}
function Show-Verbosity { [cmdletbinding()]Param()
Write-Output "Show-Verbosity called"
Write-Verbose "Show-Verbosity is Verbose"
Write-Output "Testing propagation"
Show-VerbosityA
Show-VerbosityB
}
Show-Verbosity -Verbose
结果
PS> . C:\Foo.ps1
Show-Verbosity called
VERBOSE: Show-Verbosity is Verbose
Testing propagation
Show-VerbosityA called
VERBOSE: Show-VerbosityA is Verbose
Show-VerbosityB called
为什么跳过了模块函数中的 Write-Verbose,为什么传播的行为不像 Show-VerbosityA 那样? (如果我只是 dot-source Functions.ps1 而不是导入模块,则会打印行 VERBOSE: Show-VerbosityB is Verbose
)。我可以通过例如制作传播手册打电话 Show-VerbosityB -Verbose:$PSBoundParameters['Verbose']
。或者还有其他更短的方法吗?如果函数的行为因它们是模块的一部分还是点源而有所不同,那将是相当混乱的。
发生这种情况的原因是因为调用模块时 $VerbosePreference
没有传播。
我修改了您的脚本以在您通过 Write-Verbose
和 Write-Output
.
输出的相同点显式打印值
This powershell.org post 建议将此添加到模块中,这对我来说就像一个魅力:
if (-not $PSBoundParameters.ContainsKey('Verbose'))
{
$VerbosePreference = $PSCmdlet.GetVariableValue('VerbosePreference')
}
其中一条评论提到错误报告 link(它不存在或我没有查看权限)
问题 discussed in a TechNet post, with a link to a Get-CallerPreferance
function 解决了这个问题。
模块:
function Show-VerbosityB { [cmdletbinding()]Param()
<# uncomment to get verbose preference from caller, when verbose switch not explicitly used.
if (-not $PSBoundParameters.ContainsKey('Verbose'))
{
$VerbosePreference = $PSCmdlet.GetVariableValue('VerbosePreference')
}
#>
Write-Output "`nShow-VerbosityB called"
Write-output "Global pref: $($global:VerbosePreference)"
Write-output "Script pref: $($script:VerbosePreference)"
Write-output "Effect pref: $VerbosePreference"
Write-Verbose "Show-VerbosityB is Verbose"
}
来电:
Import-Module C:\Mod
Write-output "On startup: $VerbosePreference"
function Show-VerbosityA { [cmdletbinding()]Param()
Write-Output "`nShow-VerbosityA called"
Write-output "Global pref: $($global:VerbosePreference)"
Write-output "Script pref: $($script:VerbosePreference)"
Write-output "Effect pref: $VerbosePreference"
Write-Verbose "Show-VerbosityA is Verbose"
}
function Show-Verbosity { [cmdletbinding()]Param()
Write-Output "`nShow-Verbosity called"
Write-output "Global pref: $($global:VerbosePreference)"
Write-output "Script pref: $($script:VerbosePreference)"
Write-output "Effect pref: $VerbosePreference"
Write-Verbose "Show-Verbosity is Verbose"
Write-Output "`nTesting propagation"
Show-VerbosityA
Show-VerbosityB
}
Show-Verbosity -Verbose
如果你想从调用者脚本中设置,试试这个:
(Get-Module 'ModuleName').SessionState.PSVariable.Set('Global:VerbosePreference', $VerbosePreference )
根据答案like this one和我自己的经验,Powershell 可以自动传播-Verbose(和-Debug),非常方便。然而,当我想要传播冗长的功能在一个模块中时,这将停止工作。用于测试的代码:
在某处创建一个名为Mod
的目录,假设在c:,并添加2个文件:
文件c:\Mod\Functions.ps1
:
function Show-VerbosityB { [cmdletbinding()]Param()
Write-Output "Show-VerbosityB called"
Write-Verbose "Show-VerbosityB is Verbose"
}
文件c:\Mod\Mod.psd1
:
@{
ModuleVersion = '1.0.0.0'
NestedModules = @('Functions.ps1')
FunctionsToExport = @('*-*')
}
现在创建主脚本,比如 c:\Foo.ps1
:
Import-Module c:\Mod
function Show-VerbosityA { [cmdletbinding()]Param()
Write-Output "Show-VerbosityA called"
Write-Verbose "Show-VerbosityA is Verbose"
}
function Show-Verbosity { [cmdletbinding()]Param()
Write-Output "Show-Verbosity called"
Write-Verbose "Show-Verbosity is Verbose"
Write-Output "Testing propagation"
Show-VerbosityA
Show-VerbosityB
}
Show-Verbosity -Verbose
结果
PS> . C:\Foo.ps1
Show-Verbosity called
VERBOSE: Show-Verbosity is Verbose
Testing propagation
Show-VerbosityA called
VERBOSE: Show-VerbosityA is Verbose
Show-VerbosityB called
为什么跳过了模块函数中的 Write-Verbose,为什么传播的行为不像 Show-VerbosityA 那样? (如果我只是 dot-source Functions.ps1 而不是导入模块,则会打印行 VERBOSE: Show-VerbosityB is Verbose
)。我可以通过例如制作传播手册打电话 Show-VerbosityB -Verbose:$PSBoundParameters['Verbose']
。或者还有其他更短的方法吗?如果函数的行为因它们是模块的一部分还是点源而有所不同,那将是相当混乱的。
发生这种情况的原因是因为调用模块时 $VerbosePreference
没有传播。
我修改了您的脚本以在您通过 Write-Verbose
和 Write-Output
.
This powershell.org post 建议将此添加到模块中,这对我来说就像一个魅力:
if (-not $PSBoundParameters.ContainsKey('Verbose'))
{
$VerbosePreference = $PSCmdlet.GetVariableValue('VerbosePreference')
}
其中一条评论提到错误报告 link(它不存在或我没有查看权限)
问题 discussed in a TechNet post, with a link to a Get-CallerPreferance
function 解决了这个问题。
模块:
function Show-VerbosityB { [cmdletbinding()]Param()
<# uncomment to get verbose preference from caller, when verbose switch not explicitly used.
if (-not $PSBoundParameters.ContainsKey('Verbose'))
{
$VerbosePreference = $PSCmdlet.GetVariableValue('VerbosePreference')
}
#>
Write-Output "`nShow-VerbosityB called"
Write-output "Global pref: $($global:VerbosePreference)"
Write-output "Script pref: $($script:VerbosePreference)"
Write-output "Effect pref: $VerbosePreference"
Write-Verbose "Show-VerbosityB is Verbose"
}
来电:
Import-Module C:\Mod
Write-output "On startup: $VerbosePreference"
function Show-VerbosityA { [cmdletbinding()]Param()
Write-Output "`nShow-VerbosityA called"
Write-output "Global pref: $($global:VerbosePreference)"
Write-output "Script pref: $($script:VerbosePreference)"
Write-output "Effect pref: $VerbosePreference"
Write-Verbose "Show-VerbosityA is Verbose"
}
function Show-Verbosity { [cmdletbinding()]Param()
Write-Output "`nShow-Verbosity called"
Write-output "Global pref: $($global:VerbosePreference)"
Write-output "Script pref: $($script:VerbosePreference)"
Write-output "Effect pref: $VerbosePreference"
Write-Verbose "Show-Verbosity is Verbose"
Write-Output "`nTesting propagation"
Show-VerbosityA
Show-VerbosityB
}
Show-Verbosity -Verbose
如果你想从调用者脚本中设置,试试这个:
(Get-Module 'ModuleName').SessionState.PSVariable.Set('Global:VerbosePreference', $VerbosePreference )