1

The below code will return generic OU permissions

Import-Module ActiveDirectory
set-location AD:
$OUAcl = (Get-Acl 'OU=ParentOU,OU=ChildOU,DC=test,DC=test,DC=com').Access 
$OUAcl

However what I want to audit is the advanced security permissions. I can view this in the GUI, I just can't figure out how to script it to generate a report for every OU in my organization (or specific OU's depending on our needs).

To view in the GUI do this:

  1. Open MMC and load the ADUC snapin
  2. Enable View → Advanced Features
  3. Right-click any OU, choose Properties
  4. Choose the Security tab on the properties window
  5. Click the Advanced button.
  6. View all the users/groups that have permissions to that OU.

What I want is a report that can dump out every user and group that has access to the OU, and all of their advanced permissions (eg: anything in step 6 that has the box checkes whether it's allow or deny).

I found this site, but it doesn't get to the detail I need.

Is this possible through PowerShell?

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
user3246693
  • 679
  • 11
  • 22

2 Answers2

2

I made a module a while back that I think does what you're looking for, which can be found here (try the version 4 download first). Then you can do something like this:

Get-ADOrganizationalUnit -Filter * | 
    Get-PacAccessControlEntry | 
    Export-Csv c:\ou_permissions.csv -NoTypeInformation

If you use version 3, the command would be 'Get-AccessControlEntry'. Version 3 is a script module, so you can open the files to see exactly what's going on and what it takes to translate the ACEs (which are more complicated that your normal filesystem/registry/service/etc ACE) into a more readable format. Version 4 is compiled, but you can find the source code here.

dsacls.exe can get this information, too, but you'd probably have to do some text parsing to get it in a friendlier format...

Rohn Edwards
  • 2,499
  • 1
  • 14
  • 19
0

It's certainly possible, but I'm not aware of a ready-made solution for what you want. You need to resolve the individual access rights for each ACE yourself. Something like this should work:

$dn = 'OU=ParentOU,OU=ChildOU,DC=test,DC=test,DC=com'

$ADS_RIGHTS_ENUM = @{
  'ADS_RIGHT_DELETE'                 = 0x10000
  'ADS_RIGHT_READ_CONTROL'           = 0x20000
  'ADS_RIGHT_WRITE_DAC'              = 0x40000
  'ADS_RIGHT_WRITE_OWNER'            = 0x80000
  'ADS_RIGHT_SYNCHRONIZE'            = 0x100000
  'ADS_RIGHT_ACCESS_SYSTEM_SECURITY' = 0x1000000
  'ADS_RIGHT_GENERIC_READ'           = 0x80000000
  'ADS_RIGHT_GENERIC_WRITE'          = 0x40000000
  'ADS_RIGHT_GENERIC_EXECUTE'        = 0x20000000
  'ADS_RIGHT_GENERIC_ALL'            = 0x10000000
  'ADS_RIGHT_DS_CREATE_CHILD'        = 0x1
  'ADS_RIGHT_DS_DELETE_CHILD'        = 0x2
  'ADS_RIGHT_ACTRL_DS_LIST'          = 0x4
  'ADS_RIGHT_DS_SELF'                = 0x8
  'ADS_RIGHT_DS_READ_PROP'           = 0x10
  'ADS_RIGHT_DS_WRITE_PROP'          = 0x20
  'ADS_RIGHT_DS_DELETE_TREE'         = 0x40
  'ADS_RIGHT_DS_LIST_OBJECT'         = 0x80
  'ADS_RIGHT_DS_CONTROL_ACCESS'      = 0x100
}

Import-Module ActiveDirectory

$acl = Get-Acl "AD:$dn"
foreach ($ace in $acl.Access) {
  $ADS_RIGHTS_ENUM.Keys | Where-Object {
    $ace.ActiveDirectoryRights.value__ -band $ADS_RIGHTS_ENUM[$_]
  } | ForEach-Object {
    "{0}`t{1}`t{2}" -f $ace.IdentityReference, $_, $ace.AccessControlType
  }
}
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
  • Thank you, I've been trying to parse out all the ACE codes and that's proven to be a real pain. That said Rohn Edwards script seems to do this all for me. – user3246693 Jan 11 '16 at 22:56