Как запустить установщик Windows и получить значение успешного / неудачного завершения в PowerShell? - PullRequest
11 голосов
/ 20 января 2011

Я хотел бы установить набор приложений: .NET 4, IIS 7 PowerShell оснастки, ASP.NET MVC 3 и т. Д.Как получить приложения для установки и вернуть значение, определяющее, была ли установка успешной или нет?

Ответы [ 4 ]

18 голосов
/ 18 августа 2011

Все эти ответы кажутся либо слишком сложными, либо недостаточно полными. Запуск установщика в консоли PowerShell имеет несколько проблем. MSI запускается в подсистеме Windows , поэтому вы не можете просто вызвать их (Invoke-Expression или &). Некоторые люди утверждают, что эти команды работают, передавая по трубопроводу Out-Null или Out-Host, но я не заметил, чтобы это работало.

Метод, который работает для меня, - Start-Process с параметрами установки без вывода сообщений на 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

Вы можете получить код выхода из команды Start-Process и проверить его на наличие значений «годен / нет». (а здесь ссылка на код выхода )

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

if($p.ExitCode -ne 0)
{
    throw "Installation process returned error code: $($p.ExitCode)"
}
3 голосов
/ 20 января 2011

msi также можно установить с помощью msiexec.exe, msu можно установить с помощью wusa.exe, оба имеют переключатель /quiet, /norestart и /forcerestart и параметр /log для ведения журнала (укажите файлname).

Подробнее о параметрах можно прочитать, если вызвать их с помощью /?

Примечание. При сбое wusa молча завершается сбоем, поэтому необходимо проверить файл журнала или журнал событий, чтобыопределить успех.

3 голосов
/ 20 января 2011

Зависит.MSI могут быть установлены с использованием WMI.Для exes и других методов вы можете использовать Start-Process и проверить Process ExitCode.

0 голосов
/ 02 марта 2011

Я реализовал именно то, что вы ищете в моем текущем проекте. Нам необходимо автоматизировать развертывание и внедрение n приложений в нескольких средах и центрах обработки данных. Эти сценарии немного изменены по сравнению с оригинальной версией для простоты, поскольку мой полный код достигает 1000 строк, но основная функциональность не нарушена. Я надеюсь, что это делает то, что вы просите.

Эта функция PS извлекает все приложения из реестра (что считывает добавление / удаление программ), а затем выполняет поиск по предоставленному имени приложения и отображаемой версии. В моем коде (PSM1) я запускаю эту функцию перед установкой, чтобы определить, является ли она их, а затем послесловие, чтобы убедиться, что она установлена…. Все это можно обернуть в одну ведущую функцию для управления потоками менеджера.

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

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

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

Файл TXT должен быть отформатирован как таковой ... вам нужно будет выяснить, как нужно устанавливать каждое приложение. хороший ресурс appdeploy.com

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

Дайте мне знать, если возникнут какие-либо ошибки, мне пришлось изменить существующий код, чтобы удалить собственные значения и сделать это немного более упрощенным. Я извлекаю свои значения из пользовательского листа ответов XML. Но этот код должен работать так, как я его предоставил.

Если вы хотите, чтобы я подробнее рассказал о моей реализации, дайте мне знать, и я смогу сделать более подробное объяснение, а также добавить дополнительные функции поддержки, которые я реализовал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...