【问题标题】:Automate .msi installs自动化 .msi 安装
【发布时间】:2020-11-28 04:46:03
【问题描述】:

我正在尝试一个接一个地批量安装一堆 .msi。但是当我运行我的 powershell 脚本时 msiexec /?好像我的论点是错误的。我在这里错过了什么?

$Path = Get-ChildItem -Path *my path goes here* -Recurse -Filter *.MSI
foreach ( $Installer in ( Get-ChildItem -Path $Path.DirectoryName -Filter *.MSI ) ) {
    Start-Process -Wait -FilePath C:\windows\system32\msiexec.exe -ArgumentList "/i '$Installer.FullName'"
}

【问题讨论】:

  • "/i '$Installer.FullName'"改成"/i '$($Installer.FullName)'"

标签: powershell automation windows-installer


【解决方案1】:

Olaf's answer 包含很好的指针,但让我尝试从概念上归结为:

您的尝试有两个不相关的问题:

  • 仅在可扩展字符串 ("...") 内简单变量引用 ($Installer) 可以按原样使用; 表达式 ($Installer.FullName) 需要 $()subexpression operator: $($Installer.FullName) - 请参阅 this answer 了解 PowerShell 中可扩展字符串(字符串插值)的概述。

  • 由于您通过-ArgumentListmsiexec 的参数作为单个字符串 传递,因此仅支持嵌入的双引号 "...",而不支持'...'(单引号)。

因此,请使用以下内容(为简洁起见,-FilePath-ArgumentList 参数按位置传递给Start-Process):

Get-ChildItem $Path.DirectoryName -Recurse -Filter *.MSI | ForEach-Object {
  Start-Process -Wait C:\windows\system32\msiexec.exe "/i `"$($_.FullName)`""
}

注意:

-ArgumentList 参数是 array 类型的 ([string[]])。理想情况下,您应该将参数单独作为数组的元素传递:'/i', $_.FullName,这不需要您考虑 嵌入 在 单个字符串。

不幸的是,Start-Process doesn't handle such individually passed arguments properly if they contain embedded spaces,所以可靠的解决方案是使用 single -ArgumentList 参数,包括 所有 参数,嵌入双必要时引用,如上所示。

有关更详细的讨论,请参阅this answer

【讨论】:

    【解决方案2】:

    语法"/i '$Installer.FullName'" 不正确。在你的代码中应该是"/i", $Installer.FullName

    将 PowerShell 对象括在双引号中会触发字符串扩展。发生这种情况时,只有变量本身被其值替换,然后其余不属于名称的字符被视为字符串。当您运行以下 sn-p 时,您可以看到该对象执行了 ToString(),然后只是将字符串 .FullName 添加到它。

    foreach ( $Installer in ( Get-ChildItem -Path $Path.DirectoryName -Filter *.MSI ) ) {
         "/i $Installer.FullName"
    }
    

    如果你必须有双引号,那么一种解决方法是使用子表达式运算符 $()。解析器将其中的任何内容视为表达式。所以更详细的"/i '$($Installer.FullName)'" 在技术上会起作用。

    完整的代码应该是:

    $Path = Get-ChildItem -Path *my path goes here* -Recurse -Filter *.MSI
    foreach ( $Installer in ( Get-ChildItem -Path $Path.DirectoryName -Filter *.MSI ) ) {
        Start-Process -Wait -FilePath C:\windows\system32\msiexec.exe -ArgumentList "/i", $Installer.FullName
    }
    

    【讨论】:

    • 你的建议得到了同样的结果。
    【解决方案3】:

    在 Powershell 5.1 中,使用 msi,您还可以:

    install-package $installer.fullname
    

    【讨论】:

      猜你喜欢
      • 2010-09-15
      • 2012-02-05
      • 1970-01-01
      • 2011-01-03
      • 1970-01-01
      • 2011-05-11
      • 1970-01-01
      • 2018-07-21
      • 2016-11-14
      相关资源
      最近更新 更多