Powershell: как получить -whatif для распространения на командлеты в другом модуле - PullRequest
7 голосов
/ 02 ноября 2011

Я пытался написать безопасный код, который поддерживает -whatif с методом ShouldProcess, чтобы мои пользователи имели представление о том, что должен делать командлет, прежде чем они запустят его по-настоящему.

Однако я наткнулся на небольшую загадку. Если я вызову скрипт с параметром -whatif в качестве аргумента, $ pscmdlet.ShouldProcess вернет false. Все хорошо. Если я вызову командлет, определенный в том же файле (с SupportsShouldProcess = $ true), он также вернет false.

Однако, если я вызываю командлет, определенный в другом модуле, который я загрузил с помощью Import-Module, он вернет true. Кажется, что контекст -whatif не передается вызовам в другом модуле.

Я не хочу вручную передавать флаг каждому командлету. У кого-нибудь есть лучшее решение?

Эта проблема, похоже, связана с вопросом . Однако они не говорят о проблеме кросс-модуля.

Пример сценария:

#whatiftest.ps1
[CmdletBinding(SupportsShouldProcess=$true)]
param()

Import-Module  -name .\whatiftest_module  -Force

function Outer
{
    [CmdletBinding(SupportsShouldProcess=$true)]
    param()
    if( $pscmdlet.ShouldProcess("Outer"))
    {
        Write-Host "Outer ShouldProcess"
    }
    else
    {
        Write-Host "Outer Should not Process"
    }

    Write-Host "Calling Inner"
    Inner
    Write-Host "Calling InnerModule"
    InnerModule
}

function Inner
{
    [CmdletBinding(SupportsShouldProcess=$true)]
    param()

    if( $pscmdlet.ShouldProcess("Inner"))
    {
        Write-Host "Inner ShouldProcess"
    }
    else
    {
        Write-Host "Inner Should not Process"
    }
}

    Write-Host "--Normal--"
    Outer

    Write-Host "--WhatIf--"
    Outer -WhatIf

Модуль:

#whatiftest_module.psm1
 function InnerModule
 {
    [CmdletBinding(SupportsShouldProcess=$true)]
    param()    

    if( $pscmdlet.ShouldProcess("InnerModule"))
    {
        Write-Host "InnerModule ShouldProcess"
    }
    else
    {
        Write-Host "InnerModule Should not Process"
    }
 }

Выход:

F:\temp> .\whatiftest.ps1
--Normal--
Outer ShouldProcess
Calling Inner
Inner ShouldProcess
Calling InnerModule
InnerModule ShouldProcess
--WhatIf--
What if: Performing operation "Outer" on Target "Outer".
Outer Should not Process
Calling Inner
What if: Performing operation "Inner" on Target "Inner".
Inner Should not Process
Calling InnerModule
InnerModule ShouldProcess

1 Ответ

6 голосов
/ 02 ноября 2011

Чтобы сделать это, вы можете использовать технику, которую я называю «CallStack peeking».Используйте Get-PSCallStack, чтобы посмотреть на то, что вызывается функцией.Каждый элемент будет иметь InvocationInfo, а внутри него будет свойство с именем «BoundParameters».Это имеет параметры @ каждого уровня.Если -What был передан любому из них, вы можете действовать как -WhatIf, который был передан вашей функции.

Надеюсь, это поможет

...