Does PowerShell support splatting of positional arguments as opposed to named parameters?
PowerShell's argument splatting (see Get-Help about_Splatting
) offers two fundamental choices:
- splatting via a hashtable: works for named arguments only (e.g.,
-Path C:\Windows
- splatting via an array-like value: works for positional arguments only (e.g.,
C:\Windows
) - except in non-advanced functions that pass all [unbound] arguments through to another command via@args
(i.e., by splatting the automatic$args
array variable containing all unbound arguments), in which case named arguments are also supported, owing to magic built into@args
only.
Note: This dichotomy applies when passing arguments to PowerShell cmdlets / functions (with declared parameters), whereas external programs perform their own argument parsing, which may or may not interpret the set of arguments passed as named.[1]
That said, you can combine either form with regular, individual argument passing - using any combination of individual positional arguments, individual named arguments, hashtable-splatting, and array-splatting.
In both cases, the source data structure must be:
stored in a variable beforehand.
referenced with sigil
@
instead of$
.
Note: A future enhancement, detailed in this RFC, may bring the ability to splat expressions directly, without the need for an intermediate variable, though as of PowerShell Core 7 it is unclear when this will be implemented.
Examples:
# Positional binding via *array*.
# Note that a function's / script block's parameters are by default positional.
PS> $posArgs = 'one', 'two'; & { param($foo, $bar) "`$foo: $foo"; "`$bar: $bar" } @posArgs
$foo: one
$bar: two
# Named binding via *hashtable*
PS> $namedArgs=@{bar='two';foo='one'}; & { param($foo, $bar) "`$foo: $foo"; "`$bar: $bar" } @namedArgs
$foo: one
$bar: two
# *Combining* hashtable splatting with a regular, positional argument
PS> $namedArgs=@{bar='two'}; & { param($foo, $bar) "`$foo: $foo"; "`$bar: $bar" } @namedArgs one
$foo: one
$bar: two
[1] Splatting with external programs:
Generally, you do not need splatting when you call external programs, because:
You can pass arrays as-is (with the usual
$
sigil)The only exception is if you wanted to include
%--
, the stop-parsing symbol (seeGet-Help about_Parsing
, in the array of arguments; you do need to use the@
sigil in that event.Use the individual array elements to satisfy the external program's syntax requirements, including its named arguments, if any
(e.g.,$args = '/c', 'ver'; cmd $args
to executecmd /c ver
).
The way hashtable splats are translated into command-line tokens may or may not be recognized by external programs:
- Specifically, a hashtable entry with key
<paramName>
and value<value>
is translated into a single argument formatted as-<paramName>:<value>
- a format that few external command-line utilities recognize.
- Specifically, a hashtable entry with key
© 2022 - 2024 — McMap. All rights reserved.
Invoke-Command
, realized I have some positional parameters that aren't named (not prefixed with a-
, anyways). – Agile