Nous avons un programme d'installation basé sur MSI qui a récemment cessé de fonctionner dans un environnement Windows 2008 R2. Le programme d'installation est copié sur l'ordinateur cible à l'aide des partages UNC d'administrateur \\servername\c$\
, puis exécuté à distance à l'aide de la méthode create de la classe WMI Win32_Process . L'exécution à distance échoue maintenant avec le message d'erreur suivant dans l'observateur d'événements:
La description de l'ID d'événement 10837 à partir de la source MsiInstaller ne peut pas être a trouvé. Soit le composant qui déclenche cet événement n'est pas installé sur votre ordinateur local ou l'installation est corrompue. Vous pouvez installer ou réparer le composant sur l'ordinateur local.
Si l'événement provient d'un autre ordinateur, les informations d'affichage devait être sauvé avec l'événement.
Les informations suivantes ont été incluses avec l'événement:
Produit: NOTRE NOM DE PRODUIT - L'opération demandée ne peut pas être completé. L'ordinateur doit être approuvé pour la délégation et le fichier Le compte d'utilisateur actuel doit être configuré pour autoriser la délégation.
Après une recherche, il semble que cela soit causé par un correctif de sécurité récemment publié pour Windows Installer . Lorsque je désinstalle KB2918614, le programme d'installation recommence à fonctionner et si je réinstalle KB2918614 le MSI cesse de fonctionner.
Le message d'erreur indique que, pour résoudre le problème, un administrateur de domaine devrait modifier l'ordinateur cible à l'aide de Utilisateurs et ordinateurs Active Directory pour autoriser la délégation. Toutefois, le MSI n'utilise PAS de ressources distantes. voir pourquoi cela est nécessaire. Le même processus d'exécution MSI et à distance fonctionne correctement sous Windows Server 2012; je me demande donc s'il s'agit d'un problème lié au correctif pour 2008 R2.
Existe-t-il d'autres moyens de contourner ce message d'erreur?
UPDATE: cela ne semble pas poser de problème avec l'exécution à distance de WMI, car il se produit également lorsque nous essayons d'installer le MSI à distance à l'aide de Powershell, WinRM et de la cmdlet Invoke-Commmand -ComputerName TargetComputer ...
. Après l’installation de KB2918614, le programme d’installation de Windows Installer pour 2008 R2 a été modifié. Il empêche désormais l’action personnalisée d’achever sa tâche.
D'après ce que j'ai compris,
Avec KB2918614, MS a apparemment essayé de réparer quelque chose dans le service Windows Installer.
Et, dans cette comparaison, pour une raison quelconque, ces inadéquations! (Trouvé ceux-ci dans les journaux MSI prolixes).
Une fois que cela échoue, il cherche Valeur de stratégie de l'ordinateur 'AlwaysInstallElevated' Valeur de la stratégie utilisateur 'AlwaysInstallElevated'
Désormais, si vous exécutez une installation silencieuse "qn", cette erreur est générée: MSI_LUA: l'invite d'élévation est désactivée pour les installations silencieuses.
Mon MSI est gravé via un fichier bootstrapper. Mais ce n'est pas grave. Même un appel manuel à msiexec via la ligne cmd se comporte de la même manière.
Des entrées/solutions, quelqu'un?
Voici ma façon automatique d’utiliser la liste blanche de registre mentionnée sur le site de Microsoft.
Maintenant, avant d'exécuter ma commande d'installation sur une machine distante, je regarde le fichier MSI, extrait le code produit avec Get-ProductCodeFromMSI, puis j'utilise Add-GuidToWhitelist pour ajouter chaque GUID à la liste de cet ordinateur. Voici un exemple:
$guids = Get-ChildItem -Path D:\somefolder -filter "*.msi" -recurse | % {Get-ProductCodefromMSI $_.FullName}
Add-GUIDtoWhiteList -computername "SomeServer" -GUIDs $guids
Avant de faire cela, chaque machine peut être testée et réparée pour la solution de contournement en utilisant respectivement Test-SecureRepairPolicy et Repair-SecureRepairPolicy.
Get-ProductCodeFromMSI nécessitera que la DLL référencée soit placée quelque part et débloquée - cette DLL puisse être extraite du jeu d'outils Wix.
Le code pour les fonctions que je référence est ici:
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'")
}
C'est le mot des gens du support technique MS Enterprise.
Apparemment, ils ne sont au courant d'aucune solution à ce problème. Du moins, à partir de maintenant ... Tout ce qu'ils disent c'est que cette base de connaissances vise à corriger une échappatoire en matière de sécurité ... Je ne comprends pas quel type de correctif de sécurité c'est ce qui permet une nouvelle installation sans UAC Invite, mais envoie une invite UAC uniquement pour la mise à niveau.
Solution 1: Distribution du hachage.
Capturez le fichier de hachage * sur un ordinateur et distribuez-le sur d’autres ordinateurs . Les fichiers de hachage sont créés dans le répertoire «% windir%\installer». La convention de dénomination est la suivante: «SourceHash * Ce fichier est créé uniquement lorsqu'un produit est installé avec KB2918614 sur la machine. Ce répertoire est masqué. Ouvrez l'invite cmd en utilisant "Exécuter en tant qu'administrateur". Parcourez ce chemin et ouvrez le dossier à l'aide de "Explorer". command . [Je ne pouvais pas résoudre le problème avec cette approche - cela peut être parce que l'accès à ce répertoire nécessite des privilèges d'administrateur que Windows Installer lui-même pourrait ne pas avoir]
Solution 2: Liste blanche.
Ce n’est que si vous faites confiance à l’application qu’elle est toujours signée numériquement et ne contient aucun contenu malveillant (même à l’avenir).
Étape 1: Activer la liste blanche
Sous la clé «HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer», créez un DWORD: «SecureRepairPolicy» et définissez sa valeur sur 2.
Étape 2: Ajouter l'application à la liste blanche
Créez une nouvelle clé “SecureRepairWhitelist” sous “HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer” et créez StringValues avec les codes produit (y compris les supports de fleurs {}) du produit.
... Malheureusement, ces deux solutions nécessitent des privilèges d'administrateur!
Je rencontre aussi le problème. J'ai eu le script PowerShell pour installer MSI sur des machines distantes (à l'aide de l'applet de commande Invoke-Command et fournir les informations d'identification avec le script), mais du coup, l'installation de MSI a échoué, ce qui, je suppose, provient également de ce correctif de sécurité.
Après avoir exécuté manuellement le fichier d'installation MSI sur la machine cible à l'aide du compte de domaine (à partir du bureau distant), le script powershell peut soudainement exécuter l'installation MSI à l'aide du compte de domaine, mais ne parvient toujours pas à installer si j'ai utilisé le compte d'administrateur local de la machine cible.
Je préfère ajouter ceci comme commentaire, mais je n’ai pas assez de représentants pour le faire. Si l'autre a une solution ou une explication à cela, j'aimerais bien le savoir aussi. Merci.
J'ai le même problème. Échec d'installation des MSI avec Invoke-Command PoSH. J'ai constaté que si j'installe n'importe quel fichier MSI sur le serveur localement sous le même compte utilisé pour Invoke-Command, le problème est résolu et Invoke-Command commence à fonctionner normalement.
Cela doit être fait avec les fichiers SourceHash {code-produit} dans le répertoire\windows\installer. Ce fichier peut être ouvert avec Orca, vous pouvez en lire le contenu. Il contient un nom de fichier, un spécificateur d'algorithme de hachage et un hachage. Sous Windows 2k3, ce hachage est un hachage sha256 en base64 avec le dernier octet modifié.
Si vous renommez le fichier SourceHash de votre produit , j'ai constaté que la mise à niveau fonctionnait correctement et qu'un nouveau fichier SourceHash est généré. Vous pouvez ensuite différencier les deux fichiers de hachage source. Dans le cas sur lequel je suis en train d’enquêter, lorsque vous comparez les deux fichiers, seul le hachage indiqué pour le fichier msi original est différent. Après une mise à niveau réussie, le hachage du nouveau MSI répertorié dans le fichier de hachage source correspond à celui de la source d'installation. Le fichier sourcehash cassé a évidemment été généré à partir d’un MSI source modifié/différent, bien que je n’ai pas encore pu identifier lequel.
Réponse de Microsoft: Cette mise à jour de sécurité corrige une vulnérabilité révélée confidentiellement dans Microsoft Windows. Cette vulnérabilité pourrait permettre une élévation de privilèges si un attaquant exécutait une application spécialement conçue qui tentait de réparer une application précédemment installée. Un attaquant doit disposer d'informations d'identification de connexion valides et pouvoir se connecter localement pour exploiter cette vulnérabilité.
Désinstallez l'application et réinstallez-la avec la mise à jour de sécurité installée. (fichier sourcehash généré avec la mise à jour de sécurité)
Copiez manuellement le fichier sourcehash dans le dossier c:\windows\installer. Comme le fichier sourcehash est généré sur la base des fichiers de l’application, le fichier sourcehash généré sur l’ordinateur A peut être utilisé sur l’ordinateur B.
http://happysccm.com/kb2918614-uac-gate/ - commandes pour le désinstaller.
Si vous exécutez via psexec, le simple ajout de l'argument -s résout également l'erreur. Ensuite, il est exécuté en tant qu'utilisateur système distant et le contrôle de compte d'utilisateur n'est pas requis.
J'ai eu cela aussi sur différents serveurs. Après quelques heures de fouilles, j'ai découvert qu'ils ne pouvaient pas atteindre les contrôleurs de domaine. Vérifiez vos paramètres DNS et assurez-vous qu'ils peuvent atteindre l'AD. Après avoir résolu ce problème, cette erreur a disparu.