2011-01-20 18 views

Respuesta

3

Depende. Las MSI se pueden instalar usando WMI. Para exes y otros métodos, puede usar Start-Process y verificar Process ExitCode.

3

MSI también se puede instalar utilizando msiexec.exe, MSU se puede instalar utilizando wusa.exe, ambos tienen un interruptor /quiet, /norestart y /forcerestart interruptores y una opción para iniciar sesión /log (especificar el nombre de archivo).

Puede leer más acerca de las opciones si se les llame con /?

Nota: wusa falla silenciosamente cuando fallan, así que hay que comprobar el archivo de registro o registro de eventos para determinar el éxito.

0

He implementado exactamente lo que está buscando en mi proyecto actual. Necesitamos automatizar la implementación y la instalación de n numerosas aplicaciones en múltiples entornos y centros de datos. Estos scripts se modifican ligeramente de la versión original por simplicidad, ya que mi código completo alcanza las 1000 líneas, pero la funcionalidad principal está intacta. Espero que esto haga lo que estás pidiendo.

Esta función de PS extrae todas las aplicaciones del registro (de lo que se deducen o eliminan los programas) y luego busca el nombre de la aplicación suministrada y la versión de visualización. En mi código (PSM1), ejecuto esta función antes de instalar para ver si es suya o no, y luego de la palabra clave posterior para verificar que se haya instalado ... Todo esto puede ser envuelto en una función maestra para controlar el control de flujo.

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} 
} 

Esta función PS cargará un archivo txt que tiene preinstalados los comandos de instalación (un comando por línea). y ejecute cada línea indivádidamente y espere a que se complete la instalación antes de pasar a la siguiente.

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 
    } 
} 

El archivo debe tener el formato TXT como tal ... que tendrá que hacer que la investigación sobre cómo se tiene que instalar cada aplicación. un buen recurso es appdeploy.com

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

Quiero saber si hay algún error que tuve que modificar mi código existente para eliminar los valores de propiedad y hacer esto un poco más simplista. Estoy extrayendo mis valores de una hoja de respuestas XML personalizada. Pero este código debería funcionar como lo he suministrado.

Si desea que debata más sobre mi implementación, hágamelo saber y puedo darle una explicación más detallada y también agregar más funciones de apoyo que he implementado.

16

Todas estas respuestas parecen demasiado complicadas o no lo suficientemente completas. Ejecutar un instalador en la consola de PowerShell tiene algunos problemas. Un MSI se ejecuta en el Windows subsystem, por lo que no puede invocarlos (Invoke-Expression o &). Algunas personas afirman que los comandos funcionan por tuberías al Out-Null o Out-Host, pero no he observado que funcionen.

El método que funciona para mí es Start-Process con los parámetros de instalación silenciosa en 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 

Puede obtener el exit code del comando Start-Process y compruebe que no pasa/no pasa valores. (y aquí está el 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)" 
} 
Cuestiones relacionadas