Windows installer MSI错误“;必须信任计算机进行委派”;由KB2918614引起
我们有一个基于MSI的安装程序,该安装程序最近停止在Windows 2008 R2环境下工作。使用Windows installer MSI错误“;必须信任计算机进行委派”;由KB2918614引起,windows-installer,wmi,windows-server-2008-r2,Windows Installer,Wmi,Windows Server 2008 R2,我们有一个基于MSI的安装程序,该安装程序最近停止在Windows 2008 R2环境下工作。使用\\servername\c$\管理UNC共享将安装程序复制到目标计算机上,然后使用上的create方法远程执行。远程执行现在失败,事件查看器中显示以下错误消息: 无法删除源MSInstaller中事件ID 10837的说明 建立引发此事件的组件未安装在上 您的本地计算机或安装已损坏。您可以安装 或修复本地计算机上的组件 如果事件起源于另一台计算机,则显示信息 必须与事件一起保存 本次活动包括以下信
\\servername\c$\
管理UNC共享将安装程序复制到目标计算机上,然后使用上的create方法远程执行。远程执行现在失败,事件查看器中显示以下错误消息:
无法删除源MSInstaller中事件ID 10837的说明
建立引发此事件的组件未安装在上
您的本地计算机或安装已损坏。您可以安装
或修复本地计算机上的组件
如果事件起源于另一台计算机,则显示信息
必须与事件一起保存
本次活动包括以下信息:
产品:我们的产品名称--无法执行请求的操作
完成。必须信任计算机进行委派,并且
当前用户帐户必须配置为允许委派
经过搜索,这似乎是由最近发布的。当我卸载KB2918614时,安装程序再次开始工作,如果我重新安装MSI,它将再次停止工作
错误消息表明,要解决此问题,我们必须让域管理员使用编辑目标计算机以允许委派,但是MSI没有使用任何远程资源,因此我不明白为什么需要这样做。同样的MSI和远程执行过程在Windows Server 2012上运行良好,所以我想知道这是否是2008 R2修补程序的问题
是否有其他方法可以绕过此错误消息
更新:WMI远程执行似乎没有问题,因为当我们尝试使用Powershell、WinRM和
Invoke Commmand-ComputerName TargetComputer…
cmdlet远程安装MSI时,也会出现这种情况。安装KB2918614后,2008 R2上的Windows Installer的工作方式发生了变化,现在阻止自定义操作完成其任务。我也遇到了这个问题。我使用powershell脚本在远程计算机上安装MSI(使用Invoke Command cmdlet并随脚本一起提供凭据),但它突然无法安装MSI,我想这也是通过此安全修补程序安装的在使用域帐户(从远程桌面)在目标计算机上手动运行MSI安装文件后,powershell脚本突然可以使用域帐户运行MSI安装,但如果使用目标计算机本地管理员帐户,则仍然无法安装
我更愿意将此作为评论添加,但我没有足够的代表来做这件事。如果对方对此有任何解决方案或解释,我也想知道。谢谢。微软回复: 此安全更新解决了Microsoft Windows中私下披露的漏洞。如果攻击者运行巧尽心思构建的应用程序试图修复以前安装的应用程序,则该漏洞可能允许提升权限。攻击者必须具有有效的登录凭据并能够在本地登录才能利用此漏洞进行攻击 解决方法如果您在修复应用程序时遇到问题:
据我了解, 通过KB2918614,微软显然试图修复Windows Installer服务中的某些问题 新材料:
- 他们正在下面创建一个名为“SourceHash{PRODUCT-GUID}”的文件 %windir%\Windows\Installer。这是为每个安装的产品完成的 在机器上(已安装KB2918614)
- SECREPAIR-他们正在计算给定MSI的“存储哈希值”和“当前哈希”
有任何输入/解决方案吗?这与\windows\installer目录下的SourceHash{product code}文件有关。 可以使用Orca打开此文件,您可以读取其中的内容。它包含文件名、哈希算法说明符和哈希。在Windows 2k3上,此哈希是最后一个字节已更改的基于64的sha256哈希 如果您为您的产品重命名SourceHash文件,我发现升级工作正常,之后会生成一个新的SourceHash文件。然后可以区分两个源哈希文件。在我正在调查的案例中,当您区分这两个文件时,只有为原始msi列出的哈希是不同的。
成功升级后,源哈希文件中列出的新msi的哈希将与安装源的哈希匹配。断开的sourcehash文件显然是由一个修改过的/不同的源MSI生成的,尽管我还无法确定是哪个MSI。这是来自MS Enterprise支持人员的单词 显然,他们不知道有什么办法可以解决这个问题。至少到目前为止。 他们所说的一切
$guids = Get-ChildItem -Path D:\somefolder -filter "*.msi" -recurse | % {Get-ProductCodefromMSI $_.FullName}
Add-GUIDtoWhiteList -computername "SomeServer" -GUIDs $guids
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's 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'")
}