Powershell 禁止调用函数/cmdlet';s WhatIf输出,当该函数没有WhatIf参数时
TL;DR-当函数/cmdlet没有Powershell 禁止调用函数/cmdlet';s WhatIf输出,当该函数没有WhatIf参数时,powershell,Powershell,TL;DR-当函数/cmdlet没有-WhatIf参数但仍对父调用中的-WhatIf作出反应时,如何指定-WhatIf:$false 考虑以下稍微做作的例子: Import-Module ActiveDirectory Function Test-MyFunction { [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='High')] Param( [Parameter(Mandatory=$
-WhatIf
参数但仍对父调用中的-WhatIf
作出反应时,如何指定-WhatIf:$false
考虑以下稍微做作的例子:
Import-Module ActiveDirectory
Function Test-MyFunction {
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='High')]
Param(
[Parameter(Mandatory=$true)]
[String] $Identity
)
$private:q = ($Identity -replace "'","''")
if (Get-ADServiceAccount -Filter "sAMAccountName -eq '${private:q}'") {
if (-not (Test-ADServiceAccount -Identity $Identity `
-WarningAction 'SilentlyContinue' `
-ErrorAction 'SilentlyContinue'))
{
if ($PSCmdlet.ShouldProcess($Identity, 'Install')) {
Install-ADServiceAccount -Identity $Identity
}
else {
Write-Verbose "Skipped processing '$Identity'"
}
}
else {
Write-Verbose "Already registered '$Identity'"
}
}
else {
Write-Warning "'$Identity' does not exist"
}
}
…可能的输出:
PS> Test-MyFunction -Verbose -Identity 'nonexistent$'
WARNING: 'nonexistent$' does not exist
PS> Test-MyFunction -Verbose -Identity 'registered$'
VERBOSE: Already registered 'registered$'
PS> Test-MyFunction -Verbose -Identity 'notregistered$'
Confirm
Are you sure you want to perform this action?
Performing the operation "Install" on target "notregistered$"
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): n
VERBOSE: Skipped processing 'notregistered$'
如果我将-WhatIf
添加到这些调用中,您将得到以下结果:
PS> Test-MyFunction -WhatIf -Verbose -Identity 'nonexistent$'
WARNING: 'nonexistent$' does not exist
PS> Test-MyFunction -WhatIf -Verbose -Identity 'registered$'
What if: Performing the operation "Test" on target "CN=registered,CN=Managed Service Accounts,DC=contoso,DC=local"
What if: Performing the operation "Install" on target "registered$"
VERBOSE: Skipped processing 'registered$'
PS> Test-MyFunction -WhatIf -Verbose -Identity 'notregistered$'
What if: Performing the operation "Test" on target "CN=notregistered,CN=Managed Service Accounts,DC=contoso,DC=local"
What if: Performing the operation "Install" on target "notregistered$"
VERBOSE: Skipped processing 'notregistered$'
通过在我的函数调用中指定-WhatIf
,它已将该首选项传递给我的函数调用的函数。这是经过设计的,而且在大多数情况下,是您想要的
为完整起见,Test-ADServiceAccount
应返回$true
或$false
,具体取决于本地计算机上是否安装了特定的托管服务(如果您抑制其警告/错误,至少会返回)
但是,在本例中,由于测试ADServiceAccount
的编写方式,如果在我的函数调用中提供了-WhatIf
,则它从未实际执行测试,因此总是返回$false
。这意味着我的如果
/否则
逻辑被破坏——我的函数不应表明如果删除了-WhatIf
,将调用安装ADServiceAccount
以获得注册的$
在正常情况下,我只需将-WhatIf:$false
添加到被调用函数的末尾,但测试ADServiceAccount
不会公开其自身的-WhatIf
参数:
PS> Test-ADServiceAccount -WhatIf:$false -Identity 'registered$'
Test-ADServiceAccount : A parameter cannot be found that matches parameter name 'WhatIf'.
我理解可能有更好的方法来编写该函数,而且这里没有造成任何伤害,因为安装ADServiceAccount
无论如何都没有运行,但该函数是作为MCVE使用的,而不是需要显式改进的。我还了解到,测试ADServiceAccount
可能不需要-WhatIf
语义,而且它本身可能不应该做$PSCmdlet.ShouldProcess
(我假设它正在做),但是ActiveDirectory
不是我的模块,我看不到我很快会改变它的行为
在一般情况下,如何从我自己的函数中覆盖我不控制的被调用cmdlet/函数的
-WhatIf
行为,使用其-WhatIf
参数调用my函数时,被调用函数未公开其自己的-WhatIf
参数。在调用测试AdServiceAccount
之前,可以将$WhatIf首选项设置为$false
。之后,您可以恢复首选项
function Function1 {
[CmdletBinding(SupportsShouldProcess = $true)]
param (
)
$origWhatIfPreference = $WhatIfPreference.IsPresent
$WhatIfPreference = $false
Function2
$WhatIfPreference = $origWhatIfPreference
if ($PSCmdlet.ShouldProcess("target", "command")) {
Write-Host "test"
}
}
function Function2 {
[CmdletBinding(SupportsShouldProcess = $true)]
param (
)
if ($PSCmdlet.ShouldProcess("f2: target", "f2: command")) {
Write-Host "f2: test"
}
}
找到$WhatIfPreference。在此中显示
似乎Test-AdServiceAccount
以动态方式检测WhatIf
开关,例如通过$WhatIfPreference=$PSCmdlet.SessionState.PSVariable.GetValue('WhatIfPreference')
更新:
基于@Jessens注释,您还可以将特定函数包装在脚本块中,并调用它invoke命令{$WhatIfPreference=$false;Function2;}
,在这里您不必重新构建旧的$WhatIfPreference
状态
希望有帮助。很好。您甚至不需要取消设置它,更改将是函数1
@Moerwald/@MathiasR.Jessen范围的局部更改-$WhatIsPreference.IsPresent
与普通$WhatIsPreference
的区别是什么?i、 e..IsPresent
的值为什么推断真理,而不是$WhatIsPreference
的值。如果有人测试了MyCommand-WhatIf:$false
是否.IsPresent
为真?