J'ai écrit un script PowerShell (voir ci-dessous) pour installer un très grand nombre de mises à jour MSP (fichiers avec .msp
extensions, déployés via Windows Installer) les unes après les autres. J'aimerais maintenant que ce script me dise également quand l'installation d'une mise à jour MSP a échoué.
Choses que j'ai essayées: Interroger le code d'erreur. Il y a deux approches:
- La première consiste à obtenir le code d'erreur à l'aide de $ LASTEXITCODE après une exécution
MSIEXEC.EXE
directe. C'est fastidieux. L'autre impliquait l'ajout d'un
-PassThru
commutateur àStart-Process
, stockant son résultat dans un objet, dit$a
et lisait le code d'erreur en utilisant$a.ExitCode
. Comme ça:$a=Start-Process msiexec.exe -ArgumentList "/p `"$MspRelPath`" /log `"$LogRelPath`" /passive /norestart" -Wait -PassThru Write-Host $a.ExitCode
Ni s'avérer utile. Il semble msiexec.exe
toujours retourner zéro comme code de sortie.
Si cela vous intéresse, voici le script:
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;
}
Réponses:
Vous pouvez soit rechercher les événements MSIExec dans les événements Windows, soit obtenir le contenu de la sortie du journal une fois terminé et vérifier les indications d'échec.
J'ai un script qui installe un fichier MSI à distance à l'aide de MSIExec, attend que MSIExec se ferme (ou que le processus / service démarre) ... si rien ne se produit après un temps d'installation typique, je vérifie le chemin d'accès au journal inclus dans l'appel MSIExec et vérifier les messages d'échec ou de succès
la source
msiexec
de générer un journal, mais comment interpréter par programmation le succès ou l'échec de ce journal? Bon Dieu, comment puis-je interpréter quoi que ce soit de ce journal? Je suis sûr que Microsoft a voulu que ce journal tourmente les administrateurs et ne les aide pas.