Skip to content

Instantly share code, notes, and snippets.

@davegreen
Last active October 1, 2021 09:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davegreen/368303ff31ed7c0036d6e53debebccca to your computer and use it in GitHub Desktop.
Save davegreen/368303ff31ed7c0036d6e53debebccca to your computer and use it in GitHub Desktop.
This function sets the AD permissions required for MIM to perform GALSync operations. It does this by adding the required new permissions for the GALSync group to AD.
Function Set-IdentityManagementGalAdPermission {
<#
.Synopsis
A function that sets the permissions in Active Directory (AD) required for Microsoft Identity Manager (MIM) to perform Global Address List (GAL) sync operations.
.Description
This function sets the AD permissions required for MIM to perform GALSync operations. It does this by adding the required new permissions for the GALSync group to at least three places in the AD.
The GALSync group requires permissions to AD for the following:
The extended right DS-Replication-Get-Changes on the domain root to read directory changes.
Write the ProxyAddresses attribute on the GALSync source OUs.
Create and delete objects, as wekk as write properties of these objects in the GALSync target directory.
.Parameter Identity
The object name or SamAccountName of the group to provide the required AD permissions. This parameter is mandatory.
.Parameter SourceDn
The distinguished name (or an array of distinguished names) of the source OU(s) for objects read from theis directory into MIM. This parameter is mandatory.
The permission granted allows MIM to write to the ProxyAddresses attribute of child objects of these OUs.
.Parameter TargetDn
The distinguished name of the target OU for objects created in the directory by MIM. This parameter is mandatory.
The permissions granted allow MIM to create and delete child objects of this OU, as well as write to all child object properties.
.Parameter DomainRootDn
The distinguished name of the domain root object (like 'DC=example,DC=com') to apply the DS-Replication-Get-Changes permission to. This parameter is optional and defaults to the current domain if not specified.
.Example
Set-IdentityManagementGalAdPermission -Identity 'GALSync Management Agents' -SourceDn "OU=Users,OU=TestOrg,DC=example,DC=com", "OU=Contractors,OU=TestOrg,DC=example,DC=com" -TargetDn "OU=SyncedContacts,OU=TestOrg,DC=example,DC=com"
Run from a machine in the example.com domain, this will create the rights at the domain root and the specified source and target OUs.
.Example
Set-IdentityManagementGalAdPermission -Identity 'GALSync Management Agents' -SourceDn "OU=Users,OU=TestOrg,DC=example,DC=com" -TargetDn "OU=SyncedContacts,OU=TestOrg,DC=example,DC=com" -DomainRootDn "DC=example,DC=com"
Run from a machine in the example.com domain, this will create the rights at the domain root with the specified domain root distinguished name and the specified source and target OUs.
.Notes
Author: David Green (http://tookitaway.co.uk/)
#>
[CmdletBinding(
SupportsShouldProcess = $True,
ConfirmImpact = 'High'
)]
Param(
[parameter(
Mandatory = $True
)]
[ValidateScript({
(Get-AdGroup -Identity $_).ObjectClass -eq 'group'
})]
[Microsoft.ActiveDirectory.Management.ADGroup]$Identity,
[parameter(
Mandatory = $True
)]
[ValidateScript({
$_ | ForEach-Object {
(Get-AdObject -Identity $_).ObjectClass -eq 'organizationalUnit' -or 'container'
}
})]
[string[]]$SourceDn,
[parameter(
Mandatory = $True
)]
[ValidateScript({
(Get-AdObject -Identity $_).ObjectClass -eq 'organizationalUnit'
})]
[string]$TargetDn,
[parameter(
Mandatory = $False
)]
[ValidateScript({
(Get-AdObject -Identity $_).ObjectClass -eq 'domainDNS'
})]
[string]$DomainRootDn = ([ADSI]'').DistinguishedName
)
Import-Module ActiveDirectory # Loads the AD:\ drive we will be using to grab the ACL.
$DsReplicationGuid = [guid]'1131f6aa-9c07-11d1-f79f-00c04fc2dcd2' # DS-Replication-Get-Changes attribute.
$ProxyGuid = [guid]'bf967a06-0de6-11d0-a285-00aa003049e2' # ProxyAddresses attribute.
$nullGUID = [guid]'00000000-0000-0000-0000-000000000000'
$NTAccount = New-Object -TypeName System.Security.Principal.NTAccount("$($env:USERDOMAIN)\$Identity")
$RootAcl = Get-Acl -Path "AD:\$DomainRootDn"
$TargetAcl = Get-Acl -Path "AD:\$TargetDn"
# Domain root rights.
$RootAce = New-Object -TypeName System.DirectoryServices.ActiveDirectoryAccessRule $NTAccount, 'ExtendedRight', 'Allow', $DsReplicationGuid, 'None' -ErrorAction Stop
$RootAcl.psbase.AddAccessRule($RootAce)
if ($PSCmdlet.ShouldProcess($RootAcl.Path)) {
Set-Acl -Path $RootAcl.Path -AclObject $RootAcl -ErrorAction Stop
}
# Source OU rights.
foreach ($Sdn in $SourceDn) {
$SourceAcl = Get-Acl -Path "AD:\$Sdn"
$SourceAce = New-Object -TypeName System.DirectoryServices.ActiveDirectoryAccessRule $NTAccount, 'WriteProperty', 'Allow', $ProxyGuid, 'Descendents' -ErrorAction Stop
$SourceAcl.psbase.AddAccessRule($SourceAce)
if ($PSCmdlet.ShouldProcess($SourceAcl.Path)) {
Set-Acl -Path $SourceAcl.Path -AclObject $SourceAcl -ErrorAction Stop
}
}
# Target OU Rights.
$TargetAce = New-Object -TypeName System.DirectoryServices.ActiveDirectoryAccessRule $NTAccount, 'CreateChild, DeleteChild, ReadProperty, WriteProperty, GenericExecute', 'Allow', $nullGUID, 'All' -ErrorAction Stop
$TargetAcl.psbase.AddAccessRule($TargetAce)
if ($PSCmdlet.ShouldProcess($TargetAcl.Path)) {
Set-Acl -Path $TargetAcl.Path -AclObject $TargetAcl -ErrorAction Stop
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment