带有参数的 PowerShell 调用不替代 PARAM 来安装 MSI

Posted

技术标签:

【中文标题】带有参数的 PowerShell 调用不替代 PARAM 来安装 MSI【英文标题】:PowerShell Invoke with parameters not substituting PARAM for installing MSI 【发布时间】:2020-04-13 02:49:07 【问题描述】:

我正在尝试使用 Power-shells Invoke 来运行 MSI 安装。

此代码未运行 MSI 安装。

param ($path1, $path2, $path3)

write-output "path1= $path1"
write-output "path2= $path2"
write-output "path3= $path3"
$PathToMSI = "D:\Install\$path1\'$path2$path3'"
write-output "PathToMSI= $PathToMSI"

$scriptblock = Start-Process msiexec.exe -Argumentlist "/i $PathToMSI","/qn"
invoke-command  -scriptblock $scriptblock 

我知道我的 PathToMSI 是正确的,因为这是显示的内容,但它没有执行。

path1= 20191213.3
path2= X Y Z
path3= .msi
PathToMSI= D:\Install\20191213.3\'X Y Z.msi'

如果我以硬编码运行它,它可以工作吗?

Invoke-Command -ScriptBlock 
    D:\install\20191213.3\'X Y Z.msi' /quiet

似乎 PathToMSI 没有解决它的价值。 我已经评论了一些像Error invoking command to install a Msi through Powershell

【问题讨论】:

你能分开/i $PathToMSI,让所有参数都是ArgumentList数组中的元素吗?例如Start-Process msiexec.exe -ArgumentList '/i', $PathToMSI, '/qn/'? 我为脚本块添加了写入,$Path1 没有解析PathToMSI= D:\Install\20191213.3\'X Y Z.msi' scriptblock= Start-Process msiexec.exe -Argumentlist "/i D:\Install\$path1\'$path2$path3'","/qn" scriptblock= 启动进程 msiexec.exe -Argumentlist "/i, $PathToMSI, ","/qn" 你试过Test-Path "$PathToMSI"吗?撇号是有效的文件名字符,所以我怀疑您的文件名是否包含尾随撇号。试试$PathToMSI = "D:\Install\$path1\$path2$path3" 等一下,我看到了问题。我将作为答案发布,但远程命令不知道如何解析您的本地变量。 【参考方案1】:

您需要将$PathToMSI 传递给ScriptBlock。您可以为此使用-ArgumentList

Invoke-Command -ArgumentList $PathToMSI -ScriptBlock 
  Start-Process msiexec.exe -Argumentlist '/i', $args[0], '/qn'

如果在远程计算机上调用,您可以使用$using: scope:

Invoke-Command -ComputerName server.domain.tld -ScriptBlock 
  Start-Process msiexec.exe -Argumentlist '/i', $using:PathToMSI, '/qn'

Invoke-Command 在新的 PowerShell 会话中运行您的 ScriptBlock,该会话不知道您可能已声明的任何局部变量。 $using 作用域将向父会话寻求变量解析,而 -ArgumentList 将传递可以使用 ScriptBlock 中的 $args 变量引用的文字变量。

【讨论】:

使用 $using 我得到以下错误:##[error]System.Management.Automation.RuntimeException: 无法检索使用变量。 Using 变量只能与脚本工作流中的 Invoke-Command、Start-Job 或 InlineScript 一起使用。与 Invoke-Command 一起使用时,Using 变量只有在远程计算机上调用脚本块时才有效。 使用参数列表运行第一个条目得到相同的结果,它说它运行了,但它没有运行 MSI 包 如果您完全避开 Start-Process 来执行以下操作,请确保使用上面的 ArgumentList 方法(我自己从不使用 Start-Process 用于 msiexec):&msiexec /i $args[0] /qn 我找到了另一个解决方案,其中有人遇到 Invoke 问题:***.com/questions/25407353/…;将 MSI 从“XY Z.msi”更改为“XYZ.MSI”后,它按预期工作。 如果您使用调用运算符& 执行msiexec 而不是Start-Process 会发生什么?您是否尝试过输出args[0] 以查看$PathToMSI 是否存在?另外,如果您不远程运行此程序,为什么首先使用Invoke-Command

以上是关于带有参数的 PowerShell 调用不替代 PARAM 来安装 MSI的主要内容,如果未能解决你的问题,请参考以下文章

如何在 PowerShell 中调用带有输出参数的方法?

如何从 TeamCity 构建配置中设置 PowerShell 开关参数

带有嵌套引号的 Powershell 调用 msbuild

带有嵌套引号的 Powershell 调用 msbuild

带有 Robocopy 和参数传递的 Powershell

如何在不连接 Powershell 的情况下传递参数? [复制]