We use cookies to improve your experience.
By your continued use of this site you accept such use.
For more details please see our privacy policy and cookies policy.

Script Repository

Update group memberships of user based on department

February 24, 2021 Views: 2862

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
Leave a comment
Loading...

Got questions?

Support Questions & Answers