Installationsprozess abfragen mit PowerShell

Reinhard77

Lieutenant
Registriert
Feb. 2019
Beiträge
889
Hallo,

ich suche nach einer Möglichkeit den Status bzw. den Installationsprozess von .msi Dateien abzufragen.

Dazu habe ich folgende Lösung gefunden, die auch einwandfrei funktioniert. Doch habe ich festgestellt, dass der von Windows gestartete Prozess "msiexec" relativ lange braucht, bis der beendet wurde, was somit die Installation um ein paar Minuten verlangsamt, obwohl die Installation des jeweiligen Programms schon längst abgeschlossen ist.

Wieso ist das so und wie kann ich es so lösen, dass ich nicht auf den Prozess "msiexec" warten muss?

Im Netz stehen viele Hinweise, mit ExitCode usw. doch wenn ich die teste funktionieren die nicht so wirklich.

Hier der PowerShell Code:

PowerShell:
$ExampleNameInstall = Start-Process msiexec.exe -Wait -ArgumentList '/i C:\ExampleName.msi'                             
#start installation of ExampleName       
$ExampleNameInstall

if (Get-Process | Where-Object {$_.Name -eq "msiexec"})               
{       
    #make a write host while installation is present         
    do{         
        Write-Host "Install Program ExampleName..." -ForegroundColor Yellow         
        Start-Sleep -Seconds 20         
    }while (Get-Process -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Where-Object {$_.Name -eq "msiexec"})
}
else
{
    Write-Host "Program ExampleName was not installed"
}
 
Zuletzt bearbeitet:
Du könntest versuchen das msi Log anzuschalten, evtl. steht da drin, wieso es so lange dauert.

/L*V "C:\pfad\datei.log"
 
Reinhard77 schrieb:
Im Netz stehen viele Hinweise, mit ExitCode usw. doch wenn ich die teste funktionieren die nicht so wirklich.
was meinst du damit konkret?
Auf ExitCodes schaust du ja gar nicht, und ob die Installation erfolgreich war, schaust du auch nicht an?
 
floq0r schrieb:
So wie das aussieht hättest du sowieso ein Problem wenn mehrere Instanzen von msiexec laufen weil du deinen Call nicht genau identifizieren kannst.

Es laufen aber keine mehreren Instanzen, da für jedes Paket ein seperater Schritt ausgeführt wird, der erst dran ist, wenn der vorige abgeschlossen ist. Also muss ich mir darüber momentan keine Gedanken machen.

tollertyp schrieb:
was meinst du damit konkret?
Auf ExitCodes schaust du ja gar nicht, und ob die Installation erfolgreich war, schaust du auch nicht an?

Wenn ich dazu ein funktionierendes Beispiel hätte, dann würde ich das auch umsetzen. Aber die Infos im Netz helfen mit oft nicht weiter, da immer mit gefühlt tausend Variablen um sich geschmissen wird, aber keiner zeigt so richtig ausführlich wie es (auch) geht. Das hilft mir nicht weiter. Bei der Masse an Möglichkeiten geht man da rasch unter, im Detail.
 
Du könntest noch die PID der gestarteten msiexec mit abfragen und prüfen ob der Prozess noch läuft.
Plus eben das logging der msi mitnehmen und nach „finish“ o.ä. parsen.

Beim Schreiben fällt mir gerade auf, du willst nur wissen wieso die msiexec mal länger braucht? Oder hab ich das missverstanden?
 
  • Gefällt mir
Reaktionen: s1ave77
Und warum musst du die tausend Variablen nutzen?
Starte den Prozess, warte bis der Aufzuf zurückkommt. Den ExitCode ignorierst du eh schon, dann mach das doch auch weiterhin.

Und ist ja schön, dass du das verhinderst, aber wie stellst du sicher, dass nicht anderweitig ein msiexec-Prozess gestartet wird?
 
derlorenz schrieb:
Beim Schreiben fällt mir gerade auf, du willst nur wissen wieso die msiexec mal länger braucht? Oder hab ich das missverstanden?

Nö. Die Info wäre auch hilfreich. Ich will abfragen, ob die Installation erfolgreich war oder nicht und das ganze evtl. in einen try catch Block packen, um Fehler abzufangen. Der try catch Block muss aber nicht sein, wenn es auch besser ohne geht.

hier steht was ähnliches. Hat aber in Verbindung mit der gewünschten Variante nicht funktioniert.
 
  • Gefällt mir
Reaktionen: s1ave77
Und wie willst du mit deinem Ansatz so eine Prüfung machen?
Woher soll die Erleuchtung kommen, was das Ergebnis von msiexec ist?

Und was genau hast du ausprobiert? "hat nicht funktioniert" ist nichtssagend.
 
Ja, die Überprüfung des Rückgabecodes (Return Code) ist eine gängige Methode, um festzustellen, ob eine MSI-Installation erfolgreich war. Hier sind einige der wichtigsten Rückgabecodes, die msiexec.exe zurückgeben kann:

  • 0: Erfolgreiche Installation
  • 1603: Schwerwiegender Fehler bei der Installation
  • 1618: Eine andere Installation läuft bereits
  • 1641: Neustart erforderlich, um die Installation abzuschließen
  • 3010: Installation erfolgreich, aber Neustart erforderlich

PowerShell:
$process = Start-Process 'msiexec.exe' -ArgumentList '/I "Pfad\Zu\Ihrer\Datei.msi" /qn' -Wait -PassThru
if ($process.ExitCode -eq 0) {
    Write-Output "Installation war erfolgreich."
} else {
    Write-Output "Installation fehlgeschlagen mit Fehlercode: $($process.ExitCode)"
}

Erste Antwort von ChatGPT ohne Verbesserungen oder nachbohren.
 
  • Gefällt mir
Reaktionen: tollertyp
Powered by ChatGPT:

Code:
# Array von MSI-Dateipfaden
$msiFiles = @(
    "C:\Pfad\zu\Installationsdatei1.msi",
    "C:\Pfad\zu\Installationsdatei2.msi",
    "C:\Pfad\zu\Installationsdatei3.msi"
)

# Installationsparameter (z.B. quiet für stille Installation)
$installArgs = "/quiet /norestart"

foreach ($msi in $msiFiles) {
    # Kommandozeilenbefehl zum Aufruf von msiexec
    $command = "msiexec.exe /i `"$msi`" $installArgs"

    # Asynchrones Starten des Installationsprozesses
    Write-Host "Starte Installation von $msi ..."
    $process = Start-Process -FilePath "msiexec.exe" -ArgumentList "/i `"$msi`" $installArgs" -NoNewWindow -PassThru

    # Prüfen des Prozesses während er läuft
    while (!$process.HasExited) {
        Write-Host "Installation von $msi läuft noch..."
        # Hier kannst du andere Aufgaben ausführen, solange der Prozess läuft
        Start-Sleep -Seconds 5  # Beispielsweise eine Pause von 5 Sekunden
    }

    # Überprüfung des Exit-Codes nach Beendigung des Prozesses
    if ($process.ExitCode -ne 0) {
        Write-Error "Installation von $msi ist fehlgeschlagen mit Exit-Code $($process.ExitCode). Skript wird beendet."
        exit $process.ExitCode
    } else {
        Write-Host "Installation von $msi erfolgreich abgeschlossen."
    }
}

Write-Host "Alle Installationen wurden erfolgreich abgeschlossen."
(bricht beim ersten Fehler ab)

Asynchron, so dass du sogar den "Fortschritt" ausgeben kannst
 
  • Gefällt mir
Reaktionen: JumpingCat
  • Gefällt mir
Reaktionen: s1ave77
tollertyp schrieb:
Und wie willst du mit deinem Ansatz so eine Prüfung machen?
Woher soll die Erleuchtung kommen, was das Ergebnis von msiexec ist?

Und was genau hast du ausprobiert? "hat nicht funktioniert" ist nichtssagend.
JumpingCat schrieb:
PowerShell:
$process = Start-Process 'msiexec.exe' -ArgumentList '/I "Pfad\Zu\Ihrer\Datei.msi" /qn' -Wait -PassThru
if ($process.ExitCode -eq 0) {
    Write-Output "Installation war erfolgreich."
} else {
    Write-Output "Installation fehlgeschlagen mit Fehlercode: $($process.ExitCode)"
}

Erste Antwort von ChatGPT ohne Verbesserungen oder nachbohren.

Ich denke ich habe meinen Fehler gefunden. Ich hatte den Parameter -PassThru nicht hinzugefügt, da ich nicht wusste was der Parameter macht und dann war der Fehler immer, dass ich eine Methode mit Null aufrufe.

Erst wenn man darüber z.B. hier schreibt, wird es klarer...
Und natürlich liest, was der Prameter eingentlich tut.
 
  • Gefällt mir
Reaktionen: tollertyp
Das ist gut.

Was hast du im allgemein damit vor? Das so zu Skripten scheint mir eine Sonderlocke zu sein.
 
  • Gefällt mir
Reaktionen: tollertyp
JumpingCat schrieb:
Was hast du im allgemein damit vor? Das so zu Skripten scheint mir eine Sonderlocke zu sein.

Automatisieren.

Dieses Problem sollte damit gelöst sein. Danke euch!
Ergänzung ()

blablub1212 schrieb:
Ich glaub das Problem des TEs ist, dass die Installation seiner Meinung nach schon abgeschlossen ist, bevor der MSI-Prozess abgeschlossen wurde. Du könntest hiermit https://learn.microsoft.com/de-de/windows/win32/wmisdk/wmi-tasks--computer-software mal prüfen zu welchem Zeitpunkt du Infos zum installierten Programm zurückbekommst. Evtl. schon bevor der MSI-Prozess abgeschlossen ist.

Ich denke eher nicht, da ich aus Erfahrung weiß, das gewisse Programme schneller installiert wurden, bevor ich mit do while den Prozess "msiexec" abgefragt habe. Ich denke da wird Windows ein Timeout eingebaut haben oder dergleichen. Aber um diese Frage zu klären, habe ich ja diesen Thread erstellt. Und wenn nicht, dann frage ich mich, wieso die Installation von PowerShell als abgeschlossen angesehen wurde, obwohl sie es nicht war? Das sollte dann ja eigentlich mit -wait sichergestellt sein, oder nicht?
Ergänzung ()

blablub1212 schrieb:
Du könntest hiermit https://learn.microsoft.com/de-de/windows/win32/wmisdk/wmi-tasks--computer-software mal prüfen zu welchem Zeitpunkt du Infos zum installierten Programm zurückbekommst. Evtl. schon bevor der MSI-Prozess abgeschlossen ist.

Ja mache ich, nur heute wird das nichts mehr.
 
Zuletzt bearbeitet:
Also ich nehme an, dass es hier um mehr als nur ein System geht, dann kann an sowas auch machen. Wenn es für ein System ist, dann ist es der Aufwand meiner Erfahrung nach nicht wert.
 
Zurück
Oben