Splatting哈希表 - Start-Process -ArgumentList

时间:2018-02-27 14:40:57

标签: powershell

我尝试使用splatting安装.MSI:

$InstallerArgs @{
    "DATABASENAME" = "my_database";
    "LOCALIP" = "127.0.0.1";
    "USERNAME" = "username1";
    "/i" = "C:\Files\Installer.msi";
}

然后我致电Start-Process:

Start-Process -FilePath msiexec.exe -ArgumentList @InstallerArgs -Wait

这会返回错误:Missing an argument for parameter 'ArgumentList'. Specify a parameter of type 'System.String[]' and try again.

是否无法使用[{1}}?

进行拼接

3 个答案:

答案 0 :(得分:5)

这实际上应该有效:

$InstallerArgs = @{
    FilePath = 'msiexec.exe'
    ArgumentList = @(
        '/i',
        'C:\Files\Installer.msi',
        'LOCALIP="127.0.0.1"',
        'USERNAME="username1"'
    )
    Wait = $True
}
Start-Process @InstallerArgs

答案 1 :(得分:5)

Splatting (@<varName>)不支持作为参数 (参数);相反,splatted 本身的哈希表表示一组参数名称 - 值对

相比之下,

Olaf's helpful answer演示了splatting的正确使用,其中散列表包含Start-Process 作为整体的参数名称 - 值对,其中传递给msiexec参数,指定为ArgumentList哈希表条目中的数组。

如果您只想在单独的数据结构中维护传递到msiexec参数,请使用数组传递它,假设-ArgumentList确实需要字符串 array 作为其参数([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

以上结果执行以下操作:

msiexec.exe DATABASENAME=my_database LOCALIP=127.0.0.1 USERNAME=username1 /i C:\Files\Installer.msi

请注意,如果=右侧的值需要双引号 - 例如,因为它们嵌入了空格,您必须 - 不幸的是 - 显式嵌入转义双引号`");例如,

"/i `"C:\Files A\Installer.msi`""

这会导致/i "C:\Files A\Installer.msi"通过。

使用外部程序重新展开

使用哈希表(而不是数组)进行展开时,PowerShell会将哈希表条目转换为
-<key>:<value>参数
- 请注意: - 适用于 PowerShell 命令,但可能不符合外部实用程序(如{{1)所期望的参数语法}}。
This GitHub issue建议将格式更改为使用空格分隔(使用单独的参数; msiexec)。

一个简单的例子:

-<key> <value>
然后

# 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

答案 2 :(得分:2)

您不一定需要Start-Process。记住:PowerShell是一个shell;它可以运行您键入的命令,就像cmd.exe一样。

msiexec /i C:\Files\Installer.msi DATABASENAME=my_database LOCALIP=127.0.0.1 USERNAME=username1

如果任何参数包含空格,请将它们用"个字符括起来。

注意:这将异步运行msiexec(即,如果您在脚本中运行该命令,它将继续执行下一行脚本而无需等待msiexec完成)。如果您想在继续之前等待msiexec完成(例如,同步运行),则可以将Start-Process-Wait参数一起使用,如其他答案中所述。