Im working in a script to remove TDL key from Windows 10 registry. This they are in :

  • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileNotification
  • HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\ProfileNotification

The Windows version of all computers is Windows 10 Pro 1809. The computers are in a Windows Server domain, 35 computers.

    # AMBAS RUTAS AL REGISTRO, elimino el comentario segun requiero
        $keyLocation = 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileNotification\'
        # $keyLocation = 'SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\ProfileNotification\'

    $definition = @"
    using System;
    using System.Runtime.InteropServices; 

    namespace Win32Api

        public class NtDll
            [DllImport("ntdll.dll", EntryPoint="RtlAdjustPrivilege")]
            public static extern int RtlAdjustPrivilege(ulong Privilege, bool Enable, bool CurrentThread, ref bool Enabled);

    # Defino variables
        $computerName = $env:computername | Select-Object
        $UserName = 'administrador'
        $computerUser = $computerName + '\' + $UserName
        $keyInitPath = 'HKLM'
        $keyName = 'TDL'
        $keyPath = $keyInitPath + ':\' + $keyLocation
        $keyPathComplete = $keyPath + $keyName
        $keyNameLocation = $keyLocation + $keyName

    Add-Type -TypeDefinition $definition -PassThru
    $bEnabled = $false

    # Tomo posesiĆ³n de la clave TDL
        $res = [Win32Api.NtDll]::RtlAdjustPrivilege(9, $true, $false, [ref]$bEnabled)
        $key = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey($keyLocation + $keyName, [Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::takeownership)
        $acl = $key.GetAccessControl()

    # SET Permisos a TDL para administradores
        $key = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey($keyNameLocation,[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::ChangePermissions)
        $acl = $key.GetAccessControl()
        $rule = New-Object System.Security.AccessControl.RegistryAccessRule (".\administradores","FullControl",@("ObjectInherit","ContainerInherit"),"None","Allow")

    # Elimino la clave TDL
        Remove-Item -Path $keyPathComplete

The problem is that they show me ACCESS.DENIED when I run it on another computer, in the same environment. In the development computer, dont errors are found, all are executed as one spell, but in another, this shows me an ACCESS DENIED error, but not in the TAKE OWNER segment, but in the REMOVE segment.

I chek the Key throug registry key, and no modifications are, and no errors in PowerShell too. I dont understand this.

It may be that you have modified something in the permissions at the time of development, in the registry of the source machine. I do not know ... the code seems to be ok, but...

NOTE: Im executing as elevated privilegies. (sorry for my english)

1 Answers

Theo On

The inheritanceFlags aswell as the propagationFlags parameter, is a Flags Enum, meaning the various options should be added (or 'OR-ed') together to form a bitwise combination.

In your code, you set them up as an array @("ObjectInherit","ContainerInherit") and therefore the permissions are not set as you are expecting it.
Then, when you try to delete the key, you get Access Denied, because the permissions on the properties inside the key did not inherit from the key.

In fact, you need a single value containing

[System.Security.AccessControl.InheritanceFlags]::ContainerInherit -bor [System.Security.AccessControl.InheritanceFlags]::ObjectInherit

In PowerShell you can simply use a comma delimited string for that:

"ContainerInherit, ObjectInherit"


$rule = New-Object System.Security.AccessControl.RegistryAccessRule(".\administradores","FullControl","ContainerInherit, ObjectInherit","None","Allow")

Hope that helps

Note that it is also possible to bitwise OR the numeric values together as in [System.Security.AccessControl.InheritanceFlags]::ObjectInherit.value__ -bor [System.Security.AccessControl.InheritanceFlags]::ContainerInherit.value__ which will amount to 3. However, this is not advisable because it makes the code less readable.