While Exchange Dynamic Distribution Lists handle email groups perfectly, they can't be used for security permissions or resource access control. Many administrators need to create security groups that automatically include all users from specific OUs without manual maintenance.
Here's a complete PowerShell script that creates and maintains a dynamic security group based on OU membership:
# Import Active Directory module
Import-Module ActiveDirectory
# Configuration parameters
$TargetOU = "OU=Sales,DC=contoso,DC=com"
$GroupName = "Dynamic_Sales_Users"
$GroupDescription = "Automatically includes all users from Sales OU"
# Create the group if it doesn't exist
if (-not (Get-ADGroup -Filter {Name -eq $GroupName})) {
New-ADGroup -Name $GroupName -GroupScope Global -GroupCategory Security
-Description $GroupDescription -Path "OU=Groups,DC=contoso,DC=com"
}
# Get current group members
$CurrentMembers = Get-ADGroupMember -Identity $GroupName | Select-Object -ExpandProperty DistinguishedName
# Get all users in the target OU (including sub-OUs)
$OUUsers = Get-ADUser -Filter * -SearchBase $TargetOU -SearchScope Subtree |
Select-Object -ExpandProperty DistinguishedName
# Find users to add (in OU but not in group)
$UsersToAdd = $OUUsers | Where-Object {$CurrentMembers -notcontains $_}
# Find users to remove (in group but not in OU)
$UsersToRemove = $CurrentMembers | Where-Object {$OUUsers -notcontains $_}
# Modify group membership
if ($UsersToAdd) {
Add-ADGroupMember -Identity $GroupName -Members $UsersToAdd
}
if ($UsersToRemove) {
Remove-ADGroupMember -Identity $GroupName -Members $UsersToRemove -Confirm:$false
}
To keep the group membership current, schedule this script to run periodically using Task Scheduler:
$Trigger = New-ScheduledTaskTrigger -Daily -At 3am
$Action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-File C:\scripts\Update-DynamicGroup.ps1"
Register-ScheduledTask -TaskName "Update Dynamic AD Group" -Trigger $Trigger -Action $Action -RunLevel Highest
You can enhance the user selection with additional filters. For example, to only include enabled accounts:
$OUUsers = Get-ADUser -Filter {Enabled -eq $true} -SearchBase $TargetOU -SearchScope Subtree
Or combine multiple conditions:
$OUUsers = Get-ADUser -Filter {
Enabled -eq $true -and
Department -eq "Sales" -and
Title -like "*Manager*"
} -SearchBase $TargetOU
For GUI-based solutions, you can use the Active Directory Administrative Center:
- Open ADAC and navigate to the target OU
- Right-click → New → Group
- Create a security group
- Use the "Dynamic Members" tab to define inclusion rules
While Exchange Dynamic Distribution Lists provide excellent email grouping functionality, they don't solve the need for dynamic security groups in Active Directory. The fundamental requirement is to automatically include/exclude users based on their Organizational Unit (OU) location without manual maintenance.
Active Directory doesn't natively support dynamic security groups based on OU membership. Here are your main options:
# PowerShell script to create and maintain dynamic group membership
Import-Module ActiveDirectory
# Parameters
$TargetOU = "OU=Sales,DC=domain,DC=com"
$GroupName = "Dynamic_Sales_Users"
# Create group if it doesn't exist
if (-not (Get-ADGroup -Filter {Name -eq $GroupName})) {
New-ADGroup -Name $GroupName -GroupScope Global -GroupCategory Security
}
# Get current members and desired members
$CurrentMembers = Get-ADGroupMember -Identity $GroupName | Select-Object -ExpandProperty DistinguishedName
$DesiredMembers = Get-ADUser -Filter * -SearchBase $TargetOU | Select-Object -ExpandProperty DistinguishedName
# Add missing members
$UsersToAdd = $DesiredMembers | Where-Object {$_ -notin $CurrentMembers}
$UsersToAdd | ForEach-Object {
Add-ADGroupMember -Identity $GroupName -Members $_
}
# Remove stale members
$UsersToRemove = $CurrentMembers | Where-Object {$_ -notin $DesiredMembers}
$UsersToRemove | ForEach-Object {
Remove-ADGroupMember -Identity $GroupName -Members $_ -Confirm:$false
}
For automatic updates, create a scheduled task that runs this script periodically (e.g., every 15 minutes):
# Create scheduled task action
$Action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File C:\Scripts\UpdateDynamicGroup.ps1"
# Create trigger (runs every 15 minutes)
$Trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 15)
# Register the task
Register-ScheduledTask -TaskName "Update Dynamic AD Groups" -Action $Action -Trigger $Trigger -RunLevel Highest
While not perfect, you can use LDAP filter groups with limited OU-based capabilities:
# Create group with LDAP filter
New-ADGroup -Name "LDAPFilterGroup" -GroupScope Global -GroupCategory Security -LDAPFilter "(memberOf:1.2.840.113556.1.4.1941:=CN=SalesOU,DC=domain,DC=com)"
Note that this method has limitations with nested OUs and requires specific AD functional levels.
When implementing these solutions:
- For environments with >5,000 users, consider running updates during off-peak hours
- Cache results when possible to reduce AD queries
- Implement error handling for scenarios where users are moved during script execution