title: Powershell scripting: recommended way to implement ShouldProcess when function calls are nested?
body: <p>Test script:</p>
  
  <pre><code>function outer
  {
      [cmdletbinding(supportsshouldprocess=$true)]
      param($s)
  
      process
      {        
          $pscmdlet.shouldprocess("outer $s", "ShouldProcess") | out-null
          "" | out-file "outer $s"
  
          inner ImplicitPassthru
          inner VerbosePassthru -Verbose:$Verbose 
          inner WhatifPassthru -WhatIf:$WhatIf
      }
  }
  
  function inner
  {
      [cmdletbinding(supportsshouldprocess=$true)]
      param($s)
  
      process
      {   
          $pscmdlet.shouldprocess("inner $s", "ShouldProcess") | out-null
          "" | out-file "inner $s"
      }
  }
  
  "`n** NORMAL **"
  outer normal
  "`n** VERBOSE **"
  outer verbose -Verbose
  "`n** WHATIF **"
  outer whatif -WhatIf
  </code></pre>
  
  <p>Output:</p>
  
  <pre><code>** NORMAL **
  VERBOSE: Performing operation "ShouldProcess" on Target "inner VerbosePassthru".
  What if: Performing operation "ShouldProcess" on Target "inner WhatifPassthru".
  What if: Performing operation "Output to File" on Target "inner WhatifPassthru".
  
  ** VERBOSE **
  VERBOSE: Performing operation "ShouldProcess" on Target "outer verbose".
  VERBOSE: Performing operation "ShouldProcess" on Target "inner VerbosePassthru".
  What if: Performing operation "ShouldProcess" on Target "inner WhatifPassthru".
  What if: Performing operation "Output to File" on Target "inner WhatifPassthru".
  
  ** WHATIF **
  What if: Performing operation "ShouldProcess" on Target "outer whatif".
  What if: Performing operation "Output to File" on Target "outer whatif".
  What if: Performing operation "ShouldProcess" on Target "inner ImplicitPassthru".
  What if: Performing operation "Output to File" on Target "inner ImplicitPassthru".
  What if: Performing operation "ShouldProcess" on Target "inner VerbosePassthru".
  What if: Performing operation "Output to File" on Target "inner VerbosePassthru".
  What if: Performing operation "ShouldProcess" on Target "inner WhatifPassthru".
  What if: Performing operation "Output to File" on Target "inner WhatifPassthru".
  </code></pre>
  
  <p>To my eye there are several oddities here:</p>
  
  <ul>
  <li>Specifying -WhatIf:$foo will <strong>always</strong> turn on $WhatIf in the callee (and its callees), no matter what $foo is.</li>
  <li>When you do specify -WhatIf "for real" (without constraining it to an existing variable), it propagates to callees implicitly.  No need for passthru or splatting.</li>
  <li>Unlike -WhatIf, explicit -Verbose does not cascade to callees implicitly.</li>
  <li>When you try to manually passthru -Verbose:$foo, you do see behavior is similar to -WhatIf:$foo. But it only affects scripts that manually test $psCmdlet.ShouldProcess() -- built in cmdlets aren't affected.</li>
  </ul>
  
  <p><strong><em>N.B.</strong>: Confirm behaves identical to WhatIf.  I omitted it for brevity.</em></p>
  
  <p>Searching the web and Connect, I see hardly any in-depth discussion of ShouldProcess behavior (pro or con) as pertains to advanced functions.  Closest thing is <a href="http://blogs.technet.com/jamesone/archive/2009/12/22/powershell-parameters-2-common-parameters.aspx" rel="noreferrer">a post from James O'Neill</a> that recommends passing a single instance of $psCmdlet throughout the call stack.  However, he does so to workaround an entirely different problem (avoiding multiple -Confirm prompts).  Meanwhile, when you stick with the standard $psCmdlet provided to each function, I see no docs on what to expect...much less design patterns, best practices, etc...</p>