TL; DR - Как указать -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$'
Указав -WhatIf
на my вызове функции, он передал это предпочтение функциям, вызываемым моей функцией.Это задуманно и, в большинстве случаев, вам нужно.
Для полноты Test-ADServiceAccount
должен возвращать $true
или $false
в зависимости от того, установлена ли конкретная управляемая служба налокальный компьютер (по крайней мере, это происходит, если вы подавляете его предупреждения / ошибки).
Однако, в этом случае, из-за способа, которым, как представляется, написано Test-ADServiceAccount
, если -WhatIf
указано на вызов функции , фактически он никогда не выполняет тест, поэтому всегда возвращает $false
.Это означает, что моя if
/ else
логика не работает - моя функция должна , а не указывать, что Install-ADServiceAccount
будет вызываться для registered$
, если -WhatIf
было удалено.
В обычных условиях я бы просто добавил -WhatIf:$false
в конец вызываемой функции, но Test-ADServiceAccount
не предоставляет свой собственный параметр -WhatIf
:
PS> Test-ADServiceAccount -WhatIf:$false -Identity 'registered$'
Test-ADServiceAccount : A parameter cannot be found that matches parameter name 'WhatIf'.
Я понимаю, что, вероятно, естьлучшие способы написания функции и то, что здесь действительно нет никакого вреда, потому что Install-ADServiceAccount
все равно не запускался, но эта функция была задумана как MCVE, а не как нечто, что было бы явно улучшено.Я также ценю, что Test-ADServiceAccount
может не потребоваться -WhatIf
семантика и, вероятно, сама не должна делать $PSCmdlet.ShouldProcess
(что я предполагаю, что это делает), но ActiveDirectory
не мой модуль, и я не вижу, как я меняюсьего поведение в ближайшее время.
В общем случае , как я могу переопределить поведение -WhatIf
для вызываемого командлета / функции, которой я не управляю, изнутри моей собственной функции,когда функция my вызывается с ее параметром -WhatIf
, а функция вызываемая не предоставляет свой собственный параметр -WhatIf
.