Powershell:如何将 -whatif 传播到另一个模块中的 cmdlet

发布于 2024-12-13 11:15:25 字数 2117 浏览 4 评论 0原文

我一直在尝试使用 ShouldProcess 方法编写支持 -whatif 的安全代码,以便我的用户在真正运行 cmdlet 之前就知道它应该做什么。

然而我遇到了一些障碍。如果我使用 -whatif 作为参数调用脚本,$pscmdlet.ShouldProcess 将返回 false。一切都很好。如果我调用同一文件中定义的 cmdlet(具有 SupportsShouldProcess=$true),它也会返回 false。

但是,如果我调用在使用 Import-Module 加载的另一个模块中定义的 cmdlet,它将返回 true。 -whatif 上下文似乎没有传递到其他模块中的调用。

我不想手动将标志传递给每个 cmdlet。有人有更好的解决方案吗?

此问题似乎与此问题相关。然而,他们并不是在谈论跨模块问题。

示例脚本:

#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

I've been trying write safe code that supports -whatif with the ShouldProcess method so my users have an idea of what a cmdlet is supposed to do before they run it for real.

However I’ve run into a bit of a snag. If I call a script with -whatif as an argument, $pscmdlet.ShouldProcess will return false. All well and good. If I call a cmdlet defined in the same file (that has SupportsShouldProcess=$true) it will return false as well.

However, if I am calling a cmdlet defined in another module I have loaded using Import-Module, it will return true. The -whatif context does not seem to get passed through to calls in the other module.

I don't want to have to manually pass in a flag to every cmdlet. Does anyone have a better solution?

This issue seems related to this question. However, they are not talking about the cross-module problem.

Example Script:

#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

The Module:

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

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

Output:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

眼眸里的快感 2024-12-20 11:15:25

为此,您可以使用我称之为“CallStack peeking”的技术。使用 Get-PSCallStack 查找调用该函数的内容。每个项目都有一个 InvocableInfo,其内部是一个名为“BoundParameters”的属性。每个级别都有参数。如果 -WhatIf 被传递给它们中的任何一个,你可以像 -WhatIf 被传递给你的函数一样。

希望这有帮助

To do this, you can use a technique I call "CallStack peeking". Use Get-PSCallStack to look up at whatever called the function. Each item will have an InvocationInfo, and a inside of that will be a property called "BoundParameters". This has the parameters @ each level. If -WhatIf was passed to any of them, you can act like -WhatIf was passed to your function.

Hope this helps

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文