Powershell 散列哈希表-启动进程-参数列表

Powershell 散列哈希表-启动进程-参数列表,powershell,Powershell,我正在尝试使用splatting安装.MSI: $InstallerArgs @{ "DATABASENAME" = "my_database"; "LOCALIP" = "127.0.0.1"; "USERNAME" = "username1"; "/i" = "C:\Files\Installer.msi"; } 然后我调用启动进程: Start-Process -FilePath msiexec.exe -ArgumentList @InstallerAr

我正在尝试使用splatting安装.MSI:

$InstallerArgs @{
    "DATABASENAME" = "my_database";
    "LOCALIP" = "127.0.0.1";
    "USERNAME" = "username1";
    "/i" = "C:\Files\Installer.msi";
}
然后我调用
启动进程:

Start-Process -FilePath msiexec.exe -ArgumentList @InstallerArgs -Wait
这将返回错误:
缺少参数“ArgumentList”的参数。请指定“System.String[]”类型的参数,然后重试。


不能将Splating与
启动流程一起使用吗?

这实际上应该可以:

$InstallerArgs = @{
    FilePath = 'msiexec.exe'
    ArgumentList = @(
        '/i',
        'C:\Files\Installer.msi',
        'LOCALIP="127.0.0.1"',
        'USERNAME="username1"'
    )
    Wait = $True
}
Start-Process @InstallerArgs
不支持作为参数值(参数);相反,散乱的哈希表本身表示一组参数名-值对

相反,演示了splatting的正确使用,其中哈希表包含整个
启动进程
的参数名称-值对,传递到-msiexec
参数在
参数列表
哈希表项中指定为数组

如果您确实希望在单独的数据结构中只保留传递给-
msiexec
的参数,请使用数组并将其传递,因为
-ArgumentList
确实需要字符串数组作为其参数(
[string[]
):

以上内容最终将执行以下操作:

msiexec.exe DATABASENAME=my_database LOCALIP=127.0.0.1 USERNAME=username1 /i C:\Files\Installer.msi
请注意,由于一个长期存在的错误,任何需要双引号的值(通常是因为它们嵌入了空格)都必须明确指定嵌入的、转义的双引号(
`
);例如

这将导致通过
msiexec…”C:\Files A\Installer.msi“

从PowerShell[Core]7.0开始,该问题仍然存在,并且可能永远不会修复以保持向后兼容性。但是,可能会提供一个新参数以提供正确的行为-请参阅


使用外部程序重新部署的警告:

当使用哈希表(而不是数组)进行扩展时,PowerShell会将哈希表条目转换为
-:
参数
-请注意
-它与PowerShell命令配合使用,但可能不符合外部实用程序(如
msiexec
)所需的参数语法
建议将格式更改为用空格分隔(使用单独的参数;
-

一个简单的例子:

# 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
将看到以下参数:

-foo:"bar none"

您不一定需要
启动进程
。请记住: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
参数一起使用。

可以将splatting与
Start Process
一起使用,但您不能以这种方式为msi安装程序提供选项。另外,对于那些想知道是否需要在此处使用
Start Process
的人,请注意:,即在
-Wait
开关的帮助下确保同步(阻塞)执行
msiexec
,尽管有一个扩展的CLI,但它不是控制台应用程序,因此默认情况下是异步执行的(并且始终没有控制台输出)。如果您不是从脚本运行它,只是想运行命令从PowerShell提示符卸载某些内容,我更喜欢异步,因为我得到了提示,不必等待卸载完成。
-foo:"bar none"
msiexec /i C:\Files\Installer.msi DATABASENAME=my_database LOCALIP=127.0.0.1 USERNAME=username1