OK, here is where we are at with this. We updated the code per your recommendation but are still receiving an error when running it.
Our test user in this particular case is a member of two Department (ORG_) groups currently. One incorrect department group, and the correct group they should be in. This script should take a pass at the account, check the department attribute, update the account with the corresponding department group, then remove any other "ORG_" groups on the account....next account.
Here is a screenshot of the user in AD belonging to the two groups:
The user's "DepartmentNumber" attribute currently is 7510
Running the code I'm attaching at the bottom, this is the error we receive
This is the end result we would like to see in this particular example
# Update group memberships of user based on department
# The script adds a user to an AD group that is associated with the user's department and removes from groups associated with other departments.
# http://www.adaxes.com/script-repository/updategroupmembership-base-on-department-s403.htm
<#
Parameters:
$departmentProperty - specifies the LDAP display name of the property that stores the name of the user's department; = DepartmentNumber
$groupNameTemplate - specifies a template for names of groups that represent various departments. = ORG_{0}? ORG_{0}_*?
The {0} placeholder in the template will be replaced with the value of the property specified by $departmentProperty.
#>
$departmentProperty = "DepartmentNumber"
$groupNameTemplate = "ORG_{0}"
function SearchGroup ($filter, $list)
{
# Find groups
$searcher = $Context.BindToObject("Adaxes://RootDSE")
$searcher.SearchFilter = $filter
$searcher.PageSize = 500 # page size unlimited?? 5000??
$searcher.SearchScope = "ADS_SCOPE_SUBTREE"
$searcher.ReferralChasing = "ADS_CHASE_REFERRALS_NEVER"
$searcher.SetPropertiesToLoad(@("name"))
$searcher.VirtualRoot = $True
try
{
$searchResultIterator = $searcher.ExecuteSearch()
$searchResults = $searchResultIterator.FetchAll()
if ($list -ne $NULL)
{
foreach ($searchResult in $searchResults)
{
$list.Add($searchResult.AdsPath, $searchResult.Properties["name"].Value.ToString().ToLower())
}
}
elseif ($searchResults.Length -gt 1)
{
$Context.LogMessage("Found more than one group for department '$department'", "Warning")
return $NULL
}
elseif ($searchResults.Length -eq 0)
{
$Context.LogMessage("There is no group for department '$department'", "Warning")
return $NULL
}
else
{
return $searchResults[0].AdsPath
}
}
finally
{
# Release resources
$searchResultIterator.Dispose()
}
}
function UpdateGroupMembership ($groupPath, $groupName, $operation, $groupInfo)
{
if ($groupPath -eq $NULL)
{
return
}
$group = $Context.BindToObjectEx($groupPath, $True)
switch ($operation)
{
"Add"
{
try
{
$group.Add($Context.TargetObject.AdsPath)
$groupInfo.Add($groupPath, $groupName)
}
catch
{
$operationInfo = $group.GetLastOperationInfo()
if (-not([System.String]::IsNullOrEmpty($operationInfo.ExecutionLog.FirstErrorEntry)))
{
$Context.LogMessage("An error occurred when adding the user to group '$groupName'. Error: " + $_.Exception.Message, "Warning")
}
}
}
"Remove"
{
try
{
$group.Remove($Context.TargetObject.AdsPath)
}
catch
{
$operationInfo = $group.GetLastOperationInfo()
if (-not([System.String]::IsNullOrEmpty($operationInfo.ExecutionLog.FirstErrorEntry)))
{
$Context.LogMessage("An error occurred when removing the user from group '$groupName'. Error: " + $_.Exception.Message, "Warning")
}
}
}
}
}
# Get the user's department
try
{
$department = $Context.TargetObject.Get($departmentProperty)
}
catch
{
$department = $NULL
}
# Get names and paths of the groups the user is already a member of
try
{
$groupGuidsBytes = $Context.TargetObject.GetEx("adm-DirectMemberOfGuid")
}
catch
{
$groupGuidsBytes = @()
}
$groupInfo = @{}
if ($groupGuidsBytes.Length -ne 0)
{
# Build filter
$filter = New-Object "System.Text.StringBuilder"
$searchValue = [System.String]::Format($groupNameTemplate, "*")
[void]$filter.Append("(&(objectCategory=group)(name=$searchValue)(|")
foreach ($guidBytes in $groupGuidsBytes)
{
$filterPart = [Softerra.Adaxes.Ldap.FilterBuilder]::Create("objectGuid", $guidBytes)
[void]$filter.Append($filterPart)
}
[void]$filter.Append("))")
SearchGroup $filter.ToString() $groupInfo
}
if ($department -eq $NULL)
{
# Remove from all groups that belong to various departments
foreach ($path in $groupInfo.Keys)
{
UpdateGroupMembership $path $groupInfo[$path] "Remove"
}
return # Exit the script
}
else
{
$groupNameToSearch = [System.String]::Format($groupNameTemplate, $department).ToLower()
if (-not($groupInfo.ContainsValue($groupNameToSearch)))
{
# Add to group
$groupPath = SearchGroup "(&(objectCategory=group)(name=$groupNameToSearch*))" $NULL
UpdateGroupMembership $groupPath $groupNameToSearch "Add" $groupInfo
}
}
# Check whether it is necessary to remove the user from groups for other departments
if ($groupInfo.ContainsValue($groupNameToSearch))
{
foreach ($path in $groupInfo.Keys)
{
$groupName = $groupInfo[$path]
if ($groupName -eq $groupNameToSearch)
{
continue
}
UpdateGroupMembership $path $groupInfo[$path] "Remove"
}
}
If you have any other questions...let us know. And as always, thanks again!