TL;DR - How do I specify -WhatIf:$false when a function/cmdlet does not have a -WhatIf parameter but still reacts to a -WhatIf in the parent call?
Consider the following slightly-contrived example:
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"
}
}
...and it's possible outputs:
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$'
If I add -WhatIf to those calls, you instead get the following:
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$'
By specifying -WhatIf on my function call, it has passed that preference on the functions called by my function. This is by design and, in most cases, what you would want.
For completeness, Test-ADServiceAccount is supposed to return $true or $false depending on whether a particular Managed Service has been installed to the local computer (at least, it does if you suppress its warnings/errors).
However, in this instance, due to the way Test-ADServiceAccount seems to have been written, if -WhatIf is supplied on my function call, it never actually performs the test, so always returns $false. This means that my if/else logic is broken -- my function should not indicate that Install-ADServiceAccount would be called for registered$ if -WhatIf was removed.
In normal circumstances, I would simply add -WhatIf:$false on to the end of the called function, but Test-ADServiceAccount does not expose its own -WhatIf parameter:
PS> Test-ADServiceAccount -WhatIf:$false -Identity 'registered$'
Test-ADServiceAccount : A parameter cannot be found that matches parameter name 'WhatIf'.
I appreciate that there are probably better ways to write the function, and that there is no harm really done here because Install-ADServiceAccount wasn't run anyway, but this function was intended as a MCVE, rather than something to be explicitly improved upon. I also appreciate that Test-ADServiceAccount may not need -WhatIf semantics and probably shouldn't itself do $PSCmdlet.ShouldProcess (which I assume it is doing), but ActiveDirectory isn't my module and I don't see me changing its behaviour any time soon.
In the general case, how could I override the -WhatIf behaviour for a called cmdlet/function I don't control, from within my own function, when my function is called with its -WhatIf parameter and the called function does not expose its own -WhatIf parameter.