Script Repository


Update group memberships of user based on department

December 26, 2016
1636

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.

Edit Remove
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"
    }
}


Comments ( 0 )
No results found.
Leave a comment