Zoho Banner September 2011

Unfortunately Active Directory doesn’t yet provide dynamic security groups in the way that, for example, Exchange provides dynamic distribution groups.  Sometimes it is useful to maintain a group’s membership based on a specific attribute, or set of attributes.  Here’s a quick Powershell example that shows how to maintain the membership based on the presence of a single attribute value.

You can download the script here: AttributeBasedGroupMembership

 

#########################################################
#
# Name: AttributeBasedGroupMembership.ps1
# Author: Tony Murray
# Version: 1.0
# Date: 18/06/2015
# Comment: PowerShell 2.0 script to manage group 
# membership based on attribute values
#
#########################################################

# Import the AD module
ipmo ActiveDirectory

# Define arrays to be used for matching
$arratt = @()
$arrgp = @()

# Domain controller to be used
$dc = (Get-ADRootDSE).dnshostname
write-host "Using DC $dc for all AD reads/writes"

# Specify the OU where the accounts are located
$OUdn = "OU=Corp Users,DC=Contoso,DC=com"

# Find all the objects that have the specified attribute value
$AttUsrs = Get-ADUser -LDAPFilter "(extensionattribute1=Sales)" -SearchBase $oudn -Server $dc

# Specify the GUID of the group to use
# You could also use name of group (but this can be changed)
$grp = "7bbf64bc-46c7-4a90-9d58-7cb5eca35fce" # i.e. "Sales Team"

# Find all the group members
$grpusers = Get-ADGroupMember -Identity $grp -Server $dc

# Build arrays using the DN attribute value
$AttUsrs | % {$arratt += $_.distinguishedname}
$grpusers | % {$arrgp += $_.distinguishedname}


# Add to group membership (newly assigned attribute value)
foreach ($usr in $arratt) {
    if ($arrgp -contains $usr) {
        write-host "User $usr is a member of the group"
    }
    else {
        write-host "User $usr is not a member of the group - adding..."
        Add-ADGroupMember -Identity $grp -Members $usr -Server $dc
    } # end else
    Remove-Variable -ErrorAction SilentlyContinue -Name usr    
} # end foreach

write-host "`n"

# Remove from group (no longer has attribute value or has been manually added to group)
# Assumption here is that the attribute value is authoritative for the group's membership
foreach ($mem in $arrgp) {
    if ($arratt -contains $mem) {
        write-host "User $mem still has the attribute value.  Nothing to do"
    } # end if
    else {
        write-host "User $mem does not have the attribute value.  Removing from membership..."
        Remove-ADGroupMember -Identity $grp -Members $mem -Server $dc -Confirm:$false
    } # end else
    Remove-Variable -ErrorAction SilentlyContinue -Name mem
} # end foreach

 

To ensure the script is run regularly, you would likely want to call it from a scheduled task.

 

 

5 Comments

  1. KP says:

    Brilliant. Great stuff Tony much appreciated

  2. Flemming Steffensen says:

    Looks like something I can use, but one thing eludes me…
    How do I modify this script to allow me to sign in to a specific AD by providing host address, login name and password?

  3. Flemming Steffensen says:

    I ended up creating my own script to create a shadow-group while using alternate credentials.
    It’s available here: http://fsteff.blogspot.com/2015/10/adldap-user-directories-setup-in.html

  4. PW says:

    Nice script. The issue I ran into was the limited result size of get-adgroupmember. A more universal option for building that array would be:

    $grpusers = Get-ADGroup $grp -Properties member | Select-Object -ExpandProperty member

  5. Matthias says:

    We used a script similar to this before in our projects. As the requirements were changing during the projects, we decided to develope a software called FirstWare DynamicGroup (www.firstattribute.com/en/software/firstware-dynamicgroup/). Besides attribute based groups you can set include and exlude filters and so on.

Leave a Reply