Here’s a Powershell script I wrote to delegate permissions to a service account to manage user objects within a number of OUs. The script takes as input a file containing the distinguished names (DNs) of the OUs. The approach should be reasonably obvious from the comments in the script. The only complexity comes from having to get the correct System.DirectoryServices syntax for the Access Control Entries (ACEs).
######################################################### # # Name: Add-UserOUACEs.ps1 # Author: Tony Murray # Version: 1.0 # Date: 16/04/2012 # Comment: PowerShell script to add Access Control # entries to a target object # ######################################################### Write-Verbose "Script starting..." # Import the AD module ipmo ActiveDirectory # Set the verbosity preference $VerbosePreference = "Continue" # Default is "SilentlyContinue", i.e. no verbosity ### Set Global Variables # Specify the import file to use $impfile = "c:\User_OUs.txt" # Specify the security principal to which perms will be granted $svc = Get-ADUser MyServiceAccount # Get the SID of the security principal $sid = new-object System.Security.Principal.SecurityIdentifier $svc.SID ### # Change to the AD drive CD AD: $ous = Import-Csv $impfile foreach ($dn in $ous) { $ou = $dn.distinguishedname ## Get the DACL of the OU $acl = get-acl $ou ## Note that bf967aba-0de6-11d0-a285-00aa003049e2 is the schemaIDGuid for the user object class. $guid = new-object Guid bf967aba-0de6-11d0-a285-00aa003049e2 # ACE for creating and deleting child User objects $ace1 = new-object System.DirectoryServices.ActiveDirectoryAccessRule $sid,"CreateChild,DeleteChild","Allow",$guid # ACE for full control over descendent User objects $ace2 = new-object System.DirectoryServices.ActiveDirectoryAccessRule $sid,"GenericAll","Allow","Descendents ",$guid ## Add the ACE in the ACL and set the ACL on the object $acl.AddAccessRule($ace1) $acl.AddAccessRule($ace2) Write-Verbose "Adding ACEs to ACL on $ou" set-acl -aclobject $acl $ou # Clean up variables used in ForEach loop Clear-Variable -ErrorAction SilentlyContinue -Name dn Clear-Variable -ErrorAction SilentlyContinue -Name ou Clear-Variable -ErrorAction SilentlyContinue -Name acl Clear-Variable -ErrorAction SilentlyContinue -Name guid Clear-Variable -ErrorAction SilentlyContinue -Name ace1 Clear-Variable -ErrorAction SilentlyContinue -Name ace2 } # End foreach loop # Clean up Global Variables Write-Verbose "Cleaning global variables..." Clear-Variable -ErrorAction SilentlyContinue -Name impfile Clear-Variable -ErrorAction SilentlyContinue -Name sid Clear-Variable -ErrorAction SilentlyContinue -Name svc Clear-Variable -ErrorAction SilentlyContinue -Name ous # End Write-Verbose "Script finished" $VerbosePreference = "SilentlyContinue"