Как мой скрипт может определить, была ли установка определенного обновления установщика Windows (MSP) успешной или нет?

Как мой скрипт может определить, была ли установка определенного обновления установщика Windows (MSP) успешной или нет?

Я написал скрипт PowerShell (см. ниже) для установки очень большого количества обновлений MSP (файлов с .mspрасширениями, развернутых через установщик Windows) одного за другим. Теперь я хотел бы, чтобы этот скрипт также сообщал мне, когда установка обновления MSP не удалась.

Что я пробовал: Запрос кода ошибки.Существует два подхода:

  • Один из них — получить код ошибки с помощью $LASTEXITCODE после MSIEXEC.EXEпрямого запуска. Это утомительно.
  • Другой включал добавление -PassThruswitch к Start-Process, сохранение его результата в объекте, скажем, $aи чтение кода ошибки с помощью $a.ExitCode. Вот так:

    $a=Start-Process msiexec.exe -ArgumentList "/p `"$MspRelPath`" /log `"$LogRelPath`" /passive /norestart" -Wait -PassThru
    Write-Host $a.ExitCode
    

Ни то, ни другое не оказалось полезным. Кажется, msiexec.exeвсегда возвращается ноль в качестве кода выхода.


Если кому интересно, вот скрипт:

param (
    [parameter(mandatory=$false)][Switch]$BypassAdminPrompt
)
Try 
{
  Clear-Host

  # Get script name
  $ScriptFileObject=(Get-Item $PSCommandPath)
  $ScriptName=$ScriptFileObject.Name
  $ScriptPath=$ScriptFileObject.DirectoryName

  # Load Windows Forms and initialize visual styles
  [void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
  [System.Windows.Forms.Application]::EnableVisualStyles()

  # Is the script holding administrative privileges?
  $wid=[System.Security.Principal.WindowsIdentity]::GetCurrent()
  $prp=new-object System.Security.Principal.WindowsPrincipal($wid)
  $adm=[System.Security.Principal.WindowsBuiltInRole]::Administrator
  $IsAdmin=$prp.IsInRole($adm)
  if ($IsAdmin -eq $false) {
    if (!$BypassAdminPrompt) {
      Start-Process powershell.exe -ArgumentList "-ExecutionPolicy $env:PSExecutionPolicyPreference -File `"$PSCommandPath`" -BypassAdminPrompt" -Verb RunAs
    } else {
      $result=[System.Windows.Forms.MessageBox]::Show("This script requires administrative privileges, which are absent.", $ScriptName, "OK", "Error");
    }
    break;
  }

  # Install...
  Set-Location $ScriptPath
  $MSP_list = Get-ChildItem *.msp -Recurse
  if ($MSP_list -eq $null) {
    $result=[System.Windows.Forms.MessageBox]::Show("Nothing found to install.`rSearch path was "+$ScriptPath, $ScriptName, "OK", "Error");
  }
  else
  {
    $MSP_list | ForEach-Object {
      # Ordinarily, I'd pass the path in the form of ".\foldername\filename.msp" but Windows Installer does not accept that.
      # It must be in "foldername\filename.msp" form.
      $MspRelPath = $_.FullName.Substring($ScriptPath.Length+1)
      $LogRelPath = $MspRelPath+".log"
      Write-Host $MspRelPath
      Start-Process msiexec.exe -ArgumentList "/p `"$MspRelPath`" /log `"$LogRelPath`" /passive /norestart" -Wait
    }
    Remove-Variable MspRelPath
    Remove-Variable LogRelPath
    Pause
  }
  Remove-Variable MSP_list
}
Catch
{
  $result=[System.Windows.Forms.MessageBox]::Show("Error!`r`r"+$Error[0], $ScriptName, "OK", "Error");
  break;
}

решение1

либо проверьте события Windows на наличие событий MSIExec, либо получите содержимое выходного журнала после завершения и проверьте наличие признаков сбоя.

У меня есть скрипт, который устанавливает MSI удаленно с помощью MSIExec, ждет, пока MSIExec завершит работу (или запустится процесс/служба)... если после типичного времени установки ничего не происходит, я проверяю путь к журналу, включенный в вызов MSIExec, и проверяю сообщения об ошибках или успехах.

Связанный контент