How do I take ownership of a registry key via PowerShell? How do I take ownership of a registry key via PowerShell? powershell powershell

How do I take ownership of a registry key via PowerShell?


Sometimes script don't have necessary ownership, privileges or permissions for changing registry values. It needs for admin privileges. Next script takes permissions recursively for all subkeys.

Call examples:

# group BULTIN\Users takes full control of key and all subkeysTake-Permissions "HKLM" "SOFTWARE\test"# group Everyone takes full control of key and all subkeysTake-Permissions "HKLM" "SOFTWARE\test" "S-1-1-0"# group Everyone takes full control of key WITHOUT subkeysTake-Permissions "HKLM" "SOFTWARE\test" "S-1-1-0" $false

You just should define next func:

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}


Just calling SetOwner doesn't commit the change. You need to pass the acl object back to Set-Acl to commit the change.

Check out this thread, there is a good description and full sample code. Seems there are some other hoops to jump through, as well: http://social.technet.microsoft.com/Forums/en/winserverpowershell/thread/e718a560-2908-4b91-ad42-d392e7f8f1ad


Well it is a clarifcation form an other post, but it is really important!

For the script posted last, be sure to add a security that checks for the $key. Otherwise you would overwrite all RegKeys in the particular rootkey.

Going back to a restore point does not work as computer-accounts do not have access anymore to the hole rootkey.

Something like:if ($key.length -eq 0) { write-host "key parameter must be set" return}