The Ask

Since there are no dynamic groups in AD I was tasked with creating a PowerShell script to sync the contents of an OU with a Security group. In this script, it will remove users from the group that are disabled and in the specific OU and if the user account is taken out of the OU it will also take the user out of the group. Conversely, if a user is added to the OU and is in the enabled state then the script will add the user to the group.

I have taken my Powershell script one step further by adding an attribute from the AD user to allow a user with this attribute to be added and removed based on the AD attribute, in this case Company. Please let me know if this is of any use to you. I have commented extensively in the script.

The Script


PowerShell Script
#If you want to run this from a member server and not on a DC then you will need to install ADUC on that server for the
#import statement to work. You would also need to run the powershell script as a user with rights to add and remove users from a group
Import-Module ActiveDirectory
#Change sgroupname to the name of the security group you want to sync
$sgroupname = “Attrib_Security”
#the attribute is included in this select statement
$groupmembers = Get-ADGroupMember -Identity $sgroupname -recursive | Select-ObjectName,SamAccountName,distinguishedName,Company
#set the searchbase to the path of the OU that you would like to sync or if you make the searchbase
#the domain path then any user in any OU will be picked up with the correct attribute
$SearchBase = “DC=demo,DC=local”
#the user attribute is the attribute of company in the user account, if you want to change the attribute you need to do it at each
#command that has “.Company” if you want to change the value of the company attribute just change the string below
$userAttribute = “MS”
#the attribute is included in this select statement
$UserOU = Get-ADUser -Filter * -PropertiesName,SamAccountName,Enabled,distinguishedName,Company -SearchBase $Searchbase |Select-Object Name,SamAccountName,Enabled,distinguishedName,Company
foreach($user in $UserOU)
{
#the attribute is referenced here as $user.Company
If ($user.Enabled -eq $False -AND $sgroupname.SamAccountName -notcontains$user.SamAccountName -and $user.Company -eq $userAttribute)
{
#this includes an event in the event log with each users name and why they were removed or added
$message = “remove user disabled ” + $user.Name.ToString()
Write-EventLog -logname Application -entrytype Information -eventid 11 -Source”Application” -message $message
Remove-ADGroupMember -Identity $sgroupname -Member $user.SamAccountName -ErrorAction SilentlyContinue -Confirm:$False
#the attribute is referenced here as $user.Company
If ($user.Enabled -eq $True -AND $sgroupname.SamAccountName -notcontains$user.SamAccountName -and $user.Company -ne $userAttribute)
{
#this includes an event in the event log with each users name and why they were removed or added
$message = “remove user not in company” + $user.Name.ToString()
Write-EventLog -logname Application -entrytype Information -eventid 11 -Source”Application” -message $message
Remove-ADGroupMember -Identity $sgroupname -Member $user.SamAccountName -ErrorAction SilentlyContinue -Confirm:$False
}
#the attribute is referenced here as $user.Company
If ($user.Enabled -eq $True -AND $sgroupname.SamAccountName -notcontains$user.SamAccountName -and $user.Company -eq $userAttribute){#this includes an event in the event log with each users name and why they were removed or added
$message = “add user ” + $user.Name.ToString()
Write-EventLog -logname Application -entrytype Information -eventid 11 -Source”Application” -message $message
Add-ADGroupMember -Identity $sgroupname -Member $user.SamAccountName -ErrorActionSilentlyContinue -Confirm:$False
}
}
#the attribute is included in this select statement
$members = Get-ADGroupMember -Identity $sgroupname -recursive | Select-ObjectName,SamAccountName,distinguishedName,Company
foreach($member in $members)
{
$memberexists = ($member.distinguishedName.EndsWith($SearchBase))
#the attribute is referenced here as $member.Company
$membercompany = ($member.Company -eq $userAttribute)
If (-NOT $memberexists)
{
If (-NOT $membercompany)
{
$message = “removed from OU and Group: ” + $user.Name.ToString()
Write-EventLog -logname Application -entrytype Information -eventid 11 -Source”Application” -message $message
Remove-ADGroupMember -Identity $sgroupname -Member $member.SamAccountName -ErrorAction SilentlyContinue -Confirm:$False
}
}
}
}

Please note: This script is resource intensive and will probably not be a good fit if you have more than 1000 accounts in your environment. It does give you a good starting point to create a function and improve the efficiency of the script. If you do so, please drop me a line and let me know what has been done to improve on it.

Live long and prosper,

DM

Hits: 6