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
As far I understand the issue behind the rejection: the discussion was meanly focused on an operator that could pass an unnamed argument which would require a semantic sugar in the engine that might conflict with other syntaxes or initiate a break change.
If the splatting could be done by means of a common named parameter (e.g. -Splat [Object[]]), the impact on the enige would be less and I guess easier to implement, while this would be more PowerShell compliant and support inline usage:
As with any introduction of a new common parameter, breaking existing scripts that use the same parameter name for custom purposes is a concern, and a quick search here on GitHub reveals quite a few that already use -Splat.
Thus, perhaps -PSSplat is the better choice (an analogous search currently finds no preexisting uses).
Thank you for your feedback (and the way to check search repositories).
Other alternative names, I could think of:
-SplatParameters which abbreviates to -Splat and -SplatParam
-BindParameters which abbreviates to -Bind and -BindParam. In addition to this, it could have a possible -Splat alias.
(Abbreviations and aliases get afaik a lesser priority as an actual parameter name).
Good idea; -SplatParameters seems like a better choice (I'd definitely keep the word "splat" in there), as the "PS" prefix has no precedent among the common parameters; -SplatParameters too yields currently no code-search results.
Just to clarify: I presume that by abbreviated you're simply referring to the "elastic syntax" feature, i.e. the ability to situationally specify an unambiguous name prefix for targeting any parameter by name.
(Formally declaring e.g. -Splat as an alias of -SplatParameters wouldn't work.)
Overall, I liked this idea. Exactly, as an idea. But if you consider it in a practical plane, then doubts arise about the expediency of its application. If you take the interactive mode, then it is rather inconvenient, and in scripts there is no need to save on variables. The only area of application is script blocks or copy-paste to the console.
Although it must be said that splatting allows you to structure the set of parameters.
There is: Any construct that forces you to use an auxiliary variable that otherwise serves no purpose deserves improving to eliminate that need - indeed, that's what drove the original RFC.
237dmitry, in a enhancement propose, it is not about what the propose doesn't add but what it does add.
Which in this case is mainly support for inline splatting without violating the best practices:
As with the current implementation, there is probably less need for splatting in the interactive shell (where readability is generally less of a issue as it isn't being reused). Anyways, aside from reusing splatted parameters in different commands, I can imaging situation where you could prevent some redundancy, e.g. in a situation where you have a list of parameter collection that you want to apply on a specific cmdlet as New-AzVm:
Saying that, if this propose is generally accepted, I would prefer it to support (PSCustom)Objects (#6889) rather than the current splatting (embedded) unnamed parameters (arrays) feature as that is hard to combine and the latter could lead to complex and unmanageable for cmdlet parameters as ConvertTo-Csv -Splat $MyObject, ';', especially if:
If $MyObject is similar splatted parameter collection
If there are multi parameter sets involved (that can't be resolved) along with issues as:
In other words, keep it imple and lean by only supporting (embedded) named (key-value pairs) splat parameters, like: ConvertTo-Csv -Splat @{ InputObject = $MyObject; Delimiter = ';' } . To test this idea, I have created a (quick and dirty) prototype which isn't common but might be used to manually add a -SplatParameters parameter to an existing cmdlet to check the syntax:
Example 1: Reuse splatted parameters in different commands
Add-SplatParameterWrite-Host$Colors=@{ForegroundColor="black"; BackgroundColor="white"}
#Write a message with the colors in $ColorsWrite-Host"This is a test."-Splat $Colors#Write second message with same colors. The position of splatted#hash table does not matter.Write-Host-Splat $Colors"This is another test."
Example 2: Inline Splatting
Write-Host"This is a test."-Splat @{
ForegroundColor="black"BackgroundColor="white"
}
Example 3: Override bound parameters:
Write-Host"This is a test."-ForegroundColor Blue -Splat @{ ForegroundColor="black"; BackgroundColor="white" }
Example 4: Override splat parameters:
Write-Host"This is a test."-Splat @{ ForegroundColor="black"; BackgroundColor="white" } -ForegroundColor Blue
Example 5: Loading a list of parameter object collections
Apart from the fact that -Path and -LiteralPath are mutual exclusive for Get-ChildItem anyways, I see no harm in using the suggested named -Splat parameters in the currently existing splatting feature (although I didn't implement this in the Add-SplatParameter prototype). In other words, I see no issues in your suggestive questions, but don't hesitate to further elaborate if you think there is really a (unresolvable) concern here.
Reacted by 237dmitry, Michael Klement and Blue Falcon
My only 2 concerns are:
1: Normal functions/scripts don't get common parameters, so if I define a function like this: function MyFunction ($Test){} I won't be able to use this new splat parameter.
2: It's weird to add a new common parameter that interacts slightly differently with existing systems (splatting) than every other parameter.
The obvious solution to 1 would be to just add the common parameter regardless if it's a basic or advanced function, but that would be yet another example of the odd inconsistency mentioned in the second problem.
That's why I'd personally prefer to see a new syntax like: ls -@{X="Y"} or ls @@{X="Y"} rather than a new common parameter.
Reacted by Jordan Borean, Michael Klement, iRon7, Blue Falcon, Mathias R. Jessen and Steve
Indeed, it was just to show the basic syntax as compared to the (documented) current implementation
Making splatting support [pscustomobject] instances as an alternative to `[hashtable] ...
so I encourage you to open a new issue
I am little reluctant to do that as I fear a complex rabbit hole in combination with the splatting with arrays feature where any item in the array might be a [PSCustomObject] ($InputObject) by itself. That is why I actually like to avoid this particular feature from this specific propose.
Also knowing that the general best practice is to Avoid Using Positional Parameters. To my opinion the splatting-with-arrays feature already affects the readability of the Splatting-with-hash-tables, take e.g.
1: Normal functions/scripts don't get common parameters
That is valid point (and that also includes external commands) but note that for basic functions you will also lose other common parameters as e.g. -?.
2: It's weird to add a new common parameter that interacts slightly differently with existing systems (splatting)
That is true, but improvements require change (where you might debate whether it is indeed an improvement).
iRon7, just to close the [pscustomobject] tangent: array- and hashtable-based splatting are already mutually exclusive [update: in the context of a single instance of splatting]: when you use an array for splatting (which is useful primarily when calling external programs, though even there it is isn't strictly necessary to use splatting at all), its elements are passed as-is as individual arguments.
In other words: you (sensibly) cannot mix these two forms of splatting [in a single instance of splatting], and there is therefore also no conceptual confusion.
My suggestion was to simply allow [pscustomobject]s as an alternative to hashtable-based splatting.
Mathias R. Jessen (@IISResetMe), indeed it does.
That's not what I was talking about, however: I was talking about (sensibly) not being able to mix the two approaches in a single instance of splatting, such as expecting array elements that happen to be hashtables to be splatted in a nested fashion (I've updated my previous comment to clarify).
P.S.: Not only have I personally never seen multiple instances of splatting in the context of a given, single command, doing so is, in my estimation, ill-advised.
array- and hashtable-based splatting are already mutually exclusive
You are right, I was under the assumption that they could also be mixed. Still, I see some issues with supporting both array and PSCustomObject based splatting (also knowing that PowerShell tents to unroll single item arrays).
Meaning any PSCustomObject scalar could perceived as a unnamed position 0 argument, like the way it works now:
$Object = ConvertFrom-Csv @' # or often $inputObject at position 0
BackgroundColor, ForegroundColor, Object
Black, Green, Foo
'@
Write-Host @Object
@{BackgroundColor=Black; ForegroundColor=Green; Object=Foo}
Or as PSCustomObject based splatting (as suggested):
$Splat=ConvertFrom-Csv@'BackgroundColor, ForegroundColor, ObjectBlack, Green, Foo'@Write-Host@Splat
Foo # where Foo is written in green
The differents with hashtable based splatting is that there a virtually no cmdlets that accept a hashtable a position 0.
The impact is probably low (and resolvable with $Splat = @($Splat)), but there is in fact one native cmdlet that is currently affected by this confusion:
Get cmdlets that could lead to array splatting confusion
```PowerShell
foreach ($Command in Get-Command *) {
if ($Command.Parameters) {
$PSCustomObjectAt0, $SomeThingAt1 = $null
foreach($Parameter in $Command.Parameters.get_Values()) {
if (
$Parameter.ParameterType -eq [System.Collections.iDictionary] -and
0 -eq $Parameter.Attributes.Position
) { $PSCustomObjectAt0 = $true }
if (1 -eq $Parameter.Attributes.Position) { $SomeThingAt1 = $True }
if ($PSCustomObjectAt0 -and $SomeThingAt1) { $Command; break }
}
}
}
```
CommandType Name Version Source
----------------------------
Cmdlet Add-Member7.0.0.0 Microsoft.PowerShell.Utility
And for PSCustomObject based splatting (change $Parameter.ParameterType -eq [System.Collections.iDictionary] to $Parameter.ParameterType -eq [PSCustomObject]) the affected cmdlets (aside from any potential custom cmdlet) are:
CommandType Name Version Source
----------------------------
Cmdlet ConvertTo-Csv7.0.0.0 Microsoft.PowerShell.Utility
Cmdlet Register-ObjectEvent7.0.0.0 Microsoft.PowerShell.Utility
Cmdlet Unprotect-CmsMessage7.0.0.0 Microsoft.PowerShell.Security
And I am not even covering the (lower impact but higher complexity) confusion that might raise with parameters sets (that could have different parameter positions per set)
I'm personally of the mind that that's a non-issue, or at least one we can document ourselves out of - if you want to use advanced syntactical features like the splatting operator I think it's fair to also expect you familiarize yourself with the semantics (as is already the case, as shown in your example).
I'm attempting to take another stab at splatting enhancements in PowerShell and have opened a summary of the various options proposed over the years and am hoping to get feedback from anyone interested. If you are interested in having a look and/or wanting to comment on some of the options I would love any feedback at jborean93/PowerShell-RFC#1.
The aim is to get more community consensus around the various options before settling on a real RFC based on the feedback and going from there.
I needed some time to adjust my feelings about this and I agree now that as Mathias stated, the bears on the road I saw are probably non-issues. Meaning (MartinGC94 ) that I think that a possible new splat parameter should indeed interact similar as the existing system (splatting) implementation toward array-based splatting (and possible even reuse some code behind this).
For opening a new issue on PSCustomObject-based splatting, I still like to hold off a bit and see how the Add enhanced splatting RFC draft #1 from Jordan is perceived and evolves.
Thanks all for your feedback and thoughts on this.
Activity
mklement0 commentedon May 16, 2025
Great idea, iRon7.
As with any introduction of a new common parameter, breaking existing scripts that use the same parameter name for custom purposes is a concern, and a quick search here on GitHub reveals quite a few that already use
-Splat.Thus, perhaps
-PSSplatis the better choice (an analogous search currently finds no preexisting uses).iRon7 commentedon May 17, 2025
Michael Klement (@mklement0),
Thank you for your feedback (and the way to check search repositories).
Other alternative names, I could think of:
-SplatParameterswhich abbreviates to-Splatand-SplatParam-BindParameterswhich abbreviates to-Bindand-BindParam. In addition to this, it could have a possible-Splatalias.(Abbreviations and aliases get afaik a lesser priority as an actual parameter name).
MartinGC94 commentedon May 17, 2025
What would happen if you splat the splat parameter?
jborean93 commentedon May 17, 2025
Add a few more levels and use
Splatin theSplatin the splat :)mklement0 commentedon May 17, 2025
iRon7:
Good idea;
-SplatParametersseems like a better choice (I'd definitely keep the word "splat" in there), as the "PS" prefix has no precedent among the common parameters;-SplatParameterstoo yields currently no code-search results.Just to clarify: I presume that by abbreviated you're simply referring to the "elastic syntax" feature, i.e. the ability to situationally specify an unambiguous name prefix for targeting any parameter by name.
(Formally declaring e.g.
-Splatas an alias of-SplatParameterswouldn't work.)anonhostpi commentedon May 17, 2025
BEFORE we get into any disagreements:
I'm gonna say it now (to prevent the exact same conversation that kicked off in the RFC):
I think that we would all be happy if there was anyway to inline splat than no way at all...
kasini3000 commentedon May 17, 2025
I think it's possible to write a notice in "powershell next version.MSI" stating that 'psteam' will use 'splash' as the public keyword.
Establish a preview version function switch.
237dmitry commentedon May 17, 2025
Overall, I liked this idea. Exactly, as an idea. But if you consider it in a practical plane, then doubts arise about the expediency of its application. If you take the interactive mode, then it is rather inconvenient, and in scripts there is no need to save on variables. The only area of application is script blocks or copy-paste to the console.
Although it must be said that splatting allows you to structure the set of parameters.
mklement0 commentedon May 17, 2025
237dmitry
There is: Any construct that forces you to use an auxiliary variable that otherwise serves no purpose deserves improving to eliminate that need - indeed, that's what drove the original RFC.
237dmitry commentedon May 18, 2025
The point is comfort syntax. I do not believe that you do want type splattings in interactive shell:
iRon7 commentedon May 20, 2025
237dmitry, in a enhancement propose, it is not about what the propose doesn't add but what it does add.
Which in this case is mainly support for inline splatting without violating the best practices:
As with the current implementation, there is probably less need for splatting in the interactive shell (where readability is generally less of a issue as it isn't being reused). Anyways, aside from reusing splatted parameters in different commands, I can imaging situation where you could prevent some redundancy, e.g. in a situation where you have a list of parameter collection that you want to apply on a specific cmdlet as
New-AzVm:To visualize this:
Saying that, if this propose is generally accepted, I would prefer it to support (
PSCustom)Objects(#6889) rather than the current splatting (embedded) unnamed parameters (arrays) feature as that is hard to combine and the latter could lead to complex and unmanageable for cmdlet parameters as, especially if:ConvertTo-Csv -Splat $MyObject, ';'$MyObjectis similar splatted parameter collectionIn other words, keep it imple and lean by only supporting (embedded) named (key-value pairs) splat parameters, like:
ConvertTo-Csv -Splat @{ InputObject = $MyObject; Delimiter = ';' }. To test this idea, I have created a (quick and dirty) prototype which isn't common but might be used to manually add a-SplatParametersparameter to an existing cmdlet to check the syntax:Add-SplatParameter
Add-SplatParameter
Example 1: Reuse splatted parameters in different commands
Example 2: Inline Splatting
Example 3: Override bound parameters:
Example 4: Override splat parameters:
Example 5: Loading a list of parameter object collections
A more realistic use case would probably be Creating Users with a CSV
where if you fully prepare the source CSV file, you might do:
Example 6: Inline (multiple lines without using backticks) translating parameter object collections
The syntax in the later examples might also be used to forward parameters using
$PSBoundParametersMartinGC94,
I think that a cyclic splat parameters should be neglected or eventually produce an error.
Apart from the fact that
-Pathand-LiteralPathare mutual exclusive forGet-ChildItemanyways, I see no harm in using the suggested named-Splatparameters in the currently existing splatting feature (although I didn't implement this in theAdd-SplatParameterprototype). In other words, I see no issues in your suggestive questions, but don't hesitate to further elaborate if you think there is really a (unresolvable) concern here.237dmitry commentedon May 20, 2025
And script-block is visualized
But with pipelining it will be convenient, no need to delete variables or localize their scope.
MartinGC94 commentedon May 20, 2025
My only 2 concerns are:
1: Normal functions/scripts don't get common parameters, so if I define a function like this:
function MyFunction ($Test){}I won't be able to use this new splat parameter.2: It's weird to add a new common parameter that interacts slightly differently with existing systems (splatting) than every other parameter.
The obvious solution to 1 would be to just add the common parameter regardless if it's a basic or advanced function, but that would be yet another example of the odd inconsistency mentioned in the second problem.
That's why I'd personally prefer to see a new syntax like:
ls -@{X="Y"}orls @@{X="Y"}rather than a new common parameter.2 remaining items
iRon7 commentedon May 21, 2025
Michael Klement (@mklement0),
Indeed, it was just to show the basic syntax as compared to the (documented) current implementation
I am little reluctant to do that as I fear a complex rabbit hole in combination with the splatting with arrays feature where any item in the array might be a
[PSCustomObject]($InputObject) by itself. That is why I actually like to avoid this particular feature from this specific propose.Also knowing that the general best practice is to Avoid Using Positional Parameters. To my opinion the splatting-with-arrays feature already affects the readability of the Splatting-with-hash-tables, take e.g.
vs:
And will probably be more confusing in combination with a support of Splatting-with-PSCustomObjects feature.
MartinGC94,
That is valid point (and that also includes external commands) but note that for basic functions you will also lose other common parameters as e.g.
-?.That is true, but improvements require change (where you might debate whether it is indeed an improvement).
Anyways, thank you both for you feedback.
mklement0 commentedon May 21, 2025
iRon7, just to close the
[pscustomobject]tangent: array- and hashtable-based splatting are already mutually exclusive [update: in the context of a single instance of splatting]: when you use an array for splatting (which is useful primarily when calling external programs, though even there it is isn't strictly necessary to use splatting at all), its elements are passed as-is as individual arguments.In other words: you (sensibly) cannot mix these two forms of splatting [in a single instance of splatting], and there is therefore also no conceptual confusion.
My suggestion was to simply allow
[pscustomobject]s as an alternative to hashtable-based splatting.anonhostpi commentedon May 21, 2025
MartinGC94
Be careful of what you wish for.
-splatvs@@debate has already taken place and is exactly what caused the RFC to fail (debate could never get resolved).Not trying to discourage discourse, but it might be wiser to unify on one syntax than debating it (given the circumstances).
Otherwise, they'll close this issue just like they did the RFC
IISResetMe commentedon May 21, 2025
Michael Klement (@mklement0) mixing different types of splatting targets in the same invocation works just fine:
mklement0 commentedon May 21, 2025
Mathias R. Jessen (@IISResetMe), indeed it does.
That's not what I was talking about, however: I was talking about (sensibly) not being able to mix the two approaches in a single instance of splatting, such as expecting array elements that happen to be hashtables to be splatted in a nested fashion (I've updated my previous comment to clarify).
P.S.: Not only have I personally never seen multiple instances of splatting in the context of a given, single command, doing so is, in my estimation, ill-advised.
iRon7 commentedon May 22, 2025
Michael Klement (@mklement0),
You are right, I was under the assumption that they could also be mixed. Still, I see some issues with supporting both array and PSCustomObject based splatting (also knowing that PowerShell tents to unroll single item arrays).
Meaning any
PSCustomObjectscalar could perceived as a unnamed position0argument, like the way it works now:Or as PSCustomObject based splatting (as suggested):
The differents with hashtable based splatting is that there a virtually no cmdlets that accept a hashtable a position
0.IISResetMe commentedon May 22, 2025
iRon7
Does the following example illustrate your core concern here?
iRon7 commentedon May 22, 2025
Mathias R. Jessen (@IISResetMe),
Exactly, in fact the concern already plays with the current implementation, for function with parameters like:
The impact is probably low (and resolvable with
$Splat = @($Splat)), but there is in fact one native cmdlet that is currently affected by this confusion:Get cmdlets that could lead to array splatting confusion
```PowerShell foreach ($Command in Get-Command *) { if ($Command.Parameters) { $PSCustomObjectAt0, $SomeThingAt1 = $null foreach($Parameter in $Command.Parameters.get_Values()) { if ( $Parameter.ParameterType -eq [System.Collections.iDictionary] -and 0 -eq $Parameter.Attributes.Position ) { $PSCustomObjectAt0 = $true } if (1 -eq $Parameter.Attributes.Position) { $SomeThingAt1 = $True } if ($PSCustomObjectAt0 -and $SomeThingAt1) { $Command; break } } } } ```And for PSCustomObject based splatting (change
$Parameter.ParameterType -eq [System.Collections.iDictionary]to$Parameter.ParameterType -eq [PSCustomObject]) the affected cmdlets (aside from any potential custom cmdlet) are:And I am not even covering the (lower impact but higher complexity) confusion that might raise with parameters sets (that could have different parameter positions per set)
IISResetMe commentedon May 22, 2025
Thanks for clarifying iRon7
I'm personally of the mind that that's a non-issue, or at least one we can document ourselves out of - if you want to use advanced syntactical features like the splatting operator I think it's fair to also expect you familiarize yourself with the semantics (as is already the case, as shown in your example).
jborean93 commentedon May 27, 2025
I'm attempting to take another stab at splatting enhancements in PowerShell and have opened a summary of the various options proposed over the years and am hoping to get feedback from anyone interested. If you are interested in having a look and/or wanting to comment on some of the options I would love any feedback at jborean93/PowerShell-RFC#1.
The aim is to get more community consensus around the various options before settling on a real RFC based on the feedback and going from there.
iRon7 commentedon May 28, 2025
Michael Klement (@mklement0), Mathias R. Jessen (@IISResetMe),
I needed some time to adjust my feelings about this and I agree now that as Mathias stated, the bears on the road I saw are probably non-issues. Meaning (MartinGC94 ) that I think that a possible new splat parameter should indeed interact similar as the existing system (splatting) implementation toward array-based splatting (and possible even reuse some code behind this).
For opening a new issue on PSCustomObject-based splatting, I still like to hold off a bit and see how the Add enhanced splatting RFC draft #1 from Jordan is perceived and evolves.
Thanks all for your feedback and thoughts on this.
SeeminglyScience commentedon Jul 2, 2025
Centralizing all of the issues about inline splatting in #25721
microsoft-github-policy-service commentedon Jul 2, 2025
📣 Hey @iRon7, how did we do? We would love to hear your feedback with the link below! 🗣️
🔗 https://aka.ms/PSRepoFeedback