Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Powershell 禁止调用函数/cmdlet';s WhatIf输出,当该函数没有WhatIf参数时_Powershell - Fatal编程技术网

Powershell 禁止调用函数/cmdlet';s WhatIf输出,当该函数没有WhatIf参数时

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=$

TL;DR-当函数/cmdlet没有
-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
为真?