Pass -whatif to called cmdlet?

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

  • Author
    Posts
  • #4867
    Profile photo of gbritton
    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
    Profile photo of Jeffrey Smith
    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
    Profile photo of gbritton
    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
    Profile photo of Jeffrey Smith
    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
    Profile photo of gbritton
    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
    Profile photo of Jeffrey Smith
    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.