Powershell: Suggestion: Also include parameter default values in $PSBoundParameters or provide a similar variable that does

Created on 8 Mar 2017  路  9Comments  路  Source: PowerShell/PowerShell

Currently, a script/function's parameter is only considered _bound_ if an actual value was supplied by the _caller_.

Notably, this means that parameter _default values_ are _not_ reflected in $PSBoundParameters, which decreases its usefulness when the intent is to pass _all_ parameter values through to another command via splatting (@PSBoundParameters).

If there's a good reason to keep the current behavior (if only for the sake of not making a breaking change), perhaps another automatic variable, such as $PSParametersWithValue, could be introduced.

For a real-world example and workarounds, see this Stack Overflow question.

Issue-Discussion Issue-Enhancement WG-Language

Most helpful comment

Adding a new property is reasonable though - we have BoundPositionally list of strings - we could a similar BoundDefaultValue list.

All 9 comments

Yeah, I've written a function Get-ParameterValue several times for this purpose. Particularly when splatting to another function it's awkward to have to deal with it by hand. It would be nice if there was a $PSNonEmptyParameters or $PSParametersWithValues or something.

There is a strong reason not to change the current behavior: the presence of a member in this collection tells you that the parameter was actually specified in the command call i.e. that the formal parameter was bound hence the name "PSBoundParameters". You'll have to add a new variable if you want different semantics.

Adding a new property is reasonable though - we have BoundPositionally list of strings - we could a similar BoundDefaultValue list.

I realize this issue has long been stale, but for those of us who want a realistic solution, I have implemented some rather simple boilerplate code for it.

foreach($key in $MyInvocation.MyCommand.Parameters.Keys){
    $value = Get-Variable $key -ValueOnly -EA SilentlyContinue
    if($value -and !$PSBoundParameters.ContainsKey($key)) {$PSBoundParameters[$key] = $value}
}

My alternate method didn't work as I anticipated. Sorry for not double-checking before posting.

Thanks, @True-Demon, but the issue is still open; it sounds like the plan is to eventually implement it, but it's unclear when.

As for your workarounds:

The first one is great, but I don't think the second one will work, though, because $MyInvocation.MyCommand.Parameters contains only metadata, not values, from what I can tell.

@mklement0 That's why he calls get-variable 馃槈

Here's mine, which I mentioned earlier. It's basically the same thing, except that it merges with PSBoundParameters (and is in function form, so you can dot-source it, and includes tests to make _sure_ you dot-sourced it)

https://gist.github.com/Jaykul/c623c45d32329cadac9e7622937e1b76

@Jaykul:

That's why he calls get-variable

Yes, in the first snippet, which indeed works (as stated - though I'd use $null -ne $value rather than just $value as a slightly more robust conditional to infer the presence of a value from; it too modifies $PSBoundParameters directly).

However, my comment was about the second snippet, which I interpret to make the claim that $MyInvocation.MyCommand.Parameters would essentially already give us what this issue requests as an enhancement, which is not the case; specifically, I was referring to:

you can use the native $MyInvocation.MyCommand.Parameters, which contains all parameter keys & values, bound, null, default, or otherwise

My point was that $MyInvocation.MyCommand.Parameters seemingly contains just metadata, not values (neither bound nor default ones).

Thanks for sharing your Gist, which is a nicely packaged solution.
Sounds like we have viable workarounds now.
Let's hope that we soon won't need them anymore.

You're right, I made the mistake of assuming before I posted that. I've omitted that since it doesn't apply in order to prevent leading others astray.

Was this page helpful?
0 / 5 - 0 ratings