The script adds a user to an AD group that is associated with the user's department and removes from groups associated with other departments.
To use the script, you need to create a business rule triggered automatically once a user is created or updated. For more information on how to automatically run a script once a new user is created, see Run PowerShell Script after Creating a User. Alternatively, you can schedule adding users to groups.
Parameters:
- $departmentProperty - Specifies the LDAP display name of the property that stores the name of the user's department.
- $groupNameTemplate - Specifies a template for names of groups that represent various departments. The {0} placeholder in the template will be replaced with the value of the property specified by $departmentProperty.
PowerShell
$departmentProperty = "department" # TODO: modify me
$groupNameTemplate = "Department_{0}_" # TODO: modify me
function SearchGroup ($filter, $list)
{
# Find groups
$searcher = $Context.BindToObject("Adaxes://RootDSE")
$searcher.SearchFilter = $filter
$searcher.PageSize = 500
$searcher.SearchScope = "ADS_SCOPE_SUBTREE"
$searcher.ReferralChasing = "ADS_CHASE_REFERRALS_NEVER"
$searcher.SetPropertiesToLoad(@("name"))
$searcher.VirtualRoot = $True
try
{
$searchResultIterator = $searcher.ExecuteSearch()
$searchResults = $searchResultIterator.FetchAll()
if ($list -ne $NULL)
{
foreach ($searchResult in $searchResults)
{
$list.Add($searchResult.AdsPath, $searchResult.Properties["name"].Value.ToString().ToLower())
}
}
elseif ($searchResults.Length -gt 1)
{
$Context.LogMessage("Found more than one group for department '$department'", "Warning")
return $NULL
}
elseif ($searchResults.Length -eq 0)
{
$Context.LogMessage("There is no group for department '$department'", "Warning")
return $NULL
}
else
{
return $searchResults[0].AdsPath
}
}
finally
{
# Release resources
$searchResultIterator.Dispose()
}
}
function UpdateGroupMembership ($groupPath, $groupName, $operation, $groupInfo)
{
if ($groupPath -eq $NULL)
{
return
}
$group = $Context.BindToObjectEx($groupPath, $True)
switch ($operation)
{
"Add"
{
try
{
$group.Add($Context.TargetObject.AdsPath)
$groupInfo.Add($groupPath, $groupName)
}
catch
{
$operationInfo = $group.GetLastOperationInfo()
if (-not([System.String]::IsNullOrEmpty($operationInfo.ExecutionLog.FirstErrorEntry)))
{
$Context.LogMessage("An error occurred when adding the user to group '$groupName'. Error: " + $_.Exception.Message, "Warning")
}
}
}
"Remove"
{
try
{
$group.Remove($Context.TargetObject.AdsPath)
}
catch
{
$operationInfo = $group.GetLastOperationInfo()
if (-not([System.String]::IsNullOrEmpty($operationInfo.ExecutionLog.FirstErrorEntry)))
{
$Context.LogMessage("An error occurred when removing the user from group '$groupName'. Error: " + $_.Exception.Message, "Warning")
}
}
}
}
}
# Get the user's department
try
{
$department = $Context.TargetObject.Get($departmentProperty)
}
catch
{
$department = $NULL
}
# Get names and paths of the groups the user is already a member of
try
{
$groupGuidsBytes = $Context.TargetObject.GetEx("adm-DirectMemberOfGuid")
}
catch
{
$groupGuidsBytes = @()
}
$groupInfo = @{}
if ($groupGuidsBytes.Length -ne 0)
{
# Build filter
$filter = New-Object "System.Text.StringBuilder"
$searchValue = [System.String]::Format($groupNameTemplate, "*")
[void]$filter.Append("(&(objectCategory=group)(name=$searchValue)(|")
foreach ($guidBytes in $groupGuidsBytes)
{
$filterPart = [Softerra.Adaxes.Ldap.FilterBuilder]::Create("objectGuid", $guidBytes)
[void]$filter.Append($filterPart)
}
[void]$filter.Append("))")
SearchGroup $filter.ToString() $groupInfo
}
if ($department -eq $NULL)
{
# Remove from all groups that belong to various departments
foreach ($path in $groupInfo.Keys)
{
UpdateGroupMembership $path $groupInfo[$path] "Remove"
}
return # Exit the script
}
else
{
$groupNameToSearch = [System.String]::Format($groupNameTemplate, $department).ToLower()
if (-not($groupInfo.ContainsValue($groupNameToSearch)))
{
# Add to group
$groupPath = SearchGroup "(&(objectCategory=group)(name=$groupNameToSearch))" $NULL
UpdateGroupMembership $groupPath $groupNameToSearch "Add" $groupInfo
}
}
# Check whether it is necessary to remove the user from groups for other departments
if ($groupInfo.ContainsValue($groupNameToSearch))
{
foreach ($path in $groupInfo.Keys)
{
$groupName = $groupInfo[$path]
if ($groupName -eq $groupNameToSearch)
{
continue
}
UpdateGroupMembership $path $groupInfo[$path] "Remove"
}
}