I've created a Powershell function Copy-DsAcl
which should assist with performing this sort of Active Directory permissions copy. Using this function, the original answer (below the line) may be rewritten more cleanly as:
Import-Module ActiveDirectory
# Dot source the Copy-DsAcl function: https://github.com/jasonkeithscott/Copy-DsAcl
. .\Copy-DsAcl.ps1
# Reference objects
$sourceGroup = Get-ADGroup Limited_IT_Admins
$sourceObject = Get-ADOrganizationalUnit -Filter { Name -eq "City01" }
# Hash for the new groups and their assigned OUs
$targetGroups = @{}
$targetGroups.Add("Limited_IT_Admin_01", @("City01", "City02", "City03"))
$targetGroups.Add("Limited_IT_Admin_02", @("City04", "City05"))
$targetGroups.Add("Limited_IT_Admin_03", @("City06", "City07"))
# Walk each targetGroup in the hash
foreach ( $g in $targetGroups.GetEnumerator() ) {
$targetGroup = Get-ADGroup $g.Name
# Walk each $city OU and add the $targetGroup to the ACL
foreach ( $city in $g.Value ) {
Write-Host "Adding $($g.Name) to $city"
$targetObject = Get-ADOrganizationalUnit -Filter { Name -eq $city }
Copy-DsAcl $sourceGroup $sourceObject $targetGroup $targetObject
}
}
The Powershell below should do what you're asking. There are a few requirements:
- You need the Microsoft ActiveDirectory Powershell module. It's included with RSAT7.
- You need to update the following for your environment:
$root
- the PSDrive to your "root" OU. "Country" in your question.
$sourceOU
- the source OU (name, not DN) from which you will copy the ACEs.
$sourceGroup
- the group (name, not DN or domain) listed in the ACL which you will copy.
$targetGroups
- Hash of groups (name, not DN or domain) and OUs (name, not DN) for applying the ACEs.
- This will only copy explicit ACEs, not inherited. Maybe I should look at walking up the tree to grab the inherited ones?
- I had to run this as Domain Admin as I was getting "Access Denied" errors. My initial OU delegations were probably suspect though.
Reading all this over I think I should probably just write a more generic function, CopyOuAcl
, and update this when that's done. As it is written now, it is completely specific to your question and environment.
Import-Module ActiveDirectory
$root = "AD:\OU=Country,DC=example,DC=com"
$sourceOU = "City01"
$sourceACL = Get-Acl $root.Replace("AD:\", "AD:\OU=$sourceOU,")
$sourceGroup = "Limited_IT_Admins"
# Hash for the new groups and their OUs
$targetGroups = @{}
$targetGroups.Add("Limited_IT_Admin_01", @("City01", "City02", "City03"))
$targetGroups.Add("Limited_IT_Admin_02", @("City04", "City05"))
$targetGroups.Add("Limited_IT_Admin_03", @("City06", "City07"))
# Get the uniherited ACEs for the $sourceGroup from $sourceOU
$sourceACEs = $sourceACL |
Select-Object -ExpandProperty Access |
Where-Object { $_.IdentityReference -match "$($sourceGroup)$" -and $_.IsInherited -eq $False }
# Walk each targetGroup in the hash
foreach ( $g in $targetGroups.GetEnumerator() ) {
# Get the AD object for the targetGroup
Write-Output $g.Name
$group = Get-ADGroup $g.Name
$identity = New-Object System.Security.Principal.SecurityIdentifier $group.SID
# Could be multiple ACEs for the sourceGroup
foreach ( $a in $sourceACEs ) {
# From from the sourceACE for the ActiveDirectoryAccessRule constructor
$adRights = $a.ActiveDirectoryRights
$type = $a.AccessControlType
$objectType = New-Object Guid $a.ObjectType
$inheritanceType = $a.InheritanceType
$inheritedObjectType = New-Object Guid $a.InheritedObjectType
# Create the new "copy" of the ACE using the target group. http://msdn.microsoft.com/en-us/library/w72e8e69.aspx
$ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $identity, $adRights, $type, $objectType, $inheritanceType, $inheritedObjectType
# Walk each city OU of the target group
foreach ( $city in $g.Value ) {
Write-Output "`t$city"
# Set the $cityOU
$cityOU = $root.Replace("AD:\", "AD:\OU=$city,")
# Get the ACL for $cityOU
$cityACL = Get-ACL $cityOU
# Add it to the ACL
$cityACL.AddAccessRule($ace)
# Set the ACL back to the OU
Set-ACL -AclObject $cityACL $cityOU
}
}
}
If I had to guess, the group type was change from security to distribution. This way if something breaks, the group type can be changed back to security while retaining the same security identifier.
You can find the attributes that have recently changed by using the command:
repadmin /showobjmeta dcName "[Distinguished name of group]"
Best Answer
Security groups can be associated with ACLs, whereas distribution groups can't.
Both security groups and distribution groups can be mail enabled.
http://technet.microsoft.com/en-us/library/cc781446(v=ws.10).aspx