0

I am trying to call a PowerShell function that has a parameter set, using another PowerShell function with a parameter set. In the code below, I want to call Entry-Point using either the -ABC or -DEF switch, not both. However, when I run Entry-Point with any number of parameters, I get the AmbiguousParameterSet exception below.

function My-Function {
    [CmdletBinding(DefaultParameterSetName='ABC')]
    Param(
        [Parameter(Mandatory=$false, ParameterSetName='ABC', Position=1)]
        [switch] $ABC,

        [Parameter(Mandatory=$false, ParameterSetName='DEF', Position=1)]
        [switch] $DEF,

        [switch] $Extra
    )

    echo $ABC
    echo $DEF
    echo $Extra
}


function Entry-Point {
    [CmdletBinding(DefaultParameterSetName='ABC')]
    Param(
        [Parameter(Mandatory=$false, ParameterSetName='ABC', Position=1)]
        [switch] $ABC,

        [Parameter(Mandatory=$false, ParameterSetName='DEF', Position=1)]
        [switch] $DEF,

        [switch] $Extra
    )

    My-Function -ABC:$ABC -DEF:$DEF -Extra:$Extra
}
My-Function : Parameter set cannot be resolved using the specified named
parameters.
At line:24 char:1
+ My-Function -ABC:$ABC -DEF:$DEF -Extra:$Extra
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [My-Function], ParameterBindingException
    + FullyQualifiedErrorId : AmbiguousParameterSet,My-Function

How can I pass the parameters -ABC and -DEF -- whether each was specified or not -- from function Entry-Point to function My-Function?

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
BlueTriangles
  • 1,124
  • 2
  • 13
  • 26

1 Answers1

1

The quick answer is splatting. PowerShell lets you present a hashtable as the parameters to a function (using @ instead of $), and uses the keys of the hashtable as parameter names, the values are the parameter values.

Also, each advanced function automatically sets $PSBoundParameters as a hashtable of the parameters that are passed in.

So...you can just say: My-Function @PSBoundParameters

Mike Shepard
  • 17,466
  • 6
  • 51
  • 69
  • Thanks Mike. Is splatting best practice? – BlueTriangles Jun 04 '19 at 03:10
  • It's a choice / a style preference / readability thing, etc. There are no definitive Best Practices from say Microsoft for PowerShell. However, there are several guides to encourage folks to approach it. Overtime these have come about --- https://www.microsoftpressstore.com/store/windows-powershell-best-practices-9780735666498 --- https://gallery.technet.microsoft.com/scriptcenter/PowerShell-40-Best-d9e16039 --- https://github.com/PoshCode/PowerShellPracticeAndStyle --- https://redmondmag.com/articles/2014/03/18/powershell-best-practices-analyzer.aspx. None cover it all. – postanote Jun 04 '19 at 04:17
  • As @postanote says, there's no official list of best practices. On the other hand, splatting has a lot of very helpful uses and is often recommended. The main downside (from my perspective) is that you don't get any intellisense/tab-completion in the hashtable because it isn't actually connected with the command you're using it with. – Mike Shepard Jun 04 '19 at 05:07
  • Thanks all. I also learned that if you use the @PSBoundParameter, it only passes the explicitly set parameters. So, in the case that you have different default values, those could present a tricky debugging situation. – BlueTriangles Jun 04 '19 at 17:26
  • If you are using VSCode, the addon extension to convert lines to a splat. So, you'd just code as you would normally, select the code to convert to splat, hit F1, select the Show Additional Commands option, and type splat, hit enter. It does not cover all scenarios, as if you have a very complicated line, it often won't change it, but it will get you going more consistently. If you are in the ISE, See: https://mjolinor.wordpress.com/2012/01/16/ps-v3-ise-add-on-for-splatting-updated --- https://www.powershell.amsterdam/2016/01/06/automatic-parameter-splatting-ise-add-on – postanote Jun 04 '19 at 17:45