I'm trying to install an .MSI using splatting:
$InstallerArgs @{
"DATABASENAME" = "my_database";
"LOCALIP" = "127.0.0.1";
"USERNAME" = "username1";
"/i" = "C:\Files\Installer.msi";
}
I then call Start-Process:
Start-Process -FilePath msiexec.exe -ArgumentList @InstallerArgs -Wait
This returns the error: Missing an argument for parameter 'ArgumentList'. Specify a parameter of type 'System.String[]' and try again.
Is it not possible to use splatting with Start-Process?
Splatting (@<varName>) isn't supported as a parameter value (argument); instead, the hashtable that is splatted itself represents a set of parameter name-value pairs.
Olaf's helpful answer, by contrast, demonstrates proper use of splatting, where the hashtable contains the parameter name-value pairs for Start-Process as a whole, with the pass-through-to-msiexec parameters specified as an array in the ArgumentList hashtable entry.
If you do want to maintain just the pass-through-to-msiexec arguments in a separate data structure, use an array and pass it as such, given that -ArgumentList indeed expects a string array as its argument ([string[]]):
$InstallerArgs = @(
"DATABASENAME=my_database"
"LOCALIP=127.0.0.1"
"USERNAME=username1"
"/i"
"C:\Files\Installer.msi"
)
# Note: NO splatting
Start-Process -FilePath msiexec.exe -ArgumentList $InstallerArgs -Wait
The above ends up executing the following:
msiexec.exe DATABASENAME=my_database LOCALIP=127.0.0.1 USERNAME=username1 /i C:\Files\Installer.msi
Note that, due to a long-standing bug, any values that need double-quoting - typically, because they have embedded whitespace - must explicitly specify embedded, escaped double quotes as well (`"); e.g.,
"`"C:\Files A\Installer.msi`""
This would result in msiexec ... "C:\Files A\Installer.msi" getting passed through.
The problem still exists as of PowerShell [Core] 7.0, and may never be fixed in order to preserve backward compatibility. However, a new parameter may be provided to provide the correct behavior - see GitHub issue #5576.
Caveat re splatting with external programs:
When splatting with hashtables (rather than arrays), PowerShell translates the hashtable entries into
-<key>:<value> arguments - note the : - which works well with PowerShell commands, but may not conform to the argument syntax expected by external utilities such as msiexec.
GitHub issue #9343 suggests that the format be changed to separating with a space (using separate arguments; -<key> <value>).
A simple example:
# Define hashtable with parameter name-value pairs.
$htParams = @{
foo = 'bar none' # parameter -foo with value 'bar none'
}
# Pass the hashtable via splatting (note the use of @ instead of $).
baz.exe @htParams
baz.exe would then see the following argument:
-foo:"bar none"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With