Search code examples
powershellautomationregistryaclregedit

How do I run Get-ACL for HKLM:\Security?


Get-Acl does not pull the Acl for HKLM\Security.

This command works for all other values. When I run get-itemproperty "HKLM:\Security" I get an access denied error, even though I can view both the registry key, and the ACL, manually in regedit.exe. All while running ps as admin.

I tried

get-acl "HKLM:\Security"

The result was blank. Although there are ACL rules configured for System and Administrator that should have been pulled. Why can't I pull the ACL for HKLM\Security, on an account where I have the correct permissions to view it?


Solution

  • Get-Acl path\goes\here first tries to resolve the target item at path\goes\here (equivalent to Get-Item path\goes\here), before fetching the associated ACL from the resolved target item.

    The default ACL on HKLM:\SECURITY is usually configured to deny EVERYONE Read access - and since deny trumps allow, your admin access doesn't help you :-)


    One way to work around this - and I'm sure there are other, potentially safer ways - is to use a bit of reflection to hook into the private constructor that RegistryKey.GetAccessControl() usually invokes under the hood:

    # discover private constructor of [RegistrySecurity] class
    $registryACLPrivateConstructor = [System.Security.AccessControl.RegistrySecurity].GetConstructors([System.Reflection.BindingFlags]'NonPublic,Instance')[0]
    
    # prepare arguments - hive, path, and section mask
    $hiveHandle = (Get-Item HKLM:\).Handle
    $keyPath = 'SECURITY'
    $sections = [System.Security.AccessControl.AccessControlSections]::All
    
    # construct the ACL by invoking the private ctor
    $securityACL = $registryACLPrivateConstructor.Invoke(@($hiveHandle, $keyPath, $sections))
    

    $securityACL now contains the security descriptor object corresponding to HKLM:\SECURITY