我有一个PowerShell模块,它封装了许多常用的业务功能。它通常不是从控制台调用的,而是由导入模块的自动部署和管理脚本调用的。
该模块包含一个日志记录功能,它可以写入两个集中的日志记录位置。我还想连接到写-详细功能,以便将其写入控制台。
#'Start Script.ps1
#'----------------
Import-Module Corporate
Write-Logger 'Foo'我的限制是--在企业PowerShell模块中--我需要确定是否用-Verbose参数调用了Script.ps1。理想情况下,我希望确定代码完全在模块本身内。
下面是一个例子:
[CmdletBinding()]
Param ()
New-Module -Name TempModule -ScriptBlock {
function Test-ModuleVerbose() {
[CmdletBinding()]
Param ()
PROCESS {
$vb = ($PSCmdlet.MyInvocation.BoundParameters['Verbose'] -eq $true)
Write-Host ("1: Module verbose preference: " + ($PSCmdlet.MyInvocation.BoundParameters['Verbose'] -eq $true))
Write-Host ("2: Module verbose preference: " + $Script:VerbosePreference)
Write-Host ("3: Module verbose preference: " + $VerbosePreference)
}
}
} | Out-Null
function Test-Verbose() {
[CmdletBinding()]
Param ()
PROCESS {
Write-Host ("Verbose preference: $VerbosePreference")
Test-ModuleVerbose
}
}
Test-Verbose将上述内容保存为test.ps1。从控制台调用时:
PS C:\temp> .\test.ps1
Verbose preference: SilentlyContinue
1: Module verbose preference: False
2: Module verbose preference:
3: Module verbose preference: SilentlyContinue
PS C:\temp> .\test.ps1 -Verbose
VERBOSE: Exporting function 'Test-ModuleVerbose'.
VERBOSE: Importing function 'Test-ModuleVerbose'.
Verbose preference: Continue
1: Module verbose preference: False
2: Module verbose preference:
3: Module verbose preference: SilentlyContinue如您所见,$VerbosePreference变量在模块中不可用。是否有一种从模块中获取调用脚本是否使用-Verbose标志的方法?
发布于 2014-01-06 23:37:30
有一个名为$VerbosePreference的变量,您可以检查如何处理详细的输出。但是,加载到单独范围中的脚本会给您带来问题。如果你读了Get-Help about_scopes,你会看到:
剧本: 脚本文件运行时创建的范围。只有脚本中的命令在脚本作用域中运行。对于脚本中的命令,脚本作用域就是本地作用域。
您可以使用点源表示法将脚本添加到当前范围。在相同的帮助文件中,在标题下使用带作用域的Dot符号说明如下:
脚本和函数遵循范围的所有规则。在特定范围中创建它们,它们只影响该作用域,除非使用cmdlet参数或作用域修饰符来更改该作用域。 但是,可以使用点源表示法将脚本或函数添加到当前作用域。然后,当脚本在当前作用域中运行时,脚本创建的任何函数、别名和变量都在当前作用域中可用。
我建议在Get-Help about_scopes帮助章节中阅读更多关于作用域的内容。
为了快速测试这是否有效:
[CmdletBinding()]
PARAM()
New-Module -Name TempModule -ScriptBlock {
function Show-ModuleVerbosePreference
{
[CmdletBinding()]
PARAM()
Write-Host "Verbose preference in module function: $VerbosePreference"
}
} | Out-Null
function Show-ScriptVerbosePreference
{
[CmdletBinding()]
PARAM()
Write-Host "Verbose preference in script function: $VerbosePreference"
}
Show-ScriptVerbosePreference
Show-ModuleVerbosePreference</pre>如果我们尝试使用不同的方法调用这个脚本文件,我们将得到以下输出:
PS C:\> .\verbosity.ps1
Verbose preference in script function: SilentlyContinue
Verbose preference in module function: SilentlyContinue
PS C:\> .\verbosity.ps1 -Verbose
VERBOSE: Exporting function 'Show-ModuleVerbosePreference'.
VERBOSE: Importing function 'Show-ModuleVerbosePreference'.
Verbose preference in script function: Continue
Verbose preference in module function: SilentlyContinue
PS C:\> . .\verbosity.ps1
Verbose preference in script function: SilentlyContinue
Verbose preference in module function: SilentlyContinue
PS C:\> . .\verbosity.ps1 -Verbose
VERBOSE: Exporting function 'Show-ModuleVerbosePreference'.
VERBOSE: Importing function 'Show-ModuleVerbosePreference'.
Verbose preference in script function: Continue
Verbose preference in module function: Continue因此,通过使用点源表示法,我们将脚本作用域添加到当前作用域中,这似乎使VerbosePreference设置在模块方法中也可见。
发布于 2017-04-22 09:49:25
可以使用匹配的首选项变量和类似于这样的语法-Parameter:$ParameterPreference来传递大多数公共参数。因此,对于详细的具体情况,语法是-Verbose:$VerbosePreference。
有几个例外:
$DebugPreference的值是自动传递的,但是指定-Debug开关会将$DebugPreference强制为Inquire。我对OP代码示例进行了如下修改:
[CmdletBinding(SupportsShouldProcess=$true)]
param(
[Switch]$FullPassThru
)
New-Module -Name TempModule -ScriptBlock {
function Test-ModuleVerbose
{
[CmdletBinding(SupportsShouldProcess=$true)]
param ()
Write-Host "1: Module: verbose parameter is bound : $($PSCmdlet.MyInvocation.BoundParameters['Verbose'])"
Write-Host "2: Module: verbose preference : $VerbosePreference"
# Write-Verbose will just work without any change
Write-Verbose "Verbose"
# Other commands need the $VerbosePreference passed in
Set-Item -Path Env:\DEMONSTRATE_PASS_THRU `
-Value 'You can safely delete this variable' `
-Verbose:$VerbosePreference
}
function Test-ModulePreferencePassThru
{
[CmdletBinding(SupportsShouldProcess=$true)]
param()
Write-Debug "DebugPreference: $DebugPreference"
Write-Warning "WarningPreference: $WarningPreference"
Write-Error "ErrorActionPreference: $ErrorActionPreference"
Set-Item -Path Env:\DEMONSTRATE_PASS_THRU `
-Value 'You can safely delete this variable' `
-Verbose:$VerbosePreference `
-WarningAction:$WarningPreference `
-ErrorAction:$ErrorActionPreference
}
} | Out-Null
function Test-Verbose
{
[CmdletBinding(SupportsShouldProcess=$true)]
param()
Write-Host ("Verbose preference: $VerbosePreference")
Test-ModuleVerbose -Verbose:$VerbosePreference
}
function Test-PreferencePassThru
{
[CmdletBinding(SupportsShouldProcess=$true)]
param()
Test-ModulePreferencePassThru -Verbose:$VerbosePreference
}
try
{
if ($FullPassThru -eq $false)
{
# just demonstrate -verbose pass-through
Test-Verbose
}
else
{
# most of the preferences can be explicitly passed-through, however:
#
# -Debug : $DebugPreference is automatically passed-through
# and -Debug forces $DebugPreference to 'Inquire'
# -WhatIf : automatically passed-through
Test-ModulePreferencePassThru -Verbose:$VerbosePreference `
-WarningAction:$WarningPreference `
-ErrorAction:$ErrorActionPreference | Out-Null
}
}
finally
{
# cleanup
Remove-Item -Path Env:\DEMONSTRATE_PASS_THRU -Force | Out-Null
}将上述内容保存为test.ps1。从控制台调用时:
PS C:\temp> .\test.ps1
Verbose preference: SilentlyContinue
1: Module: verbose parameter is bound : False
2: Module: verbose preference : SilentlyContinue
PS C:\temp> .\test.ps1 -Verbose
VERBOSE: Exporting function 'Test-ModuleVerbose'.
VERBOSE: Exporting function 'Test-ModulePreferencePassThru'.
VERBOSE: Importing function 'Test-ModulePreferencePassThru'.
VERBOSE: Importing function 'Test-ModuleVerbose'.
Verbose preference: Continue
1: Module: verbose parameter is bound : True
2: Module: verbose preference : Continue
VERBOSE: Verbose
VERBOSE: Performing the operation "Set Item" on target "Item: DEMONSTRATE_PASS_THRU Value: You can safely delete this variable".此外,$DebugPreference、$WarningPreference和$ErrorActionPreference的传递也是有效的:
PS C:\temp> $VerbosePreference = 'Continue'
PS C:\temp> $DebugPreference = 'Continue'
PS C:\temp> $WarningPreference = 'Continue'
PS C:\temp> $ErrorActionPreference = 'Continue'
PS C:\temp> .\test.ps1 -FullPassThru
VERBOSE: Exporting function 'Test-ModuleVerbose'.
VERBOSE: Exporting function 'Test-ModulePreferencePassThru'.
VERBOSE: Importing function 'Test-ModulePreferencePassThru'.
VERBOSE: Importing function 'Test-ModuleVerbose'.
DEBUG: DebugPreference: Continue
WARNING: WarningPreference: Continue
Test-ModulePreferencePassThru : ErrorActionPreference: Continue
At C:\OAASMain\Online\ContainerService\Tools\docker\test.ps1:72 char:9
+ Test-ModulePreferencePassThru -Verbose:$VerbosePreference `
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Test-ModulePreferencePassThru
VERBOSE: Performing the operation "Set Item" on target "Item: DEMONSTRATE_PASS_THRU Value: You can safely delete this variable".-WhatIf自动通过:
PS C:\temp> .\test.ps1 -FullPassThru -WhatIf
What if: Performing the operation "Remove Item" on target "Item: DEMONSTRATE_PASS_THRU".这也处理-WarningAction和-ErrorAction。
PS C:\temp> .\test.ps1 -FullPassThru -WarningAction Ignore -ErrorAction Stop
Test-ModulePreferencePassThru : ErrorActionPreference : Stop
At C:\OAASMain\Online\ContainerService\Tools\docker\test.ps1:72 char:9
+ Test-ModulePreferencePassThru -Verbose:$VerbosePreference `
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Test-ModulePreferencePassThru发布于 2017-04-13 17:36:39
在我的.psm1中,我放置了一个类似于以下内容的命令:
If ((Get-PSCallStack)[1].Arguments -like '\*Verbose=True\*') {
Write-Host 'The .ps1 script importing this module is Verbose'
};您可以使用脚本块来设置变量,例如模块作用域中的$VerbosePreference,或者为自己的逻辑设置自己的唯一变量。
https://stackoverflow.com/questions/20961063
复制相似问题