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.
Brilliant. Great stuff Tony much appreciated
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?
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
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
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.