views:

75

answers:

1

General code

Consider this code:

PS> function Test { param($p='default value') $PsBoundParameters }
PS> Test 'some value'
Key                                                               Value
---                                                               -----
p                                                                 some value
PS> Test
# nothing

I would expect that $PsBoundParameters would contain record for $p variable on both cases. Is that correct behaviour?

Question

I'd like to use splatting that would work like this for a lot of functions:

function SomeFuncWithManyRequiredParams {
  param(
    [Parameter(Mandatory=$true)][string]$p1,
    [Parameter(Mandatory=$true)][string]$p2,
    [Parameter(Mandatory=$true)][string]$p3,
  ...other parameters
  )
  ...
}
function SimplifiedFuncWithDefaultValues {
  param(
    [Parameter(Mandatory=$false)][string]$p1='default for p1',
    [Parameter(Mandatory=$false)][string]$p2='default for p2',
    [Parameter(Mandatory=$false)][string]$p3='default for p3',
  ...other parameters
  )
  SomeFuncWithManyRequiredParams @PsBoundParameters
}

I don't want to call SomeFuncWithManyRequiredParams with all the params enumerated:

  SomeFuncWithManyRequiredParams -p1 $p1 -p2 $p2 -p3 $p3 ...

Is it possible?

+1  A: 

It depends on how you define "bound" I guess i.e. is the value bound from a user supplied value or a default value supplied by the function? Honestly, it doesn't surprise me that it behaves the way it does as I view "bound" to mean the former - bound from user input. Anyway, you can solve this by patching the $PSBoundParameters variable e.g.:

function SimplifiedFuncWithDefaultValues { 
  param( 
    [Parameter(Mandatory=$false)][string]$p1='default for p1', 
    [Parameter(Mandatory=$false)][string]$p2='default for p2', 
    [Parameter(Mandatory=$false)][string]$p3='default for p3', 
  ...other parameters 
  ) 
  if (!$PSBoundParameters.ContainsKey(p1))
  {
    $PSBoundParameters.p1 = 'default for p1'
  }
  # rinse and repeat for other default parameters.
  SomeFuncWithManyRequiredParams @PSBoundParameters 
} 
Keith Hill
Ok, I agree that `$PSBoundParameters` may contain only explicitly supplied arguments, depends on definition. Then there should be a way how to get *all parameters and values* as I have expected.
stej
Considering the solution you propose: your code is longer than `SomeFuncWithManyRequiredParams -p1 $p1 -p2 $p2 -p3 $p3`. And if all the params in function `SimplifiedFuncWithDefaultValues` have default values then there is no difference, I think.
stej
I don't see a way of getting the info you want via an automatic variable. Perhaps you might want to file a MS Connect suggestion.
Keith Hill
@Keith, thx for your answers. And voted up for your effort.
stej
FYI, I agree that modifying $PSBoundParameters is more work if every parameter has a default. I just wanted to point out that it is quite useful to add parameters to this hashtable (as well as remove them) before splatting the variable against the target command.
Keith Hill