none
set-acl and the registry

    Question

  • Hello

    I'm learning about manipulating the registry using PowerShell, I've been following the examples in the "Windows PowerShell 2.0 Administrators Pocket Consultant".  That book suggests that the following command should copy the security descriptor from one key to another

    set-acl -path hkcu:\software\dev -aclobject (get-acl hkcu:\software\test)

    I've created the keys "dev" and "test", I've added a user named "foo" to the ACL for test and given him read.  When I run the command I mentioned above the "foo" entry never shows up in the ACL for the "dev" key.  However the command completes error free.

    Am I missing something here? 

    I'm on Windows 7 64 bit using Powershell 2.0 in 64bit mode.  I'm also running my powershell console as an administrator.

    Any help would be appreciated.

    Thursday, January 20, 2011 5:28 AM

Answers

  • Hello.  I've made some more progress on my question.  I asked the same question in some other forums and a poster at Stackoverflow mentioned that he had seen the same behaviour in both powershell and C#.  He suggested the following work around

    $acl = get-acl -path hkcu:\software\test
    $r = $acl.GetAccessRules($true, $true, [security.principal.ntaccount])
    $acl.RemoveAccessRuleAll($r[0])
    $acl.AddAccessRule($r[0])
    set-acl -path hkcu:\software\dev -aclobject $acl
    

    This works, the extra ACE entries I had manually added to hkcu:\software\test are now also applied to hkcu:\software\dev. 

    What is also weird is that this only works once, if I then subsequently apply $acl to another registry key the original problem appears again, for instance

    $acl = get-acl -path hkcu:\software\test
    $r = $acl.GetAccessRules($true, $true, [security.principal.ntaccount])
    $acl.RemoveAccessRuleAll($r[0])
    $acl.AddAccessRule($r[0])
    set-acl -path hkcu:\software\dev -aclobject $acl
    set-acl -path hkcu:\software\qa -aclobject $acl
    

     My updated ACL will be applied to hkcu:\software\dev but not to hkcu:\software\qa

    The thread on stackoverflow is http://stackoverflow.com/questions/4754966/can-i-copy-an-acl-from-one-registry-key-to-another-in-powershell-2-0

    Thank you for any insights you may be able to give me.

    Tuesday, January 25, 2011 4:34 AM

All replies

  • I've experimented with set-acl on registry keys a bit more, I haven't figured out why the code I talk about in my first post doesn't work but I have learned some more.

     

    First thing I found is that copying an ACL from one object to another works well if it is a file so something like this

    set-acl -path c:\foo.txt -aclobject (get-acl c:\bar.txt)

    works great.

     

    Second I've noticed if I retrieve the ACL of a registry entry and then modify that entry and reapply the acl object to the same registry key that works well.

    Is it simply not possible to copy an ACL object from one registry key to another?  Even though you can copy an ACL object from one file to another?

    Sunday, January 23, 2011 7:04 AM
  • Hello.  I've made some more progress on my question.  I asked the same question in some other forums and a poster at Stackoverflow mentioned that he had seen the same behaviour in both powershell and C#.  He suggested the following work around

    $acl = get-acl -path hkcu:\software\test
    $r = $acl.GetAccessRules($true, $true, [security.principal.ntaccount])
    $acl.RemoveAccessRuleAll($r[0])
    $acl.AddAccessRule($r[0])
    set-acl -path hkcu:\software\dev -aclobject $acl
    

    This works, the extra ACE entries I had manually added to hkcu:\software\test are now also applied to hkcu:\software\dev. 

    What is also weird is that this only works once, if I then subsequently apply $acl to another registry key the original problem appears again, for instance

    $acl = get-acl -path hkcu:\software\test
    $r = $acl.GetAccessRules($true, $true, [security.principal.ntaccount])
    $acl.RemoveAccessRuleAll($r[0])
    $acl.AddAccessRule($r[0])
    set-acl -path hkcu:\software\dev -aclobject $acl
    set-acl -path hkcu:\software\qa -aclobject $acl
    

     My updated ACL will be applied to hkcu:\software\dev but not to hkcu:\software\qa

    The thread on stackoverflow is http://stackoverflow.com/questions/4754966/can-i-copy-an-acl-from-one-registry-key-to-another-in-powershell-2-0

    Thank you for any insights you may be able to give me.

    Tuesday, January 25, 2011 4:34 AM
  • did you get a chance to fix this? or you are still having issues?


    Thiyagu | MCTS/MCITP - Exchange 2007 | MCSE 2003[Messaging] | http://www.myExchangeWorld.com. This posting is provided "AS IS" with no warranties, and confers no rights.
    Wednesday, February 09, 2011 10:07 AM
  • Oh, thank you, thank you, thank you. I know this thread is ancient and doesn't really land at an answer but I just ran into this this morning and had been going vaguely nuts until I managed to get the right four words into a search engine to land here.

    I don't have an answer yet either. One thing I have noticed that seems strange is that if you run the following ... 

    $path1 = # some reg-key path
    $path2 = # some other reg-key path
    $acl = Get-Acl $path1
    Write-Output $acl.path
    Set-Acl $path2 $acl
    Write-Output $acl.path

    ... not only do the permissions on the key specified by $path2 not change as you'd expect them to, but also $acl.path does change. The first Write-Output prints $path1, not surprisingly. But the second one prints $path2. Odd. I wouldn't have expected Set-Acl to modify its -AclObject argument at all.

    Tuesday, September 03, 2013 12:01 AM
  • The "refresh/dirty/kick the acl each time before you set it on another key" solution seems to work. As does reducing the code to simply ...

    $acl = Get-Acl $path1
    $acl.SetSecurityDescriptorSddlForm($acl.Sddl) # trivially "change" $acl to get Set-Acl to work.
    Set-Acl $path2 $acl




    Tuesday, September 03, 2013 12:24 AM