I'm trying to combine these two scripts to effectively store a user's group memberships in customattributebinary5 and then be able to copy and paste those memberships to a new user in the future. So far I think I have everything except for the pasting of the groups to a new user as I'm having trouble converting the logic from groups to users.
Remove groups from user and store in attribute:
# $groupNamesToSkip = @("MyGroup1", "MyGroup2", "Department*") # TODO: modify me
$groupNamesToSkip = $null
function SkipGroup($patterns, $sAMAccountName)
{
foreach ($pattern in $patterns)
{
if ($sAMAccountName -like $pattern)
{
return $True
}
}
return $False
}
# Get all groups user is a direct member of
$groupGuids = $Context.TargetObject.GetEx("adm-DirectMemberOfGuid")
# Build a single-dimension array of member GUIDs
$totalBytes = $groupGuids.Count * 16
$result = New-Object 'System.Collections.Generic.List[System.Byte]' $totalBytes
foreach ($GuidBytes in $groupGuids)
{
$result.AddRange($GuidBytes)
}
# Save the GUIDs to the adm-CustomAttributeBinary5 virtual property of target user
$Context.TargetObject.Put("adm-CustomAttributeBinary5", $result.ToArray())
$Context.TargetObject.SetInfo()
# Get the Primary Group ID
$primaryGroupId = $Context.TargetObject.Get("primaryGroupID")
foreach ($groupGuidBytes in $groupGuids)
{
# Bind to the group
$groupGuid = New-Object "System.Guid" (,$groupGuidBytes)
$groupGuid = $groupGuid.ToString("B")
$groupPath = "Adaxes://<GUID=$groupGuid>"
$group = $Context.BindToObject($groupPath)
# Skip Primary Group
if ($group.Get("primaryGroupToken") -eq $primaryGroupId)
{
continue
}
# Skip special groups
$sAMAccountName = $group.Get("sAMAccountName")
if (($groupNamesToSkip -ne $NULL) -and
(SkipGroup $groupNamesToSkip $sAMAccountName))
{
continue
}
# Remove user from the group
$group.Remove($Context.TargetObject.AdsPath)
}
Copy groups from user to initiator:
# Get an array of member GUIDs
try
{
$sourceMemberGuids = $Context.TargetObject.Get("adm-CustomAttributeBinary5")
}
catch
{
$Context.Cancel("Failed to get member GUIDs.")
return
}
# Calculate the number of GUIDs
$totalBytes = $sourceMemberGuids.Length
# Make sure that the total number of bytes is a divisible of 16
$remainder = 0
[System.Math]::DivRem($totalBytes, 16, [ref] $remainder)
if ($remainder -ne 0)
{
$Context.Cancel("Unexpected data length! Exiting.")
return
}
# Save the GUIDs to the adm-CustomAttributeBinary1 virtual property user who invokes the script
$Context.Initiator.UserAdsObject.Put("adm-CustomAttributeBinary1", $sourceMemberGuids)
$Context.Initiator.UserAdsObject.SetInfo()
And finally, need help with pasting, as this doesn't work:
# Get the Primary Group ID
$primaryGroupId = $Context.TargetObject.Get("primaryGroupID")
#change this to skip certain groups
$groupNamesToSkip = $null
# Get an array of member GUIDs
try
{
$sourceMemberGuids = $Context.Initiator.UserAdsObject.Get("adm-CustomAttributeBinary1")
}
catch
{
$Context.Cancel("Failed to get member GUIDs.")
return
}
# Calculate the number of GUIDs
$totalBytes = $sourceMemberGuids.Length
# Make sure that the total number of bytes is a divisible of 16
$remainder = 0
[System.Math]::DivRem($totalBytes, 16, [ref] $remainder)
if ($remainder -ne 0)
{
$Context.Cancel("Unexpected data length! Exiting.")
return
}
foreach ($groupGuidBytes in $sourceMemberGuids)
{
# Bind to the group
$groupGuid = New-Object "System.Guid" (,$groupGuidBytes)
$groupGuid = $groupGuid.ToString("B")
$groupPath = "Adaxes://<GUID=$groupGuid>"
$group = $Context.BindToObject($groupPath)
$groupName = $group.Get("cn")
# Skip the group if it is the user's Primary Group
if (($group.Get("primaryGroupToken") -eq $primaryGroupId) -or ($groupNamesToSkip -contains $groupName))
{
continue
}
# Add user to the group
$group.Add($Context.TargetObject.AdsPath)
$Context.LogMessage("Added the user to group '$groupName'", "Information")
}