Skip to content

Parameter binding pipeline input, and how the default parameter set influences that behavior #10188

@KirkMunro

Description

@KirkMunro

When you have multiple parameter sets that take pipeline input, one by value and another (or others) by property name, if you pipe in the actual object type that is accepted by value that will not necessarily result in the corresponding parameter set being used. This feels wrong, more like a gotcha than how things should actually work.

For example, consider Enable-PSBreakpoint, Disable-PSBreakpoint, and Remove-PSBreakpoint.

Each of those commands has two parameter sets. Let's just call them "Id" and "Breakpoint" (those may be their actual names, but it doesn't matter). The "Id" parameter set has an int id parameter that accepts pipeline input by property name. The "Breakpoint" parameter set has a Breakpoint breakpoint parameter set that accepts pipeline input by value.

Enable-PSBreakpoint is configured to use the "Id" parameter set by default. The others are configured to use the "Breakpoint" parameter set by default.

If you pipe a Breakpoint object into each of these cmdlets, the parameter set that is chosen is based on the default parameter set and the properties on the object passed in. For Enable-PSBreakpoint, the "Id" parameter set is a match because the incoming object has an "Id" property, so it is used. For the others, the "Breakpoint" parameter set is a match, so it is used.

I think this is wrong, and feel that if you pipe in an object that matches exactly the type of a parameter that accepts pipeline input by value, that is the most logical choice to use no matter what the default parameter set is. You can only have one ValueFromPipeline parameter in a command -- that should be for a good reason like the behavior expected here, but it doesn't really seem like it is.

As a command author, if I were building these commands from scratch I would want the "Id" parameter set to be the default so that ad hoc users are prompted for an id if they invoke the command with no parameters (prompting them for a breakpoint with no transform attribute to convert from an id to a breakpoint is useless), but I would also most definitely expect that the "Breakpoint" parameter set is used if I pipe in an actual "Breakpoint" object.

I suspect at this point this would just be a breaking change. I'm posting this issue here just the same because it can cause unexpected bugs to occur (like the one I just lost an hour to), so users should be aware of this (Is this behavior documented? I'll have to check later). This is also one of those things that I would be inclined to opt into in my modules if I could localize the change so that my commands work more intelligently (i.e. if we had support for optional features as described in an open RFC right now).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Breaking-Changebreaking change that may affect usersIssue-Questionideally support can be provided via other mechanisms, but sometimes folks do open an issue to get aResolution-No ActivityIssue has had no activity for 6 months or moreWG-Enginecore PowerShell engine, interpreter, and runtime

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions