Ошибка MSI "Компьютер должен быть доверен для делегирования", вызванный KB2918614

У нас есть установщик на базе MSI, который недавно перестал работать в среде Windows 2008 R2. Установщик копируется на целевой компьютер с использованием общих ресурсов \\servername\c$\ admin UNC, а затем удаленно выполняется с использованием метода create в классе WMI Win32_Process. Удаленное выполнение теперь не выполняется со следующим сообщением об ошибке в средстве просмотра событий:

Описание для Event ID 10837 из источника MsiInstaller не может быть найденный. Либо компонент, который повышает это событие, не установлен на ваш локальный компьютер или установка повреждена. Вы можете установить или отремонтировать компонент на локальном компьютере.

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

В мероприятии была включена следующая информация:

Продукт: НАШИМ НАЗВАНИЕ ПРОДУКТА - Запрошенная операция не может будет завершена. Компьютер должен быть доверен для делегирования, а текущая учетная запись пользователя должна быть настроена для делегирования.

После поиска похоже, что это вызвано недавно выпущенным патчем для защиты для установщика Windows. Когда я удалю KB2918614, программа установки снова начнет работать, и если я переустановит KB2918614, MSI перестанет работать снова.

Сообщение об ошибке указывает, что для решения проблемы нам необходимо было бы, чтобы администратор домена редактировал целевой компьютер с помощью "Пользователи и компьютеры Active Directory" , чтобы разрешить делегирование, однако MSI НЕ использует удаленные ресурсы, поэтому я не понимаю, почему это требуется. Тот же процесс MSI и удаленного выполнения отлично работает в Windows Server 2012, поэтому я задаюсь вопросом, является ли это проблемой с патчем для 2008 R2.

Есть ли другие способы обойти это сообщение об ошибке?

ОБНОВЛЕНИЕ. Это не проблема с удаленным выполнением WMI, как это происходит, когда мы пытаемся установить MSI удаленно с помощью командлета Powershell, WinRM и Invoke-Commmand -ComputerName TargetComputer .... Существует изменение в том, как работает установщик Windows в 2008 R2 после установки KB2918614, который теперь запрещает выполнение пользовательским действием задачи.

Ответ 1

Из того, что я понимаю,

С KB2918614 MS, похоже, попыталась что-то исправить в службе установщика Windows.

Новый материал:

  • Они создают файл по имени "SourceHash {PRODUCT-GUID}" под % Windir%\Windows\Installer. Это делается для каждого установленного продукта на машине (с уже установленным KB2918614).
  • SECREPAIR- Они вычисляют "Сохраненное значение хеша" и "Текущий хэш" для данного MSI.

Ошибка:

  • И, в этом сравнении, почему-то это несоответствие! (Найдено их в подробных журналах MSI).

  • Как только это не удается, он ищет   Значение политики машины "AlwaysInstallElevated"   Значение политики пользователя "AlwaysInstallElevated"

  • Теперь, если вы используете тихую установку "qn", эта ошибка вызывается: MSI_LUA: приглашение на высоту отключено для бесшумных установок.

  • Удаление опции молчания install cmdline для msiexec-ex., "qr" или "qb" приведет к вызову UAC. (что, скорее всего, не будет ожидаемым поведением).

Дополнительная информация:

Мой MSI ivkoded через загрузочный exe. Но это не имеет большого значения. Даже ручной вызов линии msiexec через cmd ведет себя одинаково.

Любые входы/решения, кто-нибудь?

Ответ 2

Это слово от пользователей поддержки MS Enterprise.

По-видимому, они не знают об этом. По крайней мере, на данный момент. Все они говорят, что этот КБ должен исправить лазейку безопасности. Я не понимаю, что это за исправление безопасности, которое позволяет обновить установку без приглашения UAC, но выдает приглашение UAC только для обновления.

Обходной путь 1: Распределение хешей.

Захватите хэш файл * на одной машине и распространите их на другие машины. Хэш файлы создаются в каталоге "% windir%\installer". Соглашение об именах выглядит следующим образом: "SourceHash * Этот файл создается только в том случае, если на компьютере установлен продукт с установленным KB2918614. Этот каталог скрыт. Откройте приглашение cmd с помощью "run as administrator". Перейдите к этому пути и откройте папку с помощью "explorer". команда. [Я не мог решить проблему с использованием этого подхода, возможно, потому, что для доступа к этому каталогу требуются права администратора, которые сам установщик Windows не может иметь]

Обходной путь 2: Белый список.

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

Шаг 1: Включить белый список

В разделе "HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer" создайте DWORD: "SecureRepairPolicy" и установите значение "2".

Шаг 2: добавьте приложение в белый список

Создайте новый ключ "SecureRepairWhitelist" в разделе "HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer" и создайте StringValues ​​с кодами продуктов (включая цветочные скобки {}) продукта.

... К сожалению, обе эти обходные пути нуждаются в привилегиях администратора!

Ответ 3

Вот мой автоматический способ использования работы с белым списком реестра, упомянутого на сайте Microsoft.

Теперь, прежде чем я запустил свою команду установки на удаленную машину, я посмотрю на MSI и извлечу код продукта с помощью Get-ProductCodeFromMSI, а затем с помощью Add-GuidToWhitelist добавит каждый GUID в список на этом компьютере. Вот пример:

$guids = Get-ChildItem -Path D:\somefolder -filter "*.msi" -recurse | % {Get-ProductCodefromMSI $_.FullName}
Add-GUIDtoWhiteList -computername "SomeServer" -GUIDs $guids

Прежде чем это сделать, каждую машину можно протестировать и отремонтировать для обходного пути, используя Test-SecureRepairPolicy и Repair-SecureRepairPolicy, соответственно.

Get-ProductCodeFromMSI потребует, чтобы DLL была помещена где-то и разблокирована. Эта DLL может быть получена из набора инструментов Wix.

Код для функций, которые я ссылаюсь здесь:

Function Test-SecureRepairPolicy{
    param (
        [Parameter(mandatory=$true,ValueFromPipelineByPropertyName=$true)][string[]]
        # Specifies the computer name to connect to
        $ComputerName
    )

    Process {
        foreach ($Computer in $ComputerName)
        {
            #Open Remote Base
            $reg=[microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',$Computer)
            #Get Windows key
            $subkey = $reg.OpenSubKey("SOFTWARE\Policies\Microsoft\Windows")
            $subkeynames = $subkey.GetSubKeyNames()
            if (($subkeynames | Measure-Object).Count -lt 1){
                return New-Object -type PSObject -Property @{
                    Success = $False
                    Note = "Can not open base key"
                    ComputerName = $Computer
                }
            }
            if ($subkeynames -notcontains "Installer"){
                return New-Object -type PSObject -Property @{
                    Success = $False
                    Note = "Can not locate installer subkey"
                }
            }
            $subkey.Close();$subkey = $null
            $subkey = $reg.OpenSubKey("SOFTWARE\Policies\Microsoft\Windows\Installer")
            $subkeynames = $subkey.GetSubKeyNames()
            if ($subkeynames -notcontains "SecureRepairWhitelist"){
                return New-Object -type PSObject -Property @{
                    Success = $False
                    Note = "Can not locate repairlist subkey"
                    ComputerName = $Computer
                }
            }
            $repairvalue = $subkey.GetValue("SecureRepairPolicy")
            if ($repairvalue -ne 2){
                return New-Object -type PSObject -Property @{
                    Success = $False
                    Note = "SecureRepairPolicy is incorrect"
                    ComputerName = $Computer
                }
            }
            $subkey.Close();$subkey = $null;$reg.Close();$reg = $null
            return New-Object -type PSObject -Property @{
                Success = $True
                Note = "SecureRepairPolicy structure is in place"
                ComputerName = $Computer
            } 
        }
    }
}

Function Repair-SecureRepairPolicy{
    param (
        [Parameter(mandatory=$true,ValueFromPipelineByPropertyName=$true)][string[]]
        # Specifies the computer name to connect to
        $ComputerName

    )
    Begin{
        Function Add-RemoteRegistryKey($Computer,$Parent,$Name){
            $reg=[microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',$Computer)
            $subkey = $reg.OpenSubKey($Parent, $true)
            $subkey.CreateSubKey($Name)
            $subkey.Close();$subkey = $null;$reg.Close();$reg = $null
        }
        Function Add-InstallerKey($Computer){
           Add-RemoteRegistryKey $Computer "SOFTWARE\Policies\Microsoft\Windows" "Installer" 
        }
        Function Add-RepairPolicy($Computer){
            $reg=[microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',$Computer)
            $subkey = $reg.OpenSubKey("SOFTWARE\Policies\Microsoft\Windows\Installer", $true)
            $subkey.SetValue("SecureRepairPolicy",2, "DWORD")
            $subkey.Close();$subkey = $null;$reg.Close();$reg = $null
        }
        Function Add-WhitelistKey($Computer){
            Add-RemoteRegistryKey $Computer "SOFTWARE\Policies\Microsoft\Windows\Installer" "SecureRepairWhitelist"
        }

    }
    Process {
        foreach ($Computer in $ComputerName)
        {
            $audit = Test-SecureRepairPolicy $computer
            if ($audit.Success){
                Write-Output "Repair whitelist keys setup.  No repair being performed."
            }
            else{
                Write-Output "Repair whitelist keys not setup.  Attempting to resolve"
                 if ($audit.Note -match "Can not open base key"){
                    Write-Error "Unable to open computer registry key"
                    return
                 }
                 if ($audit.Note -match "Can not locate installer subkey"){
                    Add-Installerkey $Computer
                    Add-RepairPolicy $Computer
                    Add-WhitelistKey $Computer
                 }
                 if ($audit.Note -match "Can not locate repairlist subkey"){
                    Add-RepairPolicy $Computer
                    Add-WhitelistKey $Computer
                 }
                 if ($audit.Note -match "Can not locate repairlist subkey"){
                    Add-RepairPolicy $Computer
                 }
                 Write-Output "Showing new audit"
                 Test-SecureRepairPolicy $computer
            }
        }
    }
}

Function Add-GUIDtoWhiteList{
    param (
        [Parameter(mandatory=$true,ValueFromPipelineByPropertyName=$true)][string[]]
        # Specifies the computer name to connect to
        $ComputerName,
        [Parameter(mandatory=$true)][string[]]
        # Specifies the GUID(s) to add.
        $GUIDs
    )

    Process {
        foreach ($Computer in $ComputerName)
        {
            #Open Remote Base
            $reg=[microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',$Computer)
            $subkey = $reg.OpenSubKey("SOFTWARE\Policies\Microsoft\Windows\Installer\SecureRepairWhitelist", $true)
            foreach($GUID in $GUIDs){
                $subkey.SetValue($GUID,"", "String")
            }
            $subkey.Close();$subkey = $null;$reg.Close();$reg = $null
        }
    }
}

Function Get-ProductCodefromMSI ($msi){
    [Reflection.Assembly]::LoadFrom("D:\scripts\lib\Microsoft.Deployment.WindowsInstaller.dll") | out-null
    (New-Object -TypeName Microsoft.Deployment.WindowsInstaller.Database -ArgumentList $msi).ExecuteQuery("SELECT Value FROM Property WHERE Property = 'ProductCode'")
}

Ответ 4

Я также сталкиваюсь с проблемой. Я получил powershell script для установки MSI на удаленных компьютерах (с помощью командлета Invoke-Command и предоставления учетных данных вместе с script), но внезапно ему не удалось установить MSI, который, как я полагаю, также и из этого исправления безопасности.

После запуска файла установки MSI вручную на целевом компьютере с использованием учетной записи домена (с удаленного рабочего стола) неожиданно Powerwill script может запустить установку MSI с использованием учетной записи домена, но все равно не удалось установить, если я использовал учетную запись локального администратора целевой машины.

Я предпочитаю добавлять это в качестве комментария, но мне не хватает репутации для этого. Если у другого есть какое-то решение или объяснение, я тоже хотел бы это узнать. Спасибо.

Ответ 5

Это должно быть связано с файлами SourceHash {product-code} в каталоге \windows\installer. Этот файл можно открыть с помощью Orca, вы можете прочитать содержимое. Он содержит имя файла, спецификатор алгоритма хэша и хэш. В Windows 2k3 этот хэш - это base64ed sha256 hash с последним байтом.

Если вы переименуете файл SourceHash для своего продукта в сторону, я обнаружил, что обновление выполнено, и после этого создается новый файл SourceHash. Затем вы можете разделить два хэш файла источника. В случае, когда я исследую, когда вы меняете два файла, только хэш, указанный для исходного msi, отличается. После успешного обновления хэш нового msi, указанного в исходном хеш файле, будет соответствовать настройке источника установки. Сломанный файл sourcehash, очевидно, был сгенерирован из модифицированного/другого источника MSI, хотя я пока не смог определить, какой из них.

Ответ 6

У меня та же проблема. MSI не удалось установить с помощью команды Invoke-Command PoSH. Я обнаружил, что если я устанавливаю MSI на сервере локально под той же учетной записью, которая используется для Invoke-Command, проблема исправлена, и Invoke-Command начинает работать как обычно.

Ответ 7

Ответ Microsoft: Это обновление для системы безопасности устраняет уязвимость в Microsoft Windows. Уязвимость может позволить повысить привилегию, если злоумышленник запускает специально созданное приложение, которое пытается восстановить ранее установленное приложение. Злоумышленник должен иметь действительные учетные данные для входа и иметь возможность локально локально использовать эту уязвимость.

Обходной путь, если у вас возникли проблемы с ремонтом приложения:

  • Удалите приложение и переустановите его с установленным обновлением безопасности. (файл-источник, сгенерированный с обновлением безопасности)

  • Вручную скопируйте файл sourcehash в папку c:\windows\installer. Поскольку файл sourcehash создается на основе файлов приложений, файл sourcehash, сгенерированный на компьютере A, можно использовать на компьютере B.

  • http://happysccm.com/kb2918614-uac-gate/ - команды для его удаления.

Ответ 8

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

Ответ 9

Если вы выполняете psexec, просто добавление аргумента -s также устраняет ошибку. Затем он запускается как пользователь удаленной системы и UAC не требуется.