VDA update – 7.7 to 7.8 – Impossible d’installer ICATS_x64 [XDML :611b8615 ]

Lors de la mise à jour vers XD 7.8, nous avons eu le droit à « impossible d’installer le VDA », le journal d’installation nous indique:
– erreur 1603 lors de l’installation de ICATS_x64
En regardant de plus près le fichier de log de l’installation MSI de ICATS_x64, nous trouvons l’erreur explicitement :
– Product: Citrix HDX TS (retail) — Error 1402. Could not open key: HKEY_LOCAL_MACHINE32\SOFTWARE\Citrix\EUEM\LoggedEvents. System error 5. Verify that you have sufficient access to that key, or contact your support personnel.

Ok, vérifions ça !

loggedevents
autorisation

Nous avons donc besoin de change le propriétaire de la ruche HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Citrix\EUEM et de ses descendants, évidemment nous n’avons pas qu’un seul VDA alors nous allons le scripter.
Nous avons trouvé une partie de la réponse, modifier récursivement le propriétaire d’une ruche sur stackoverflow http://stackoverflow.com/questions/12044432/how-do-i-take-ownership-of-a-registry-key-via-powershell . Suivant le conseil d’Axel Limousin, nous choississon d’utilisr les « Well knows SIDs » ( https://support.microsoft.com/fr-fr/kb/243330 ) dans notre script plutot que les noms locaux. Après l’installation du VDA, les permissions sur les clé sont réinitialiser, il faut donc repasser le script.

invoke-command -computername $computers -ScriptBlock {
function Take-Permissions {
    # Developed for PowerShell v4.0
    # Required Admin privileges
    # Links:
    #   http://shrekpoint.blogspot.ru/2012/08/taking-ownership-of-dcom-registry.html
    #   http://www.remkoweijnen.nl/blog/2012/01/16/take-ownership-of-a-registry-key-in-powershell/
    #   https://powertoe.wordpress.com/2010/08/28/controlling-registry-acl-permissions-with-powershell/

    param($rootKey, $key, [System.Security.Principal.SecurityIdentifier]$sid = 'S-1-5-32-545', $recurse = $true)

    switch -regex ($rootKey) {
        'HKCU|HKEY_CURRENT_USER'    { $rootKey = 'CurrentUser' }
        'HKLM|HKEY_LOCAL_MACHINE'   { $rootKey = 'LocalMachine' }
        'HKCR|HKEY_CLASSES_ROOT'    { $rootKey = 'ClassesRoot' }
        'HKCC|HKEY_CURRENT_CONFIG'  { $rootKey = 'CurrentConfig' }
        'HKU|HKEY_USERS'            { $rootKey = 'Users' }
    }

    ### Step 1 - escalate current process's privilege
    # get SeTakeOwnership, SeBackup and SeRestore privileges before executes next lines, script needs Admin privilege
    $import = '[DllImport("ntdll.dll")] public static extern int RtlAdjustPrivilege(ulong a, bool b, bool c, ref bool d);'
    $ntdll = Add-Type -Member $import -Name NtDll -PassThru
    $privileges = @{ SeTakeOwnership = 9; SeBackup =  17; SeRestore = 18 }
    foreach ($i in $privileges.Values) {
        $null = $ntdll::RtlAdjustPrivilege($i, 1, 0, [ref]0)
    }

    function Take-KeyPermissions {
        param($rootKey, $key, $sid, $recurse, $recurseLevel = 0)

        ### Step 2 - get ownerships of key - it works only for current key
        $regKey = [Microsoft.Win32.Registry]::$rootKey.OpenSubKey($key, 'ReadWriteSubTree', 'TakeOwnership')
        $acl = New-Object System.Security.AccessControl.RegistrySecurity
        $acl.SetOwner($sid)
        $regKey.SetAccessControl($acl)

        ### Step 3 - enable inheritance of permissions (not ownership) for current key from parent
        $acl.SetAccessRuleProtection($false, $false)
        $regKey.SetAccessControl($acl)
		        ### Step 4 - only for top-level key, change permissions for current key and propagate it for subkeys
        # to enable propagations for subkeys, it needs to execute Steps 2-3 for each subkey (Step 5)
        if ($recurseLevel -eq 0) {
            $regKey = $regKey.OpenSubKey('', 'ReadWriteSubTree', 'ChangePermissions')
            $rule = New-Object System.Security.AccessControl.RegistryAccessRule($sid, 'FullControl', 'ContainerInherit', 'None', 'Allow')
            $acl.ResetAccessRule($rule)
            $regKey.SetAccessControl($acl)
        }

        ### Step 5 - recursively repeat steps 2-5 for subkeys
        if ($recurse) {
            foreach($subKey in $regKey.OpenSubKey('').GetSubKeyNames()) {
                Take-KeyPermissions $rootKey ($key+'\'+$subKey) $sid $recurse ($recurseLevel+1)
            }
        }
    }

    Take-KeyPermissions $rootKey $key $sid $recurse
}

Take-Permissions HKLM SOFTWARE\Wow6432Node\Citrix\EUEM S-1-5-32-544 $true

cd HKLM:\Software\Wow6432Node\citrix\EUEM
$acl = get-acl LoggedEvents
$nrule = New-Object System.Security.AccessControl.RegistryAccessRule([System.Security.Principal.SecurityIdentifier]"S-1-5-20", 'FullControl', 'ContainerInherit', 'None', 'Allow')
$acl.setAccessRule($nrule)
$lrule = New-Object System.Security.AccessControl.RegistryAccessRule([System.Security.Principal.SecurityIdentifier]"S-1-5-18", 'FullControl', 'ContainerInherit', 'None', 'Allow')
$acl.setAccessRule($lrule)
$urule = New-Object System.Security.AccessControl.RegistryAccessRule( [System.Security.Principal.SecurityIdentifier]"S-1-5-32-555", 'FullControl', 'ContainerInherit', 'None', 'Allow')
$acl.setAccessRule($urule)
set-acl LoggedEvents $acl
}