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 membership based on combination of two property values

May 05, 2021 Views: 1804

The script updates group membership of a user based on a combination of two property values.

Parameter:

  • $firstPropertyName - Specifies the LDAP name of the first property whose values will be taken into account to update group membership.
  • $secondPropertyName - Specifies the LDAP name of the second property whose values will be taken into account to update group membership.
  • $valuesToGroupDNs - Maps values of the properties specified in the $firstPropertyName and $secondPropertyName variables with the groups a user should be added to. The user will also be removed from all the groups specified in the mapping that do not match the user property values combination.
Edit Remove
PowerShell
$firstPropertyName = "l" # TODO: modify me
$secondPropertyName = "employeeType" # TODO: modify me
$valuesToGroupDNs = @{
    "NY" = @{
        "Fulltime" = @("CN=New York Full Time,OU=Groups,DC=Domain,DC=com", "CN=New York,OU=Groups,DC=Domain,DC=com");
        "Parttime" = @("CN=New York Part time,OU=Groups,DC=Domain,DC=com", "CN=New York,OU=Groups,DC=Domain,DC=com");
    }
    "WA" = @{
        "Fulltime" = @("CN=Washington Full Time,OU=Groups,DC=Domain,DC=com", "CN=Washington,OU=Groups,DC=Domain,DC=com");
        "Parttime" = @("CN=Washington Part time,OU=Groups,DC=Domain,DC=com", "CN=Washington,OU=Groups,DC=Domain,DC=com");
    }
} # TODO: modify me. Example: $valuesToGroupDNs = @{"<first property value>" = @{"<second property value>" = @("<Group DN 1>", "<Group DN 2>"); "<second property value>" = @("<Group DN 1>")}}

function SearchObjects($filter)
{
    # Set search parameters
    $domain = $Context.GetObjectDomain("%distinguishedName%")
    $searcher = $Context.BindToObject("Adaxes://$domain/rootDSE")
    $searcher.SearchFilter = $filter
    $searcher.SearchScope = "ADS_SCOPE_SUBTREE"
    $searcher.PageSize = 500
    $searcher.ReferralChasing = "ADS_CHASE_REFERRALS_NEVER"
    
    try
    {
        # Execute search
        $searchResultIterator = $searcher.ExecuteSearch()
        $searchResults = $searchResultIterator.FetchAll()
        
        return ,$searchResults
    }
    finally
    {
        # Release resources
        if ($searchResultIterator){ $searchResultIterator.Dispose() }
    }
}

function RemoveFromGroups ($groupDNsToSkip, $valuesToGroupDNs)
{
    $groupGuidsBytes = $Context.TargetObject.GetEx("adm-DirectMemberOfGuid")

    if ($groupGuidsBytes.Length -le 1 -and [System.String]::IsNullOrEmpty($groupDNsToSkip))
    {
        return
    }
    
    # Find groups
    # Build search filter
    $filter = New-Object "System.Text.StringBuilder"
    [void]$filter.Append("(&(objectCategory=group)")
    
    if ($groupDNsToSkip)
    {
        foreach ($dn in $groupDNsToSkip)
        {
            [void]$filter.Append("(!(distinguishedName=$dn))")
        }
    }
    
    $secondValuesInfo = $valuesToGroupDNs.Values
    $groupDNs = New-Object System.Collections.ArrayList
    foreach ($secondValueInfo in $secondValuesInfo)
    {
        $secondValueInfo.Keys | %%{[void]$groupDNs.AddRange($secondValueInfo[$_])}
    }
    [void]$filter.Append("(|")
    
    foreach ($dn in $groupDNs)
    {
        [void]$filter.Append("(distinguishedName=$dn)")
    }
    [void]$filter.Append(")(|")
    
    foreach ($guidBytes in $groupGuidsBytes)
    
    {
        [void]$filter.Append([Softerra.Adaxes.Ldap.FilterBuilder]::Create("objectGuid", $guidBytes))
    }
    
    [void]$filter.Append("))")
    $searchResults = SearchObjects $filter.ToString()

    if ($searchResults.Length -eq 0)
    {
        return
    }

    foreach ($searchResult in $searchResults)
    {
        # Remove user from group
        $group = $Context.BindToObjectEx($searchResult.AdsPath, $True)

        if ($group.Get("primaryGroupToken") -eq "%primaryGroupID%")
        {
            continue
        }

        $group.Remove($Context.TargetObject.AdsPath)
    }
}

# Get property values
try
{
    $firstValue = $Context.TargetObject.Get($firstPropertyName)
}
catch
{
    $firstValue = $NULL
}
try
{
    $secondValue = $Context.TargetObject.Get($secondPropertyName)
}
catch
{
    $secondValue = $NULL
}

if ([System.String]::IsNullOrEmpty($firstValue) -or [System.String]::IsNullOrEmpty($secondValue))
{
    # First property and/or Second property not specified
    # Remove from all groups specified in $valuesToGroupDNs
    RemoveFromGroups $NULL $valuesToGroupDNs
    return
}

# Get the DN of the group to add the user to
if (-not($valuesToGroupDNs.ContainsKey($firstValue)))
{
    # The First property value of the user wasn't found in $valuesToGroupDNs
    # Remove from all groups specified
    $Context.LogMessage("There is no group specified for property '$firstPropertyName' with value '$firstValue'", "Warning")
    RemoveFromGroups $NULL $valuesToGroupDNs
    return
}
$secondValueInfo = $valuesToGroupDNs[$firstValue]

if (-not($secondValueInfo.ContainsKey($secondValue)))
{
    # The Second property value of the user wasn't found in $valuesToGroupDNs
    # Remove from all groups specified
    $Context.LogMessage("There is no group specified for property '$secondPropertyName' with value '$secondValue'", "Warning")
    RemoveFromGroups $NULL $valuesToGroupDNs
    return
}
$groupDNs = $secondValueInfo[$secondValue]

# Update group membership
foreach ($dn in $groupDNs)
{
    $group = $Context.BindToObjectEx("Adaxes://$dn", $True)
    if (!$group.IsMember($Context.TargetObject.AdsPath))
    {
        $group.Add($Context.TargetObject.AdsPath)
    }
}

# Remove from other groups specified in $valuesToGroupDNs
RemoveFromGroups $groupDNs $valuesToGroupDNs

Comments 0
Leave a comment
Loading...

Got questions?

Support Questions & Answers