I am using PowerShell 5.1.
I'm having trouble understanding hashtable and splatting. When splatting are using a hash table to do that or is it something completely different?
I have the following code:
$hashtable1 = @{}
$hashtable1.add('PROD',@{ FirstName = 'John'; LastName = 'Smith'})
function Main() {
$sel = $hashtable1['PROD']
Function1 $sel
Function2 @sel
}
function Function1([hashtable] $x) {
"Value: $($x.LastName)"
$x.FirstName
}
function Function2([string] $firstName) {
"Value: $($firstName)"
}
Main
There's good information in the existing answers, but let me attempt a focused summary:
The answer to your actual question is:
Yes, @{ FirstName = 'John'; LastName = 'Smith' }
is a hashtable too, namely in the form of a declarative hashtable literal - just like @{}
is an empty hashtable literal (it constructs an instance that initially has no entries).
=
separating each key from its value, and pairs being separated with ;
or newlines.FirstName
), except if they contain special characters such as spaces or if they're provided via an expression, such as a variable reference; see this answer for details.This contrasts with adding entries to a hashtable later, programmatically, as your $hashtable1.Add('PROD', ...)
method call exemplifies (where PROD
is the entry key, and ...
is a placeholder for the entry value).
.Add()
method is to use an index expression or even dot notation (property-like access), though note that it situationally either adds an entry or updates an existing one: $hashtable1['PROD'] = ...
or $hashtable1.PROD = ...
The answer to the broader question implied by your question's title:
PowerShell's hashtables are a kind of data structure often called a dictionary or, in other languages, associative array or map. Specifically, they are case-insensitive instances of the .NET [hashtable]
(System.Collections.Hashtable
) type, which is a collection of unordered key-value pair entries. Hashtables enable efficient lookup of values by their associated keys.
Via syntactic sugar [ordered] @{ ... }
, i.e. by placing [ordered]
before a hashtable literal, PowerShell offers a case-insensitive ordered dictionary that maintains the entry-definition order and allows access by positional index in addition to the usual key-based access. Such ordered hashtables are case-insensitive instances of the .NET System.Collections.Specialized.OrderedDictionary
type.
A quick example:
# Create an ordered hashtable (omit [ordered] for an unordered one).
$dict = [ordered] @{ foo = 1; bar = 'two' }
# All of the following return 'two'
$dict['bar'] # key-based access
$dict.bar # ditto, with dot notation (property-like access)
$dict[1] # index-based access; the 2nd entry's value.
Splatting is an argument-passing technique that enables passing arguments indirectly, via a variable containing a data structure encoding the arguments, which is useful for dynamically constructing arguments and making calls with many arguments more readable.
Typically and robustly - but only when calling PowerShell commands with declared parameters - that data structure is a hashtable, whose entry keys must match the names of the target command's parameters (e.g., key Path
targets parameter -Path
) and whose entry values specify the value to pass.
In other words: This form of splatting uses a hashtable to implement passing named arguments (parameter values preceded by the name of the target parameter, such as -Path /foo
in direct argument passing).
A quick example:
# Define the hashtable of arguments (parameter name-value pairs)
# Note that File = $true is equivalent to the -File switch.
$argsHash = @{ LiteralPath = 'C:\Windows'; File = $true }
# Note the use of "@" instead of "$"; equivalent to:
# Get-ChildItem -LiteralPath 'C:\Windows' -File
Get-ChildItem @argsHash
Alternatively, an array may be used for splatting, comprising parameter values only, which are then passed positionally to the target command.
In other words: This form of splatting uses an array to implement passing positional arguments (parameter values only).
This form is typically only useful:
$args
variableA quick example:
# Define an array of arguments (parameter values)
$argsArray = 'foo', 'bar'
# Note the use of "@" instead of "$", though due to calling an
# *external program* here, you may use "$" as well; equivalent to:
# cmd /c echo 'foo' 'bar'
cmd /c echo @argsArray