Author Posts

May 15, 2013 at 12:33 pm

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]

}`

May 15, 2013 at 1:27 pm

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

May 16, 2013 at 4:56 am

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"

May 16, 2013 at 6:39 am

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.

May 16, 2013 at 6:58 am

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?

 

May 16, 2013 at 10:07 am

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.