2011-01-20 17 views

risposta

3

Depends. Gli MSI possono essere installati usando WMI. Per gli ex e altri metodi, è possibile utilizzare Start-Process e controllare il Process ExitCode.

3

MSI può anche essere installato utilizzando msiexec.exe, MSU di può essere installato utilizzando wusa.exe, entrambi hanno un interruttore /quiet, /norestart e /forcerestart interruttori e un'opzione /log per la registrazione (specificare il nome del file).

Si può leggere di più sulle opzioni se li chiami con /?

Nota: wusa fallisce silenziosamente quando non riescono, quindi bisogna controllare il file di log o registro eventi per determinare il successo.

0

Ho implementato esattamente quello che stai cercando nel mio progetto attuale. Dobbiamo automatizzare la distribuzione e l'instillazione di n numero di app in più ambienti e data center. Questi script sono leggermente modificati dalla versione originale per motivi di semplicità poiché il mio codice completo raggiunge le 1000 linee ma la funzionalità di base è intatta. Spero che questo faccia quello che stai chiedendo.

Questa funzione PS estrae tutte le app dal registro (da che cosa si aggiungono/rimuovono i programmi), quindi cerca il nome dell'app fornito e visualizza la versione. Nel mio codice (PSM1) eseguo questa funzione prima di installare o meno i loro e poi afterword per verificare che sia stata installata .... Tutto ciò può essere avvolto in una funzione principale per controllare il flusso del gestore.

function Confirm-AppInstall{ 
param($AppName,$AppVersion) 
$Apps = Get-ItemProperty Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*|?{$_.DisplayName -ne $Null}|?{$_.DisplayName -ne ""} 

$Apps += Get-ItemProperty Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*|?{$_.DisplayName -ne $Null}|?{$_.DisplayName -ne ""} 

$Installed = $Apps|?{$_.DisplayName -eq ""}|?{$_.DisplayVersion -eq ""}|select -First 1 
if($Installed -ne $null){return $true}else{return $false} 
} 

Questa funzione PS caricherà un file txt con i comandi di installazione prepopolati (un comando per riga). ed esegui ogni riga indivaduly ed aspetti l'installazione per completare prima di passare al seguente.

function Install-Application{ 
param($InstallList = "C:\Install_Apps_CMDS.txt") 

$list = gc -Path $InstallList 
foreach ($Command in $list){ 
    Write-Output ("[{0}]{1}" -f (Get-Date -Format G),$call) 
    #Make install process wait for exit before continuing. 
    $p = [diagnostics.process]::Start("powershell.exe","-NoProfile -NoLogo -Command $Command") 
    $p.WaitForExit() 
    Start-Sleep -Seconds 2 
    #Searches for the installer exe or msi that was directly opened by powershell and gets the process id. 
    $ProcessID = (gwmi -Query ("select ProcessId from Win32_Process WHERE ParentProcessID = {0} AND Name = '{1}'" -f $p.Id,$ParentProcessFile)|select ProcessId).ProcessId 
    #waits for the exe or msi to finish installing 
    while ((Get-Process -Id $ProcessID -ea 0) -ne $null){ 
     Start-Sleep -Seconds 2 
     $ElapsedTime = [int](New-TimeSpan -Start $P.StartTime -End (Get-Date)|select TotalSeconds).TotalSeconds 
     #install times out after 1000 seconds so it dosent just sit their forever this can be changed 
     if(2000 -lt $ElapsedTime){ 
      Write-Output ('[{0}] The application "{1}" timed out during instilation and was forcfully exited after {2} seconds.' -f (Get-Date -Format G),$App.Name,(([int]$App.InstallTimeOut) * 60)) 
      break 
     } 
    } 
    #clean up any old or hung install proccess that should not be running at this point. 
    Stop-Process -Name $ParentProcessName -ea 0 -Force 
    Stop-Process -Name msiexec -ea 0 -Force 
    } 
} 

Il file TXT deve essere formattato come tale ... dovrete fare voi ricerca su come ogni applicazione ha bisogno di essere installato. una buona risorsa è appdeploy.com

C:\Install.exe /q 
C:\install.msi /qn TRANSFORMS='C:\transform.mst' 
C:\install2.msi /qn /norestart 
C:\install3.exe /quiet 

Fatemi sapere se ci sono errori che ho dovuto modificare il mio codice esistente per rimuovere i valori di proprietà e rendere questo un po 'più semplice. Sto estrapolando i miei valori da un foglio di risposta XML personalizzato. Ma questo codice dovrebbe funzionare come l'ho fornito.

Se desideri discutere di più sulla mia implementazione fammi sapere e posso fare una spiegazione più dettagliata e aggiungere anche altre funzioni di supporto che ho implementato.

16

Queste risposte sembrano tutte eccessivamente complicate o non sufficientemente complete. L'esecuzione di un programma di installazione nella console di PowerShell presenta alcuni problemi. Un MSI viene eseguito nel Windows subsystem, quindi non è possibile richiamarli (Invoke-Expression o &). Alcune persone sostengono di far funzionare quei comandi tramite piping a Out-Null o Out-Host, ma non l'ho osservato per funzionare.

Il metodo che funziona per me è Start-Process con i parametri di installazione non presidiati su msiexec.

$list = 
@(
    "/I `"$msi`"",      # Install this MSI 
    "/QN",        # Quietly, without a UI 
    "/L*V `"$ENV:TEMP\$name.log`""  # Verbose output to this log 
) 

Start-Process -FilePath "msiexec" -ArgumentList $list -Wait 

È possibile ottenere il exit code dal comando Start-Process ed esaminarlo per pass/fail valori. (ed ecco lo exit code reference)

$p = Start-Process -FilePath "msiexec" -ArgumentList $list -Wait -PassThru 

if($p.ExitCode -ne 0) 
{ 
    throw "Installation process returned error code: $($p.ExitCode)" 
} 
Problemi correlati