最近Windows 2008 R2環境での動作を停止したMSIベースのインストーラーがあります。インストーラーは、\\servername\c$\
admin UNC共有を使用してターゲットコンピューターにコピーされ、 WMI Win32_Processクラス のcreateメソッドを使用してリモートで実行されます。リモート実行が失敗し、イベントビューアに次のエラーメッセージが表示されるようになりました。
ソースMsiInstallerからのイベントID10837の説明が見つかりません。このイベントを発生させるコンポーネントがローカルコンピューターにインストールされていないか、インストールが破損しています。コンポーネントをローカルコンピューターにインストールまたは修復できます。
イベントが別のコンピューターで発生した場合、表示情報をイベントと共に保存する必要がありました。
イベントには以下の情報が含まれていました。
製品:当社の製品名-要求された操作を完了できません。コンピューターは委任について信頼されている必要があり、現在のユーザーアカウントは委任を許可するように構成されている必要があります。
検索したところ、これは最近リリースされたWindowsインストーラー用の セキュリティパッチが原因であるようです 。 KB2918614をアンインストールすると、インストーラーが再び動作し始めます KB2918614 を再インストールすると、MSIが再び動作しなくなります。
エラーメッセージは、問題を解決するには、ドメイン管理者に Active Directoryユーザーとコンピューター を使用してターゲットコンピューターを編集させ、委任を許可する必要があることを示していますが、MSIはリモートリソースなので、なぜこれが必要なのかわかりません。同じMSIとリモート実行プロセスがWindowsServer 2012で正常に機能するため、これが2008R2のパッチの問題であるかどうか疑問に思います。
このエラーメッセージを回避する他の方法はありますか?
[〜#〜] update [〜#〜]:これは、WMIリモート実行の問題ではないようです。 Powershell、WinRM、およびInvoke-Commmand -ComputerName TargetComputer ...
コマンドレットを使用してMSIをリモートでインストールします。 KB2918614をインストールした後、2008 R2のWindowsインストーラーの動作方法に変更があり、カスタムアクションがそのタスクを完了できなくなりました。
私の理解から、
MSはKB2918614を使用して、Windowsインストーラサービスの何かを修正しようとしたようです。
そして、この比較では、何らかの理由で、これらの不一致! (これらはMSIの詳細ログで見つかりました)。
これが失敗すると、マシンポリシー値 'AlwaysInstallElevated'ユーザーポリシー値 'AlwaysInstallElevated'を検索します
これで、サイレントインストール「qn」を実行している場合、次のエラーがスローされます。
私のMSIは、ブートストラップexeによってivkodedされています。しかし、それは本当に重要ではありません。 cmd行を介したmsiexecの手動呼び出しでも、同じように動作します。
入力/ソリューション、誰か?
これは、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参照をどこかに配置する必要がありますおよびブロック解除-this 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'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'")
}
これはMSエンタープライズサポートの人々からの言葉です。
どうやら彼らはこれに対する修正を認識していません。現在、少なくとも。彼らが言っているのは、このKBはセキュリティの抜け穴を修正することです。これがどのようなセキュリティ修正であるかわかりません。UACプロンプトなしでフレッシュインストールを許可しますが、アップグレードに対してのみUACプロンプトをスローします。
回避策1:ハッシュの配布
1つのマシンでハッシュファイル*をキャプチャし、他のマシンに配布します。ハッシュファイルは「%windir%\ installer」ディレクトリの下に作成されます。命名規則は次のとおりです。「SourceHash *このファイルは、製品がインストールされ、マシンにKB2918614がインストールされている場合にのみ作成されます。このディレクトリは非表示です。 「管理者として実行」を使用してcmdプロンプトを開きます。このパスに移動し、「Explorer」を使用してフォルダーを開きます。コマンド。 [このアプローチを使用して問題を解決できませんでした-このディレクトリにアクセスするには、Windowsインストーラ自体にはない管理者権限が必要なためかもしれません]
回避策2:ホワイトリスト
常にデジタル署名されており、悪意のあるものが含まれていない(将来においても)アプリケーションを信頼している場合のみ。
ステップ1:ホワイトリストを有効にする
キー「HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer」の下に、DWORD「SecureRepairPolicy」を作成し、その値を2に設定します。
ステップ2:アプリケーションをホワイトリストに追加
「HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer」の下に新しいキー「SecureRepairWhitelist」を作成し、製品の製品コード(花のブラケット{}を含む)を含むStringValuesを作成します。
...残念ながら、これらの回避策には両方とも管理者権限が必要です。
私もこの問題に遭遇します。リモートマシンにMSIをインストールするためのPowerShellスクリプトを入手しました(Invoke-Commandコマンドレットを使用して、スクリプトと一緒に資格情報を提供します)が、突然、このセキュリティパッチからも推測されるMSIのインストールに失敗しました。
ドメインアカウントを使用して(リモートデスクトップから)ターゲットマシンでMSIインストールファイルを手動で実行した後、突然、PowerShellスクリプトがドメインアカウントを使用してMSIインストールを実行できるようになりましたが、ターゲットマシンのローカル管理者を使用した場合でもインストールに失敗しましたアカウント。
コメントとして追加したいのですが、それを行うのに十分な担当者がいません。他の人がこれに対する解決策や説明を持っている場合は、それも知りたいです。ありがとう。
私も同じ問題を抱えてる。 MSIは、Invoke-Command PoSHでインストールできませんでした。 Invoke-Commandに使用されているのと同じアカウントでサーバーにMSIをローカルにインストールすると、問題が修正され、Invoke-Commandが通常どおり機能し始めることがわかりました。
これは、\ windows\installerディレクトリの下にあるSourceHash {product-code}ファイルと関係があります。このファイルはOrcaで開くことができ、内容を読み取ることができます。これには、ファイル名、ハッシュアルゴリズム指定子、およびハッシュが含まれています。 Windows 2k3では、このハッシュはbase64化されたsha256ハッシュであり、最後のバイトが変更されています。
製品のSourceHashファイルの名前を邪魔にならないように変更の場合、アップグレードが機能していることがわかり、その後、新しいSourceHashファイルが生成されます。次に、2つのソースハッシュファイルを比較できます。私が調査している場合、2つのファイルを比較すると、元のmsiにリストされているハッシュのみが異なります。アップグレードが成功すると、ソースハッシュファイルにリストされている新しいmsiのハッシュがインストールソースのハッシュと一致します。壊れたsourcehashファイルは明らかに変更された/異なるソースMSIから生成されましたが、まだ特定できていません。
マイクロソフトからの応答:このセキュリティ更新プログラムは、非公開で公開されたMicrosoft Windowsの脆弱性を解決します。この脆弱性により、攻撃者が特別に細工したアプリケーションを実行して、以前にインストールしたアプリケーションを修復しようとすると、特権が昇格される可能性があります。この脆弱性を悪用するには、攻撃者は有効なログオン資格情報を所持し、ローカルでログオンできる必要があります。
アプリケーションをアンインストールし、セキュリティアップデートをインストールして再インストールします。 (セキュリティアップデートで生成されたsourcehashファイル)
Sourcehashファイルをc:\ windows\installerフォルダーに手動でコピーします。ソースハッシュファイルはアプリケーションファイルに基づいて生成されるため、コンピューターAで生成されたソースハッシュファイルをコンピューターBで使用できます。
http://happysccm.com/kb2918614-uac-gate/ -アンインストールするコマンド。
Psexecを介して実行している場合は、-s引数を追加するだけでエラーも解決します。次に、リモートシステムユーザーとして実行され、UACは必要ありません。
私もこれを別のサーバーに持っていました。数時間掘り下げた後、ドメインコントローラーに到達できないことがわかりました。 DNS設定をチェックして、ADに到達できることを確認してください。これを修正した後、このエラーは消えました。