首页 > 解决方案 > 在文件夹中安装所有 .msi 文件

问题描述

我正在尝试编写一个我从 python 脚本启动的 powershell 脚本,该脚本将允许我通过并安装包含在某个文件夹中的每个 .msi 文件。

这是我到目前为止所拥有的:

$msiFiles = Get-ChildItem -Path "***PATH TO FOLDER***" -Recurse -Include *.msi

foreach($file in $msiFiles)
{

    Write-Host "$file is being installed"
    Start-Process "msiexec.exe" -arg "/I $file /qb ADDLOCAL=ALL ALLUSERS=TRUE" -Wait
    Write-Host "$file is finished being installed"


}

我想以静默模式安装这些 msi,所以我看不到或不需要 ant GUI 交互。当它要安装 msi 时,我会从安装程序中弹出一个弹出窗口,其中包含用于安装东西的所有可能命令,但它实际上并没有安装它。

在静默模式下安装这些的正确命令是什么?

标签: pythonpowershellwindows-installer

解决方案


通常,如果调用msiexec只显示一个描述命令行语法的对话框,则暗示存在语法问题

语法错误的可能来源"..."是您用作-arg参数的字符串(全名:-Args-ArgumentList)已$file嵌入其中而没有嵌入引号

也就是说,如果的值$file具有嵌入的空格,例如(例如,C:\Msi Installers\foo.msi),则生成的msiexec命令在语法上将是无效的,因为路径的空格分隔标记每个都被视为一个参数。

Bill_Stewart 的有用答案向您展示了如何使用嵌入式引用$file解决此问题,方法是将其包含在`"(`是 PowerShell 的转义字符) 中。

如果您坚持将参数作为单个字符串传递,您将使用:

Start-Process msiexec.exe -Args "/I `"$file`" /qb ADDLOCAL=ALL ALLUSERS=TRUE" -Wait

然而,可以说,不要单个类似命令行的字符串作为唯一参数传递,而是将参数作为数组的元素传递,这确实是-ArgumentList/-Args被设计接受的内容(它的参数类型是[string[]]) :

Start-Process msiexec.exe -Args /I, `"$file`", /qb, ADDLOCAL=ALL, ALLUSERS=TRUE -Wait

请注意,嵌入式引用仍然$file如何传递的,不幸的是,由于Start-Process(从 Windows PowerShell v5.1 / PowerShell Core v7.1 开始)中的一个错误,这是必需的;然而,看起来这个错误不会得到修复,但链接的 GitHub 报告建议引入一个
-ArgumentArray具有正确行为的新参数。


您也可以提前建立参数数组;注意这是如何在表达式模式下完成的(语法更像常规编程语言),所以数组元素需要引用;还要注意我如何使用引号来定义文字参数:

# Create the array of arguments to pass to msiexec
$msiArgs = 
  '/I',
  "`"$file`"",      #`# !! enclosing in `"...`" is needed due to the bug mentioned above
  '/qb',
  '/ADDLOCAL=ALL',
  'ALLUSERS=TRUE'

Start-Process msiexec.exe -Args $msiArgs -Wait      

推荐阅读