PowerShell Splatting and Hashtable Values

Last update: 2021-12-04 17:34:29 +0800 +0800
Available translations: 日本語 / 中文(简体) / 中文(繁體)

PowerShell splatting passes a hashtable or array as named or positional arguments. It avoids repeating long parameter lists and keeps configuration separate from a command invocation.

Splatting PowerShell Commands #

Prefix a hashtable variable with @ at the call site:

powershell
$request = @{
    Uri         = 'https://api.example.test/items'
    Method      = 'Get'
    Headers     = @{ Accept = 'application/json' }
    TimeoutSec  = 30
}

Invoke-RestMethod @request

Hashtable keys must match parameter names, including supported aliases. Splatting does not expand arbitrary strings into shell syntax; PowerShell binds the resulting values as typed command arguments.

PowerShell 7.1 and later permit an explicitly written named parameter to override the same parameter in a splatted hashtable. Earlier PowerShell releases report duplicate binding instead, so cross-version scripts should update a copied hashtable before invocation:

powershell
$effective = $request.Clone()
$effective.TimeoutSec = 60
Invoke-RestMethod @effective

Arrays provide positional splatting:

powershell
$copyArgs = @('source.txt', 'destination.txt')
Copy-Item @copyArgs

External Programs and Interpolation #

Native executables receive strings rather than PowerShell parameter binding. A hashtable property in an interpolated string needs a subexpression:

powershell
$config = @{
    AppId     = 'example-id'
    GroupCode = 'workers'
}

& $connector `
    "--app-id=$($config.AppId)" `
    "--group-code=$($config.GroupCode)"

"--app-id=$config.AppId" expands $config and leaves .AppId as literal text, which produces a value beginning with the hashtable’s string representation. $($config.AppId) evaluates the member access before interpolation.

Build an argument array when an executable has optional flags:

powershell
$arguments = @(
    '--server-mode=http'
    '--threads=10'
    "--app-id=$($config.AppId)"
)

& $connector @arguments
if ($LASTEXITCODE -ne 0) {
    throw "Connector failed with exit code $LASTEXITCODE"
}

The array splat after the call operator supplies one argument per array element. Avoid constructing one command string and passing it to Invoke-Expression; argument arrays preserve boundaries and avoid an additional parsing step.

On Windows, PowerShell 7.3 changed native argument passing through $PSNativeCommandArgumentPassing; the Standard, Windows, and Legacy modes control how the engine constructs the native command line. Unix-like systems pass an argument vector, while Windows programs may apply their own command-line parser. Test empty strings, embedded quotes, and trailing backslashes against the supported PowerShell and executable versions rather than serializing a command by hand.

Comments

Read or comment on GitHub (sign-in required to comment)