How To Document OU Delegation

OU delegation Active Directory

Delegation of rights on your Active Directory OU’s is standard practice in any AD. Delegation allows you to grant limited access in various scenarios:

  • Enable your first level helpdesk to reset passwords (only)
  • Allow your HR service account to modify a limited set of user properties (only)
  • Allow your Dynamic Group service to modify group membership (only)
  • etc…

Without a well-defined strategy, the OU delegation can become a mess after some time.

This article will show you how to get back on top of your OU delegation. With a simple PowerShell script, you can extract an overview of your delegation and maybe identify some clean-up candidates.

(If you’re looking for information on GPO security filtering, have a look at this article)

Extract OU Delegation With PowerShell

Fire up a PowerShell prompt! First, make sure you have the Active Directory PowerShell module available (use a DC or install the Remote Server Administration Tools).

OU’s can be easily “grabbed” using the following command:

$OUs = Get-ADOrganizationalUnit -Filter *

To get the ACL (Access Control List) of a given OU, you can use the following command:

(Get-Acl -Path $OU.DistinguishedName).Access

A lot of ACLs exist on every OU, but most of them are inherited. Therefore, to identify what custom delegation has been made in your AD, you should focus only on non-inherited ACLs.

The below script uses the above commands to:

  • Get all OU’s in your AD
  • Get all ACL’s set up on all the OU’s
  • List all the ACL’s that are not inherited

This is how it goes:

# Set up output file
$File = "OU_Delegation.txt"
"Path;ID;Rights;Type" | Out-File $File
# Import AD module
Import-Module ActiveDirectory
# Get all OU's in the domain
$OUs = Get-ADOrganizationalUnit -Filter *
$Result = @()
ForEach($OU In $OUs){
    # Get ACL of OU
    $Path = "AD:\" + $OU.DistinguishedName
    $ACLs = (Get-Acl -Path $Path).Access
    ForEach($ACL in $ACLs){
        # Only examine non-inherited ACL's
        If ($ACL.IsInherited -eq $False){
            # Objectify the result for easier handling
            $Properties = @{
                ACL = $ACL
                OU = $OU.DistinguishedName
                }
            $Result += New-Object psobject -Property $Properties
        }
    }
}
ForEach ($Item In $Result){
    $Output = $Item.OU + ";" + $Item.ACL.IdentityReference + ";" + $Item.ACL.ActiveDirectoryRights + ";" + $Item.ACL.AccessControlType
    $Output | Out-File $File -Append
    Write-Host $Output
}

It’s only a couple of lines of code that does the actual work. The rest is about formatting the result for easy import to Excel.

Your output may look similar to this (but much larger):

OU=Admins,DC=gigacorp,DC=local;Everyone;DeleteChild, DeleteTree, Delete;Deny
OU=Admins,DC=gigacorp,DC=local;NT AUTHORITY\ENTERPRISE DOMAIN CONTROLLERS;GenericRead;Allow
OU=Admins,DC=gigacorp,DC=local;NT AUTHORITY\Authenticated Users;GenericRead;Allow
OU=Admins,DC=gigacorp,DC=local;NT AUTHORITY\SYSTEM;GenericAll;Allow
OU=Admins,DC=gigacorp,DC=local;GIGACORP\Domain Admins;GenericAll;Allow
OU=Admins,DC=gigacorp,DC=local;BUILTIN\Account Operators;CreateChild, DeleteChild;Allow
OU=Admins,DC=gigacorp,DC=local;BUILTIN\Account Operators;CreateChild, DeleteChild;Allow
OU=Admins,DC=gigacorp,DC=local;BUILTIN\Account Operators;CreateChild, DeleteChild;Allow
OU=Admins,DC=gigacorp,DC=local;BUILTIN\Account Operators;CreateChild, DeleteChild;Allow
OU=Admins,DC=gigacorp,DC=local;BUILTIN\Print Operators;CreateChild, DeleteChild;Allow
OU=Serveradmins,OU=Admins,DC=gigacorp,DC=local;Everyone;DeleteTree, Delete;Deny
OU=Serveradmins,OU=Admins,DC=gigacorp,DC=local;NT AUTHORITY\ENTERPRISE DOMAIN CONTROLLERS;GenericRead;Allow
OU=Serveradmins,OU=Admins,DC=gigacorp,DC=local;NT AUTHORITY\Authenticated Users;GenericRead;Allow
OU=Serveradmins,OU=Admins,DC=gigacorp,DC=local;NT AUTHORITY\SYSTEM;GenericAll;Allow
OU=Serveradmins,OU=Admins,DC=gigacorp,DC=local;GIGACORP\Domain Admins;GenericAll;Allow
OU=Serveradmins,OU=Admins,DC=gigacorp,DC=local;BUILTIN\Account Operators;CreateChild, DeleteChild;Allow
OU=Serveradmins,OU=Admins,DC=gigacorp,DC=local;BUILTIN\Account Operators;CreateChild, DeleteChild;Allow
OU=Serveradmins,OU=Admins,DC=gigacorp,DC=local;BUILTIN\Account Operators;CreateChild, DeleteChild;Allow
OU=Serveradmins,OU=Admins,DC=gigacorp,DC=local;BUILTIN\Account Operators;CreateChild, DeleteChild;Allow
OU=Serveradmins,OU=Admins,DC=gigacorp,DC=local;BUILTIN\Print Operators;CreateChild, DeleteChild;Allow
OU=GlobalAdmins,OU=Admins,DC=gigacorp,DC=local;Everyone;DeleteTree, Delete;Deny
OU=GlobalAdmins,OU=Admins,DC=gigacorp,DC=local;NT AUTHORITY\ENTERPRISE DOMAIN CONTROLLERS;GenericRead;Allow
OU=GlobalAdmins,OU=Admins,DC=gigacorp,DC=local;NT AUTHORITY\Authenticated Users;GenericRead;Allow
OU=GlobalAdmins,OU=Admins,DC=gigacorp,DC=local;NT AUTHORITY\SYSTEM;GenericAll;Allow
OU=GlobalAdmins,OU=Admins,DC=gigacorp,DC=local;GIGACORP\Domain Admins;GenericAll;Allow
OU=GlobalAdmins,OU=Admins,DC=gigacorp,DC=local;BUILTIN\Account Operators;CreateChild, DeleteChild;Allow
OU=GlobalAdmins,OU=Admins,DC=gigacorp,DC=local;BUILTIN\Account Operators;CreateChild, DeleteChild;Allow
OU=GlobalAdmins,OU=Admins,DC=gigacorp,DC=local;BUILTIN\Account Operators;CreateChild, DeleteChild;Allow
OU=GlobalAdmins,OU=Admins,DC=gigacorp,DC=local;BUILTIN\Account Operators;CreateChild, DeleteChild;Allow
OU=GlobalAdmins,OU=Admins,DC=gigacorp,DC=local;BUILTIN\Print Operators;CreateChild, DeleteChild;Allow

Analyze OU Delegation With Excel

Once you have exported the data with the previous script, it’s time to give it a closer look using Excel.

Copy the contents of the output file, “OU_Delegation.txt” into Excel, use semicolon as column separator, and create a filter on the top row:

OU Delegation AD

By far, the main content of this file will be standard OU delegation. Standard delegation is default access granted by the system to provide a standard functional Active Directory.

To identify custom delegation, you should make a filter on the ID column to remove any NT AUTHORITY, BUILTIN, EXCHANGE, and well-known SIDs. This includes the following (and possibly more depending on your installation):

  • NT AUTHORITY\Authenticated Users
  • NT AUTHORITY\ENTERPRISE DOMAIN CONTROLLERS
  • NT AUTHORITY\SYSTEM
  • BUILTIN\Account Operators
  • BUILTIN\Print Operators
  • GIGACORP\Domain Admins
  • GIGACORP\Exchange Trusted Subsystem
  • GIGACORP\Organization Management

You should also filter out Deny entries granted by default to Everyone to avoid accidental deletion of OUs.

Once the filtering is set, have a careful look at the rest of the entries. Then you’ll get a perfect picture of the custom delegation in your domain!

In my small test setup, I found this entry:

OU Delegation Active Directory

Maybe this custom delegation is something I want, or perhaps it’s a cleanup candidate.

You can check the security tab of the OU properties for further details on the configured access:

Active Directory OU Properties

And if you click “Advanced” you’ll be able to see specifically what access is granted to which object types in the OU:

OU properties Active Directory

Summary

And there you have it. Getting an overview of custom delegation on OU’s in your Active Directory may appear a daunting task. But it’s actually relatively easy to achieve.

Delegation of access rights on Active Directory OU’s should always adhere to the Principle of Least Privilege. Using PowerShell and Excel, you can quickly examine your setup in depth.

If your AD is synchronized with Office 365 and you like to manage it in the easiest way possible, please have a look at Easy365Manager.

Easy365Manager is a small but powerful snap-in to AD Users & Computers that lets you manage email properties, Office 365 licenses, and mailboxes inside AD user properties:

easy365manager ui
easy365manager ui

With Easy365Manager, you can do all your daily Office 365 management inside AD Users & Computers. There’s no longer any need to go to the Exchange Online Admin Center, the Microsoft 365 Admin Center, or the Azure Portal.

You can even remove your on-premise Exchange Server as Easy365Manager lets you manage all mail attributes. This gives you 100% protection from Exchange on-premises 0-day exploits.

Download Easy365Manager for a 30-day free trial run. You can download, install and configure Easy365Manager in just a couple of minutes: