TL; DR -当函数/ cmdlet没有-WhatIf:$false
参数但仍然对-WhatIf
做出反应时,如何指定-WhatIf
家长打电话吗?
请考虑以下示例:
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$'
通过在 my 函数调用上指定-WhatIf
,它已在我的函数调用的函数上传递了该首选项。这是设计使然,在大多数情况下是您想要的。
出于完整性考虑,Test-ADServiceAccount
应该返回$true
或$false
,具体取决于是否已在本地计算机上安装了特定的托管服务(至少,如果您取消了对它的管理,则可以这样做)。警告/错误)。
但是,在这种情况下,由于似乎写了Test-ADServiceAccount
的方式,如果在 my 函数调用中提供了-WhatIf
,它实际上不会执行测试,因此始终返回$false
。这意味着我的if
/ else
逻辑被破坏了-我的函数应该 not 表示如果{{ 1}}已删除。
在通常情况下,我只会在被调用函数的末尾添加Install-ADServiceAccount
,但是registered$
不会公开其自己的-WhatIf
参数:
-WhatIf:$false
我很欣赏可能有更好的方法来编写该函数,并且这里实际上并没有造成任何危害,因为无论如何Test-ADServiceAccount
都没有运行,但是此函数旨在用作MCVE,而不是为了明确改进。我也很感激-WhatIf
可能不需要PS> Test-ADServiceAccount -WhatIf:$false -Identity 'registered$'
Test-ADServiceAccount : A parameter cannot be found that matches parameter name 'WhatIf'.
的语义,也许自己不应该自己做Install-ADServiceAccount
(我认为是这样做的),但是Test-ADServiceAccount
不是我的模块而且我看不到我会很快改变其行为。
在一般情况下,当 my <时,如何从我自己的函数中覆盖我无法控制的调用cmdlet /函数的-WhatIf
行为/ em>函数使用其$PSCmdlet.ShouldProcess
参数进行调用,而调用函数不会公开其自身的ActiveDirectory
参数。
答案 0 :(得分:1)
您可以在致电$WhatIfPreference
之前将$false
设置为Test-AdServiceAccount
。之后,您可以恢复首选项
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"
}
}
在此stackoverflow answer中找到了$WhatIfPreference.IsPresent
。
似乎Test-AdServiceAccount
以动态方式检测到WhatIf
开关,例如通过$WhatIfPreference = $PSCmdlet.SessionState.PSVariable.GetValue('WhatIfPreference')
更新:
基于@Jessens注释,您还可以将特定功能包装在脚本块中并调用invoke-command { $WhatIfPreference = $false; Function2;}
,在这里您无需重建旧的$WhatIfPreference
状态。
希望有帮助。