locked
Take ownership of a registry key, and change permissions RRS feed

  • Question

  • Hello,

    I am writing a powershell script to configure a W2008-R2 Server. In one of the steps, I need to take ownership of an existing registry key, and then give full control permissions to the administrators.

    I have done this:

     $acl = Get-Acl $key
    
     $me = [System.Security.Principal.NTAccount]"$env:userdomain\$env:username"
    
     $acl.SetOwner($me)
    
    
    
     $person = [System.Security.Principal.NTAccount]"Administrators"
    
     $access = [System.Security.AccessControl.RegistryRights]"FullControl"
    
     $inheritance = [System.Security.AccessControl.InheritanceFlags]"None"
    
     $propagation = [System.Security.AccessControl.PropagationFlags]"None"
    
     $type = [System.Security.AccessControl.AccessControlType]"Allow"
    
     $rule = New-Object System.Security.AccessControl.RegistryAccessRule($person,$access,$inheritance,$propagation,$type)
    
     $acl.AddAccessRule($rule)
    
     Set-Acl $key $acl
    
    

    But it fails in "set-acl" command, with the message "Set-Acl : Requested registry access is not allowed."

     

    Any ideas of how to do this? or if it is even possible?

     

    Thank you!

    Wednesday, November 3, 2010 11:01 AM

Answers

  • I just realized I forgot something.  My initial code won't work correctly.  When you grab the acl while you are not the owner you must grab a blank acl because you will not have permissions to get anything else.  After you set the owner and apply the acl you will need to grab a new acl to add the original permission you were trying to add.  I have put my own user/perms in the sample, but you should be able to plug yours in very easily.

    Here's the complete script to enable your process with the SeTakeOwnershipPrivilege, set the owner for the key, and then add a new access rule to the key:

    function enable-privilege {
     param(
      ## The privilege to adjust. This set is taken from
      ## http://msdn.microsoft.com/en-us/library/bb530716(VS.85).aspx
      [ValidateSet(
       "SeAssignPrimaryTokenPrivilege", "SeAuditPrivilege", "SeBackupPrivilege",
       "SeChangeNotifyPrivilege", "SeCreateGlobalPrivilege", "SeCreatePagefilePrivilege",
       "SeCreatePermanentPrivilege", "SeCreateSymbolicLinkPrivilege", "SeCreateTokenPrivilege",
       "SeDebugPrivilege", "SeEnableDelegationPrivilege", "SeImpersonatePrivilege", "SeIncreaseBasePriorityPrivilege",
       "SeIncreaseQuotaPrivilege", "SeIncreaseWorkingSetPrivilege", "SeLoadDriverPrivilege",
       "SeLockMemoryPrivilege", "SeMachineAccountPrivilege", "SeManageVolumePrivilege",
       "SeProfileSingleProcessPrivilege", "SeRelabelPrivilege", "SeRemoteShutdownPrivilege",
       "SeRestorePrivilege", "SeSecurityPrivilege", "SeShutdownPrivilege", "SeSyncAgentPrivilege",
       "SeSystemEnvironmentPrivilege", "SeSystemProfilePrivilege", "SeSystemtimePrivilege",
       "SeTakeOwnershipPrivilege", "SeTcbPrivilege", "SeTimeZonePrivilege", "SeTrustedCredManAccessPrivilege",
       "SeUndockPrivilege", "SeUnsolicitedInputPrivilege")]
      $Privilege,
      ## The process on which to adjust the privilege. Defaults to the current process.
      $ProcessId = $pid,
      ## Switch to disable the privilege, rather than enable it.
      [Switch] $Disable
     )
    
     ## Taken from P/Invoke.NET with minor adjustments.
     $definition = @'
     using System;
     using System.Runtime.InteropServices;
      
     public class AdjPriv
     {
      [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_ENABLED = 0x00000002;
      internal const int SE_PRIVILEGE_DISABLED = 0x00000000;
      internal const int TOKEN_QUERY = 0x00000008;
      internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
      public static bool EnablePrivilege(long processHandle, string privilege, bool disable)
      {
       bool retVal;
       TokPriv1Luid tp;
       IntPtr hproc = new IntPtr(processHandle);
       IntPtr htok = IntPtr.Zero;
       retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
       tp.Count = 1;
       tp.Luid = 0;
       if(disable)
       {
        tp.Attr = SE_PRIVILEGE_DISABLED;
       }
       else
       {
        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;
      }
     }
    '@
    
     $processHandle = (Get-Process -id $ProcessId).Handle
     $type = Add-Type $definition -PassThru
     $type[0]::EnablePrivilege($processHandle, $Privilege, $Disable)
    }
    
    enable-privilege SeTakeOwnershipPrivilege 
    $key = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey("SOFTWARE\powertoe",[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::takeownership)
    # You must get a blank acl for the key b/c you do not currently have access
    $acl = $key.GetAccessControl([System.Security.AccessControl.AccessControlSections]::None)
    $me = [System.Security.Principal.NTAccount]"t-alien\tome"
    $acl.SetOwner($me)
    $key.SetAccessControl($acl)
    
    # After you have set owner you need to get the acl with the perms so you can modify it.
    $acl = $key.GetAccessControl()
    $rule = New-Object System.Security.AccessControl.RegistryAccessRule ("T-Alien\Tome","FullControl","Allow")
    $acl.SetAccessRule($rule)
    $key.SetAccessControl($acl)
    
    $key.Close()


    http://twitter.com/toenuff
    write-host ((0..56)|%{if (($_+1)%3 -eq 0){[char][int]("116111101110117102102064103109097105108046099111109"[($_-2)..$_] -join "")}}) -separator ""
    • Marked as answer by Jagermeist Thursday, November 4, 2010 9:30 AM
    Thursday, November 4, 2010 2:24 AM

All replies

  • I am certainly no expert in this area.  But it has been my experience that, depending on the permissions, you might have to take ownership before you can set permissions.  Given that the file exists already, that may be the case.

     

    This article might provide some insight: http://alt.pluralsight.com/wiki/default.aspx/Keith.GuideBook/HowToTakeOwnershipOfAnObject.html

     

     


    Sam Hays
    Wednesday, November 3, 2010 7:49 PM
  • SetOwner is not changing the owner on the key, only the copy of the ACL stored in the variable. You will need to call Set-Acl to change ownership, then proceed with your permission changes.

    http://blogs.technet.com/b/heyscriptingguy/archive/2008/04/15/how-can-i-use-windows-powershell-to-determine-the-owner-of-a-file.aspx

     

    Wednesday, November 3, 2010 10:31 PM
  • Here is the code to take ownership of a registry key.  You first need to set the SeTakeOwnership permission on your process

     

    The enable-privilege function is taken from a posting by Lee Holmes (http://www.leeholmes.com/blog/2010/09/24/adjusting-token-privileges-in-powershell/), but I've been meaning to get around to tidy it up a bit for my purposes.  Perhaps this thread is the motivation I need to do this.  I should also note that the PowerShell Community Extensions has cmdlets to work with tokens already.  

     

    I also never tested whether you can do the PowerShell native methods of get-acl set-acl if you set the token.  I don't have time to play with that now, but if you want to try it and let us know if it works that would be great.  The opensubkey method I'm using I've documented here for changing permissions when you don't have permissions: http://powertoe.wordpress.com/2010/08/28/controlling-registry-acl-permissions-with-powershell/

     

    function enable-privilege {
      param(
        ## The privilege to adjust. This set is taken from
        ## http://msdn.microsoft.com/en-us/library/bb530716(VS.85).aspx
        [ValidateSet(
          "SeAssignPrimaryTokenPrivilege", "SeAuditPrivilege", "SeBackupPrivilege",
          "SeChangeNotifyPrivilege", "SeCreateGlobalPrivilege", "SeCreatePagefilePrivilege",
          "SeCreatePermanentPrivilege", "SeCreateSymbolicLinkPrivilege", "SeCreateTokenPrivilege",
          "SeDebugPrivilege", "SeEnableDelegationPrivilege", "SeImpersonatePrivilege", "SeIncreaseBasePriorityPrivilege",
          "SeIncreaseQuotaPrivilege", "SeIncreaseWorkingSetPrivilege", "SeLoadDriverPrivilege",
          "SeLockMemoryPrivilege", "SeMachineAccountPrivilege", "SeManageVolumePrivilege",
          "SeProfileSingleProcessPrivilege", "SeRelabelPrivilege", "SeRemoteShutdownPrivilege",
          "SeRestorePrivilege", "SeSecurityPrivilege", "SeShutdownPrivilege", "SeSyncAgentPrivilege",
          "SeSystemEnvironmentPrivilege", "SeSystemProfilePrivilege", "SeSystemtimePrivilege",
          "SeTakeOwnershipPrivilege", "SeTcbPrivilege", "SeTimeZonePrivilege", "SeTrustedCredManAccessPrivilege",
          "SeUndockPrivilege", "SeUnsolicitedInputPrivilege")]
        $Privilege,
        ## The process on which to adjust the privilege. Defaults to the current process.
        $ProcessId = $pid,
        ## Switch to disable the privilege, rather than enable it.
        [Switch] $Disable
      )
    
      ## Taken from P/Invoke.NET with minor adjustments.
      $definition = @'
      using System;
      using System.Runtime.InteropServices;
       
      public class AdjPriv
      {
        [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_ENABLED = 0x00000002;
        internal const int SE_PRIVILEGE_DISABLED = 0x00000000;
        internal const int TOKEN_QUERY = 0x00000008;
        internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
        public static bool EnablePrivilege(long processHandle, string privilege, bool disable)
        {
          bool retVal;
          TokPriv1Luid tp;
          IntPtr hproc = new IntPtr(processHandle);
          IntPtr htok = IntPtr.Zero;
          retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
          tp.Count = 1;
          tp.Luid = 0;
          if(disable)
          {
            tp.Attr = SE_PRIVILEGE_DISABLED;
          }
          else
          {
            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;
        }
      }
    '@
    
      $processHandle = (Get-Process -id $ProcessId).Handle
      $type = Add-Type $definition -PassThru
      $type[0]::EnablePrivilege($processHandle, $Privilege, $Disable)
    }
    
    enable-privilege SeTakeOwnershipPrivilege 
    $key = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey("SOFTWARE\powertoe",[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::takeownership)
    $acl = $key.GetAccessControl()
    $me = [System.Security.Principal.NTAccount]"t-alien\tome"
    $acl.SetOwner($me)
    $key.SetAccessControl($acl)


    http://twitter.com/toenuff
    write-host ((0..56)|%{if (($_+1)%3 -eq 0){[char][int]("116111101110117102102064103109097105108046099111109"[($_-2)..$_] -join "")}}) -separator ""
    Wednesday, November 3, 2010 11:22 PM
  • I wound up playing with this some more.  You must use OpenSubKey:

     

    enable-privilege SeTakeOwnershipPrivilege 
    $key = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey("SOFTWARE\powertoe",[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::takeownership)
    $acl = $key.GetAccessControl()
    $me = [System.Security.Principal.NTAccount]"t-alien\tome"
    $acl.SetOwner($me)
    $key.SetAccessControl($acl)

     

    You cannot use

     

    enable-privilege SeTakeOwnershipPrivilege
    (Get-Acl hklm:\software\powertoe).setowner($me)|set-acl

    I'm not really surprised, but I thought it was worth mentioning here for anyone who finds this thread.


    http://twitter.com/toenuff
    write-host ((0..56)|%{if (($_+1)%3 -eq 0){[char][int]("116111101110117102102064103109097105108046099111109"[($_-2)..$_] -join "")}}) -separator ""
    Thursday, November 4, 2010 2:00 AM
  • I just realized I forgot something.  My initial code won't work correctly.  When you grab the acl while you are not the owner you must grab a blank acl because you will not have permissions to get anything else.  After you set the owner and apply the acl you will need to grab a new acl to add the original permission you were trying to add.  I have put my own user/perms in the sample, but you should be able to plug yours in very easily.

    Here's the complete script to enable your process with the SeTakeOwnershipPrivilege, set the owner for the key, and then add a new access rule to the key:

    function enable-privilege {
     param(
      ## The privilege to adjust. This set is taken from
      ## http://msdn.microsoft.com/en-us/library/bb530716(VS.85).aspx
      [ValidateSet(
       "SeAssignPrimaryTokenPrivilege", "SeAuditPrivilege", "SeBackupPrivilege",
       "SeChangeNotifyPrivilege", "SeCreateGlobalPrivilege", "SeCreatePagefilePrivilege",
       "SeCreatePermanentPrivilege", "SeCreateSymbolicLinkPrivilege", "SeCreateTokenPrivilege",
       "SeDebugPrivilege", "SeEnableDelegationPrivilege", "SeImpersonatePrivilege", "SeIncreaseBasePriorityPrivilege",
       "SeIncreaseQuotaPrivilege", "SeIncreaseWorkingSetPrivilege", "SeLoadDriverPrivilege",
       "SeLockMemoryPrivilege", "SeMachineAccountPrivilege", "SeManageVolumePrivilege",
       "SeProfileSingleProcessPrivilege", "SeRelabelPrivilege", "SeRemoteShutdownPrivilege",
       "SeRestorePrivilege", "SeSecurityPrivilege", "SeShutdownPrivilege", "SeSyncAgentPrivilege",
       "SeSystemEnvironmentPrivilege", "SeSystemProfilePrivilege", "SeSystemtimePrivilege",
       "SeTakeOwnershipPrivilege", "SeTcbPrivilege", "SeTimeZonePrivilege", "SeTrustedCredManAccessPrivilege",
       "SeUndockPrivilege", "SeUnsolicitedInputPrivilege")]
      $Privilege,
      ## The process on which to adjust the privilege. Defaults to the current process.
      $ProcessId = $pid,
      ## Switch to disable the privilege, rather than enable it.
      [Switch] $Disable
     )
    
     ## Taken from P/Invoke.NET with minor adjustments.
     $definition = @'
     using System;
     using System.Runtime.InteropServices;
      
     public class AdjPriv
     {
      [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_ENABLED = 0x00000002;
      internal const int SE_PRIVILEGE_DISABLED = 0x00000000;
      internal const int TOKEN_QUERY = 0x00000008;
      internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
      public static bool EnablePrivilege(long processHandle, string privilege, bool disable)
      {
       bool retVal;
       TokPriv1Luid tp;
       IntPtr hproc = new IntPtr(processHandle);
       IntPtr htok = IntPtr.Zero;
       retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
       tp.Count = 1;
       tp.Luid = 0;
       if(disable)
       {
        tp.Attr = SE_PRIVILEGE_DISABLED;
       }
       else
       {
        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;
      }
     }
    '@
    
     $processHandle = (Get-Process -id $ProcessId).Handle
     $type = Add-Type $definition -PassThru
     $type[0]::EnablePrivilege($processHandle, $Privilege, $Disable)
    }
    
    enable-privilege SeTakeOwnershipPrivilege 
    $key = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey("SOFTWARE\powertoe",[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::takeownership)
    # You must get a blank acl for the key b/c you do not currently have access
    $acl = $key.GetAccessControl([System.Security.AccessControl.AccessControlSections]::None)
    $me = [System.Security.Principal.NTAccount]"t-alien\tome"
    $acl.SetOwner($me)
    $key.SetAccessControl($acl)
    
    # After you have set owner you need to get the acl with the perms so you can modify it.
    $acl = $key.GetAccessControl()
    $rule = New-Object System.Security.AccessControl.RegistryAccessRule ("T-Alien\Tome","FullControl","Allow")
    $acl.SetAccessRule($rule)
    $key.SetAccessControl($acl)
    
    $key.Close()


    http://twitter.com/toenuff
    write-host ((0..56)|%{if (($_+1)%3 -eq 0){[char][int]("116111101110117102102064103109097105108046099111109"[($_-2)..$_] -join "")}}) -separator ""
    • Marked as answer by Jagermeist Thursday, November 4, 2010 9:30 AM
    Thursday, November 4, 2010 2:24 AM
  • Thank you very much to all of you, I'll try it today and will let you know how it went!
    Thursday, November 4, 2010 7:55 AM
  • Worked perfectly, thank you again!!
    Thursday, November 4, 2010 9:31 AM
  • Hi, I tried running the script above on a Windows 7 build and it comes up with an error:

    "You cannot call a method on a null-valued expression." for all of the following line:

    $acl = $key.GetAccessControl([System.Security.AccessControl.AccessControlSections]::None)

    $acl.SetOwner($me)


    $key.SetAccessControl($acl)

    $acl = $key.GetAccessControl()

    Any ideas as to what else needs to be done to get the script to work?

    Wednesday, April 20, 2011 7:53 PM
  • my guess is the registry key isnt there.. so that’s why its null. you might want to test the path first (test-path works with registry keys as well)

    Thursday, April 21, 2011 12:00 PM
  • Hi,

          I am trying to change owner of a registry key from "TrustedInstaller" to "domain\user" in windows 7. 

    Here is my key.

    $key = [Microsoft.Win32.Registry]::ClassesRoot.OpenSubKey("CLSID\{76A64158-CB41-11D1-8B02-00600806D9B6}",[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,
    [System.Security.AccessControl.RegistryRights]::TakeOwnership)

    When I execute my code, I am getting following error.

    Exception calling "OpenSubKey" with "3" argument(s): "Requested registry access is not allowed."

    Any help is greatly appreciated.


    Tuesday, March 4, 2014 6:11 PM
  • Did you enable the 'SeTakeOwnershipPrivilege' privilege? Are you running this from an elevated prompt? If you answered yes to both of those, you can type 'whoami /priv' from PS and make sure that the 'SeTakeOwnershipPrivilege' is present on the token (if it's present but showing 'Disabled', then it hasn't been enabled yet; if it's not showing up at all, you won't be able to enable it).

    If you're willing to use a module to handle this, you can import this one and run one of the following commands:

    # To take ownership, -Principal parameter isn't necessary:
    PS> Set-Owner -Path "HKLM:\SOFTWARE\Classes\CLSID\{76A64158-CB41-11D1-8B02-00600806D9B6}"
    
    # You can also do this through the pipeline:
    PS> Get-Item "HKLM:\SOFTWARE\Classes\CLSID\{76A64158-CB41-11D1-8B02-00600806D9B6}" | Set-Owner

    If you want to assign ownership to another user, just use the -Principal parameter.

    If that doesn't answer your question, you're probably better off creating a new question in the forum since this one has already been answered. The accepted answer does look like it should work just fine, though (most of the code goes to making it so that the privilege can be enabled from PS).

    Tuesday, March 4, 2014 6:47 PM
  • You are correct. SeTakeOwnershipPrivilege is disable. 

    SeTakeOwnershipPrivilege        Take ownership of files or other objects  Disabled

    How to enable this ownership?

    Tuesday, March 4, 2014 7:55 PM
  • The accepted answer in this thread has the code to enable the privilege.
    Wednesday, March 5, 2014 2:30 AM
  • After changing the permissions I want to set the owner of the registry key to "TrustedInstaller"

    For that here is my code:

    $user = [System.Security.Principal.NTAccount]"NT SERVICE\TrustedInstaller"
    $acl = $key.GetAccessControl([System.Security.AccessControl.AccessControlSections]::None)
    $acl.SetOwner($user)
    $key.SetAccessControl($acl)

    $acl = $key.GetAccessControl()
    $rule = New-Object System.Security.AccessControl.RegistryAccessRule ("NT SERVICE\TrustedInstaller","FullControl","Allow")
    $acl.SetAccessRule($rule)
    $key.SetAccessControl($acl)

    I got following error:

    Cannot convert argument "identity", with value: "NT SERVICE\TrustedInstaller", for "SetOwner" to type
    "System.Security.Principal.IdentityReference": "Cannot convert the "NT SERVICE\TrustedInstaller" value of type
    "System.String" to type "System.Security.Principal.IdentityReference"."

    So how can we set the registry owner back to TrustedInstaller.


    Thursday, March 6, 2014 7:27 PM
  • I am able to set the the owner of key back to TrustedInstaller using the following code.

    [System.Security.Principal.NTAccount]$TrustedInstaller = "NT SERVICE\TrustedInstaller"
    $acl =  Get-Acl "Registry::\HKEY_CLASSES_ROOT\key"
    $acl.SetOwner($TrustedInstaller)
    enable-privilege SeRestorePrivilege
    Set-Acl -Path "Registry::\HKEY_CLASSES_ROOT\key" -AclObject $acl

    But permissions are set to "only this key". How can we set permissions to "this key and all sub keys".

    Thursday, March 6, 2014 9:22 PM
  • I also would like to know how to set "this key and all sub keys". Any ideas?
    Tuesday, July 22, 2014 5:36 AM
  • Hi,

    For information, I tried using your code and encountered random failures (EnablePrivilege simply returned $false).
    I analyzed the issue further, and it turns out that in some occurrences, OpenProcessToken fails, and GetLastError returns ERROR_INVALID_HANDLE

    In my use case I only needed to enable the privilege for the current process, so I stopped the investigation there and instead had the C# code retrieve the process handle, and that seems to work fine.

    Out of curiosity I may try to figure out where that comes from. No promise, though...

     
    Tuesday, November 4, 2014 6:52 PM