Pass -whatif to called cmdlet?

This topic contains 5 replies, has 2 voices, and was last updated by  Jeffrey Smith 4 years, 3 months ago.

  • Author
    Posts
  • #4867

    gbritton
    Participant

    I have a script that takes the -whatif switch.  I'm looking for a neat way to pass the switch to other cmdlets that I call.

    e.g.

    `function foo {

    param ([switch]$whatif)

    bar [some way to pass the -whatif switch if given in the call to foo]

    }`

  • #4887

    Jeffrey Smith
    Participant

    What you really want to do is create an advanced function with the [CmdletBinding()] attribute; then you can put "SupportsShouldProcess=$true" (or just SupportsShouldProcess in V3) inside the parenthesis and you'll automatically get a -WhatIf Parameter built in.

     

    This tip from the Scripting Guy shows you in detail:

    http://blogs.technet.com/b/heyscriptingguy/archive/2012/07/23/3507237.aspx

  • #4926

    gbritton
    Participant

    Well, that's interesting but still doesn't answer my question.  Consider this example (for some reason, code formatting doesn't work for me...a real drag!):

     

    function foo {
    [cmdletbinding(SupportsShouldProcess=$True)]
    param()

    if ($PSBoundParameters.ContainsKey('whatif')) {'whatif'} else {'not whatif'}
    bar
    }

    function bar {
    [cmdletbinding(SupportsShouldProcess=$True)]
    param()

    if ($PSBoundParameters.ContainsKey('whatif')) {'whatif'} else {'not whatif'}
    }

    foo -whatif

    When I run this, I get this result:

    whatif

    not whatif

    I still need a way to call "bar" with "-whatif" if and only if "foo" is also called with "-whatif"

  • #4937

    Jeffrey Smith
    Participant

    Okay, just using SupportsShouldProcess works with native Cmdlets, but if you want to pass the preference along to your own subfunctions, you have to do it a bit more explicitly. This should do what you're looking for:

    function foo {
        [cmdletbinding(SupportsShouldProcess=$True)]
        param()
    
        if ($Pscmdlet.ShouldProcess('a')) {
            ‘ foo not whatif’
        } else {
            ‘ foo whatif’
        }
        bar -WhatIf:$PSBoundParameters.ContainsKey('WhatIf')   
    }
    
    function bar {
        [cmdletbinding(SupportsShouldProcess=$True)]
        param()
    
        if ($PSCmdlet.ShouldProcess('a')) {
            ‘ bar not whatif’
        } else {
            ‘ bar whatif’
        }
    }

    There's some good discussion on this in this Stack Overflow question:

    http://stackoverflow.com/questions/7180271/how-do-you-support-powershells-whatif-confirm-parameters-in-a-cmdlet-that-c

    I don't know if there's an agreement on the 'best practice' approach for this, but the code I put above makes the most sense to me.

    Alternatively, if you just put your second function inside the "If ($PSCmdlet.ShouldProcess()) {}" scriptblock, it will only even call the second function (ie. 'bar') if WhatIf is NOT passed.

  • #4938

    gbritton
    Participant

    Aha!  Now that does it.  In fact I found that this seems to be sufficient:

     

    bar -WhatIf:$WhatIfPreference

    Is there a circumstance where this would not work reliably?

     

  • #4961

    Jeffrey Smith
    Participant

    I'm pretty sure as long as you don't set $WhatIfPreference to $false yourself, that should work fine.

    I'd honestly forgotten about that automatic variable.

You must be logged in to reply to this topic.