You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Add $PSBoundParametersObject and support for Splatting PSCustomObjects #6889
There are often scenarios where you need $PSBoundParameters but with some parameter(s) excluded, some renamed, and others possibly added to get the correct parameters needed for another function your calling.
There are many existing ways to manipulate $PSBoundParameters but they are not intuitive due to the type of $PSBoundParameters.
If we had $PSBoundParametersObject we could do things like:
Adding the ability to splat PSCustomOjbects we could then do:
Invoke-Something @ParametersNeededToCallFunction
This would allow better knowledge reuse as someone who takes the time to learn Select-Object and Add-Memeber now can intuitively deal with bound parameters.
This would be better than having to learn about and deal with a lot of the quirks related to System.Management.Automation.PSBoundParametersDictionary which are not as generally applicable.
Reacted by KevinW, adanlozano, Stu Mace, bb010g and iRon7
I'm not sure I see how this is a win. Because $PSBoundParameters is essentially just a hashtable, all the normal things you do with hashtables just work. Adding a property is simple assignment:
Bruce Payette (@BrucePay) I have taken what you have said to heart and been writing code since you posted this in the style you proposed as I figured doing it this way would help me better explain the difficulties with this pattern.
Some observations:
$PSBoundParameters.Remove("propertytoremove") returns True or False depending on whether the property was present so in practice you always have to remember to do something like | Out-Null or you will likely break code calling your function
If we had $PSBoundParametersObject the code we write feels cleaner and more clear
Below are two examples of the same function that ends up calling another function that makes a web service call that needs to have some parameters in the body of the request, some in the query string, and some to change the behavior of the function making the request (like setting authorization headers).
Using $PSBoundParameters as it is today
function New-FreshDeskTicket {
param (
$name,
$requester_id,
$email,
$facebook_id,
$phone,
$twitter_id,
$unique_external_id,
$subject,
#.. 17 more parameters go here but removed for brevity
$Credential,
$SubDomain
)
$InvokeAPIParameters = @{}
$PSBoundParameters.Keys |
Where-Object Name -In "Credential","SubDomain" |
ForEach-Object {
$InvokeAPIParameters.Add($_, $PSBoundParameters.$_)
}
$QueryStringParameters = @{}
$PSBoundParameters.Keys |
Where-Object Name -In "requester_id","unique_external_id" |
ForEach-Object {
$QueryStringParameters.Add($_, $PSBoundParameters.$_)
}
$PSBoundParameters.Remove("Credential") | Out-Null
$PSBoundParameters.Remove("Domain") | Out-Null
Invoke-FreshDeskAPI -Body $PSBoundParameters -QueryString $QueryStringParameters -Resource tickets -Method Post @InvokeAPIParameters
}
Using $PSBoundParametersObject
function New-FreshDeskTicket {
param (
$name,
$requester_id,
$email,
$facebook_id,
$phone,
$twitter_id,
$unique_external_id,
$subject,
#.. 17 more parameters go here but removed for brevity
$Credential,
$SubDomain
)
$InvokeAPIParameters = $PSBoundParametersObject | Select-Object -Property Credential,SubDomain
$QueryStringParameters = $PSBoundParametersObject | Select-Object -Property requester_id,unique_external_id
$BodyParameters = $PSBoundParametersObject | Select-Object -ExcludeProperty Credential,Domain,requester_id,unique_external_id
#When https://github.com/PowerShell/PowerShell/issues/7049 is resolved we won't need the following if statement
if (-Not $InvokeAPIParameters) {
$InvokeAPIParameters = [PSCustomObject]@{}
}
Invoke-FreshDeskAPI -Body $BodyParameters -QueryString $QueryStringParameters -Resource tickets -Method Post @InvokeAPIParameters
}
It doesn't appear that splatting a System.Object[] of System.Collections.Generic.KeyValuePair``2[[System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Object, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]] behaves the same way as splatting a System.Collections.Hashtable.
Your right, it is including the key with the value as the value. In theory, the ToDictionary LINQ Extension Method should convert it back to a workable state but don't know if that is working yet in 6.0+.
Maybe Splatting just needs to be updated to handle passing the KeyValuePair type directly and handle that weirdness for us.
Troy Campbell (@dragonwolf83) Just for information's sake, the above test was with PowerShell version 6.1.0-preview.2.
I think your intuition about how this should work not aligning with how it actually works is further evidence that this does not align with the principle of least astonishment and that things would be better/less surprising if we had an object to work with and could splat objects instead of dealing with the idiosyncrasies of dictionaries/hashtables for this particular purpose.
Reacted by alx9r and Harry John
microsoft-github-policy-service commented on Nov 16, 2023
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
microsoft-github-policy-service commented on Nov 16, 2023
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
microsoft-github-policy-service commented on Nov 16, 2023
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
Activity
ChrisMagnuson commentedon May 17, 2018
In case it helps provide context, I use a helper function ConvertFrom-BSBoundParameters to accomplish a similar style of coding now.
vexx32 commentedon May 19, 2018
This is a neat idea, but I must say this should have a slightly shorter name!
BrucePay commentedon May 24, 2018
I'm not sure I see how this is a win. Because
$PSBoundParametersis essentially just a hashtable, all the normal things you do with hashtables just work. Adding a property is simple assignment:and removing a property is done with the
Remove()method.This seems simpler than messing around with
Select-ObjectandAdd-Memberand will definitely be much faster. What am I missing?ChrisMagnuson commentedon Aug 10, 2018
Bruce Payette (@BrucePay) I have taken what you have said to heart and been writing code since you posted this in the style you proposed as I figured doing it this way would help me better explain the difficulties with this pattern.
Some observations:
$PSBoundParameters.Remove("propertytoremove")returnsTrueorFalsedepending on whether the property was present so in practice you always have to remember to do something like| Out-Nullor you will likely break code calling your function$PSBoundParametersObjectthe code we write feels cleaner and more clearUsing $PSBoundParameters as it is today
Using $PSBoundParametersObject
dragonwolf83 commentedon Aug 11, 2018
You can pretty much do everything in your
PSBoundParametersObjectexample if you use.GetEnumerator(). The code is just as simple as yours:ChrisMagnuson commentedon Aug 13, 2018
Troy Campbell (@dragonwolf83) I am having trouble getting an example working the way your describing things should:
It doesn't appear that splatting a
System.Object[]ofSystem.Collections.Generic.KeyValuePair``2[[System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Object, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]behaves the same way as splatting aSystem.Collections.Hashtable.dragonwolf83 commentedon Aug 13, 2018
Your right, it is including the key with the value as the value. In theory, the
ToDictionaryLINQ Extension Method should convert it back to a workable state but don't know if that is working yet in 6.0+.Maybe Splatting just needs to be updated to handle passing the
KeyValuePairtype directly and handle that weirdness for us.ChrisMagnuson commentedon Aug 13, 2018
Troy Campbell (@dragonwolf83) Just for information's sake, the above test was with PowerShell version 6.1.0-preview.2.
I think your intuition about how this should work not aligning with how it actually works is further evidence that this does not align with the principle of least astonishment and that things would be better/less surprising if we had an object to work with and could splat objects instead of dealing with the idiosyncrasies of dictionaries/hashtables for this particular purpose.
microsoft-github-policy-service commentedon Nov 16, 2023
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
microsoft-github-policy-service commentedon Nov 16, 2023
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
microsoft-github-policy-service commentedon Nov 16, 2023
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
microsoft-github-policy-service commentedon Nov 23, 2023
This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes.