How can I take control of the registry key through Powershell?

I try to take control of the registry key through Powershell and it fails. I am using the following code:

# get the username of the current user $uname = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name # create an identity reference for the owner $user = new-object System.Security.Principal.NTAccount($uname) # create a "drive" for HKEY_CLASSES_ROOT new-psdrive -name HKCR_zf -psprovider Registry -root HKEY_CLASSES_ROOT # change the current location set-location HCKR_zf:\CLSID # set ACLs (get-acl '{E88DCCE0-B7B3-11d1-A9F0-00AA0060FA31}').setowner($user) 

Everything works to the last line, but the .setowner () call fails (the owner does not change).

How to get ownership of a registry key?

+4
source share
5 answers

Just calling SetOwner does not SetOwner the changes. You need to pass the acl object back to Set-Acl to commit the change.

Look at this topic, there is a good description and a complete code sample. There seem to be other hoops: http://social.technet.microsoft.com/Forums/en/winserverpowershell/thread/e718a560-2908-4b91-ad42-d392e7f8f1ad

+2
source

Sometimes a script does not have the necessary ownership, privileges, or permissions to modify registry values. It is required for administrator privileges. The following script recursively accepts permissions for all subkeys.

Call examples:

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

You just have to define the following function:

 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 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 } 
+2
source

When using identifiers such as {E88DCCE0-B7B3-11d1-A9F0-00AA0060FA31} you need to use "" In example (HKLM:\SOFTWARE\Classes\CLSID\"{031E4825-7B94-4dc3-B131-E946B44C8DD5}",Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::takeownership)

+1
source

Well, this is an explanation from another post, but it is really important!

For the last script sent, be sure to add security that checks the $ key. Otherwise, you must overwrite all RegKeys in a specific root directory.

Returning to the restore point does not work because computer accounts no longer have access to the root hole key.

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

+1
source

A variant of another answer. This only establishes ownership.

 <# .SYNOPSIS Give ownership of a file or folder to the specified user. .DESCRIPTION Give the current process the SeTakeOwnershipPrivilege" and "SeRestorePrivilege" rights which allows it to reset ownership of an object. The script will then set the owner to be the specified user. .PARAMETER Path (Required) The path to the object on which you wish to change ownership. It can be a file or a folder. .PARAMETER User (Required) The user whom you want to be the owner of the specified object. The user should be in the format <domain>\<username>. Other user formats will not work. For system accounts, such as System, the user should be specified as "NT AUTHORITY\System". If the domain is missing, the local machine will be assumed. .PARAMETER Recurse (switch) Causes the function to parse through the Path recursively. .INPUTS None. You cannot pipe objects to Take-Ownership .OUTPUTS None .NOTES Name: Take-Ownership.ps1 Author: Jason Eberhardt Date: 2017-07-20 #> function Take-Ownership { [CmdletBinding(SupportsShouldProcess=$false)] Param([Parameter(Mandatory=$true, ValueFromPipeline=$false)] [ValidateNotNullOrEmpty()] [string]$Path, [Parameter(Mandatory=$true, ValueFromPipeline=$false)] [ValidateNotNullOrEmpty()] [string]$User, [Parameter(Mandatory=$false, ValueFromPipeline=$false)] [switch]$Recurse) Begin { $AdjustTokenPrivileges=@ " using System; using System.Runtime.InteropServices; public class TokenManipulator { [DllImport("kernel32.dll", ExactSpelling = true)] internal static extern IntPtr GetCurrentProcess(); [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen); [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok); [DllImport("advapi32.dll", SetLastError = true)] internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid); [StructLayout(LayoutKind.Sequential, Pack = 1)] internal struct TokPriv1Luid { public int Count; public long Luid; public int Attr; } internal const int SE_PRIVILEGE_DISABLED = 0x00000000; internal const int SE_PRIVILEGE_ENABLED = 0x00000002; internal const int TOKEN_QUERY = 0x00000008; internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020; public static bool AddPrivilege(string privilege) { bool retVal; TokPriv1Luid tp; IntPtr hproc = GetCurrentProcess(); IntPtr htok = IntPtr.Zero; retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok); tp.Count = 1; tp.Luid = 0; tp.Attr = SE_PRIVILEGE_ENABLED; retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid); retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero); return retVal; } public static bool RemovePrivilege(string privilege) { bool retVal; TokPriv1Luid tp; IntPtr hproc = GetCurrentProcess(); IntPtr htok = IntPtr.Zero; retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok); tp.Count = 1; tp.Luid = 0; tp.Attr = SE_PRIVILEGE_DISABLED; retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid); retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero); return retVal; } } "@ } Process { $Item=Get-Item $Path Write-Verbose "Giving current process token ownership rights" Add-Type $AdjustTokenPrivileges -PassThru > $null [void][TokenManipulator]::AddPrivilege("SeTakeOwnershipPrivilege") [void][TokenManipulator]::AddPrivilege("SeRestorePrivilege") # Change ownership $Account=$User.Split("\") if ($Account.Count -eq 1) { $Account+=$Account[0]; $Account[0]=$env:COMPUTERNAME } $Owner=New-Object System.Security.Principal.NTAccount($Account[0],$Account[1]) Write-Verbose "Change ownership to '$($Account[0])\$($Account[1])'" $Provider=$Item.PSProvider.Name if ($Item.PSIsContainer) { switch ($Provider) { "FileSystem" { $ACL=[System.Security.AccessControl.DirectorySecurity]::new() } "Registry" { $ACL=[System.Security.AccessControl.RegistrySecurity]::new() # Get-Item doesn't open the registry in a way that we can write to it. switch ($Item.Name.Split("\")[0]) { "HKEY_CLASSES_ROOT" { $rootKey=[Microsoft.Win32.Registry]::ClassesRoot; break } "HKEY_LOCAL_MACHINE" { $rootKey=[Microsoft.Win32.Registry]::LocalMachine; break } "HKEY_CURRENT_USER" { $rootKey=[Microsoft.Win32.Registry]::CurrentUser; break } "HKEY_USERS" { $rootKey=[Microsoft.Win32.Registry]::Users; break } "HKEY_CURRENT_CONFIG" { $rootKey=[Microsoft.Win32.Registry]::CurrentConfig; break } } $Key=$Item.Name.Replace(($Item.Name.Split("\")[0]+"\"),"") $Item=$rootKey.OpenSubKey($Key,[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::TakeOwnership) } default { throw "Unknown provider: $($Item.PSProvider.Name)" } } $ACL.SetOwner($Owner) Write-Verbose "Setting owner on $Path" $Item.SetAccessControl($ACL) if ($Provider -eq "Registry") { $Item.Close() } if ($Recurse.IsPresent) { # You can't set ownership on Registry Values if ($Provider -eq "Registry") { $Items=Get-ChildItem -Path $Path -Recurse -Force | Where-Object { $_.PSIsContainer } } else { $Items=Get-ChildItem -Path $Path -Recurse -Force } $Items=@ ($Items) for ($i=0; $i -lt $Items.Count; $i++) { switch ($Provider) { "FileSystem" { $Item=Get-Item $Items[$i].FullName if ($Item.PSIsContainer) { $ACL=[System.Security.AccessControl.DirectorySecurity]::new() } else { $ACL=[System.Security.AccessControl.FileSecurity]::new() } } "Registry" { $Item=Get-Item $Items[$i].PSPath $ACL=[System.Security.AccessControl.RegistrySecurity]::new() # Get-Item doesn't open the registry in a way that we can write to it. switch ($Item.Name.Split("\")[0]) { "HKEY_CLASSES_ROOT" { $rootKey=[Microsoft.Win32.Registry]::ClassesRoot; break } "HKEY_LOCAL_MACHINE" { $rootKey=[Microsoft.Win32.Registry]::LocalMachine; break } "HKEY_CURRENT_USER" { $rootKey=[Microsoft.Win32.Registry]::CurrentUser; break } "HKEY_USERS" { $rootKey=[Microsoft.Win32.Registry]::Users; break } "HKEY_CURRENT_CONFIG" { $rootKey=[Microsoft.Win32.Registry]::CurrentConfig; break } } $Key=$Item.Name.Replace(($Item.Name.Split("\")[0]+"\"),"") $Item=$rootKey.OpenSubKey($Key,[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::TakeOwnership) } default { throw "Unknown provider: $($Item.PSProvider.Name)" } } $ACL.SetOwner($Owner) Write-Verbose "Setting owner on $($Item.Name)" $Item.SetAccessControl($ACL) if ($Provider -eq "Registry") { $Item.Close() } } } # Recursion } else { if ($Recurse.IsPresent) { Write-Warning "Object specified is neither a folder nor a registry key. Recursion is not possible." } switch ($Provider) { "FileSystem" { $ACL=[System.Security.AccessControl.FileSecurity]::new() } "Registry" { throw "You cannot set ownership on a registry value" } default { throw "Unknown provider: $($Item.PSProvider.Name)" } } $ACL.SetOwner($Owner) Write-Verbose "Setting owner on $Path" $Item.SetAccessControl($ACL) } } } Take-Ownership -Path "Registry::HKCR\CLSID\{0D43FE01-F093-11CF-8940-00A0C9054228}" -User "Administrator" -Recurse -Verbose 
0
source

All Articles