0 votes

Hi,

Group memberships are kept when using "User Copy" function.
Is it possible to do the same thing between two existing users ? (custom commands or else)

Thanks for your response,
Yoann

by (1.9k points)
0

Yoann,

We have a solution for you. We are now writing some PowerShell scripts for you to use, I'll update the topic as soon as we get these scripts working.

1 Answer

0 votes
by (213k points)

Hello Yoann,

We don't yet have this functionality in Adaxes, but it is in our TODO list.

Nevertheless, there is a workaround that we may suggest for the time being. You need to create two Custom Commands.

One of these Custom Commands, when executed on a user, will copy GUIDs of all the groups that the user is a member of to the CustomAttributeBinary1 property of the user who invokes the Custom Command. CustomAttributeBinary1 is one of the Adaxes virtual properties that can store binary data.

The other Custom Command will read the value of the CustomAttributeBinary1 property of the user who invokes the Custom Command. If this property is not empty, it will set the user, on which the command is performed, to be a member of the groups represented by the GUIDs.

To create a Custom Command that will copy group membership to CustomAttributeBinary1:

  1. Create a new Custom Command

  2. On the 2nd step of the Custom Command creation wizard, select User.

  3. On the 3rd step of the wizard, add the Run a program or PowerShellScript action and paste the following script:

     # Get a list of GUIDs of the groups the selected object is a member of.
     $sourceGroupGuids = $Context.TargetObject.GetEx("adm-DirectMemberOfGuid") 
    
     # Build a single-dimention array that will contain all GUIDs of the groups
     $totalBytes = $sourceGroupGuids.Count * 16
     $result = New-Object 'System.Collections.Generic.List[System.Byte]' $totalBytes
     foreach ($groupGuidBytes in $sourceGroupGuids)
     {
         $result.AddRange($groupGuidBytes)
     }
     # Save the data to the adm-CustomAttributeBinary1 virtual property of the operation initiator.
     $Context.Initiator.UserAdsObject.Put("adm-CustomAttributeBinary1", $result.ToArray())
     $Context.Initiator.UserAdsObject.SetInfo()

To create a Custom Command that will 'paste' group membership from CustomAttributeBinary1:

  1. Create a new Custom Command

  2. On the 2nd step of the Custom Command creation wizard, select User.

  3. On the 3rd step of the wizard, add the Run a program or PowerShellScript action and paste the following script:

     # Get an array of  group GUIDs
     try
     {
         $sourceGroupGuids = $Context.Initiator.UserAdsObject.Get("adm-CustomAttributeBinary1")
     }
     catch
     {
         $Context.Cancel("Failed to get group GUIDs.")
     }
    
     # Calculate the number of GUIDs
     $totalBytes = $sourceGroupGuids.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!")
     }
     $groupsToAdd = New-Object "System.Collections.Generic.HashSet[System.Guid]"
    
     for ($i = 0; $i -lt ($totalBytes / 16); $i++)
     {
         $bytes = [System.Guid]::Empty.ToByteArray()
         [System.Array]::Copy($sourceGroupGuids, $i * 16, $bytes, 0, 16)
         $guid = New-Object "System.Guid" (,$bytes)
         $groupsToAdd.Add($guid)
     }
    
     # Get GUIDs of the groups the user is a member of
     $targetGroupGuids = $Context.TargetObject.GetEx("adm-DirectMemberOfGuid")
    
     # Adjust the list of groups to add the user to, and the list of groups to remove the user from
     $groupsToRemove = New-Object "System.Collections.Generic.HashSet[System.Guid]"
     foreach($targetGroupGuidBytes in $targetGroupGuids)
     {
         $guid = New-Object "System.Guid" (,$targetGroupGuidBytes)
         if ($groupsToAdd.Contains($guid))
         {
             $groupsToAdd.Remove($guid) # already a member of the group
         }
         else
         {
             $groupsToRemove.Add($guid)
         }
     }
    
     # Remove from groups that are not in the list of copied groups
     foreach($groupGuid in $groupsToRemove)
     {
         $groupGuid = $groupGuid.ToString("B")
         $groupPath = "Adaxes://<GUID=$groupGuid>"
         $group = $Context.BindToObjectEx($groupPath, $True)
         $group.Remove($Context.TargetObject.AdsPath)
     }
    
     # Add to groups
     foreach($groupGuid in $groupsToAdd)
     {
         $groupGuid = $groupGuid.ToString("B")
         $groupPath = "Adaxes://<GUID=$groupGuid>"
         $group = $Context.BindToObjectEx($groupPath, $True)
         $group.Add($Context.TargetObject.AdsPath)    
     }
0

Are there any security implications for having that adm-CustomAttributeBinary1 attribute filled out on your user profile?

0

Not at all. Thank you.

0

In there a way to edit this script to omit certain groups from being copied.
The Guids are giving me trouble.
I wanted something like this:

$BlackList = "Domain Admins","App\_Test\*","App\_Test2\*"  
 #Foreach ($bgroup in $Blacklist)  
 # {  
 #IF ($groups -notlike $bgroup)  

Then add group to user

0

Hello,

In there a way to edit this script to omit certain groups from being copied.

Yes, sure. You'll need to change only the 1st script that copies groups. The 2nd script that pastes the groups can remain as it is.

To implement what you want, use the following version of the 1st script:

$groupNamesToSkip = @("Domain Admins", "App_Test*", "App_Test2*") # TODO: modfiy me

# Get GUIDS of the groups won't be copied
$domainName = $Context.GetObjectDomain("%distinguishedName%")
$searcher = $Context.BindToObject("Adaxes://$domainName/rootDSE")
$filter = New-Object "System.Text.StringBuilder"
$filter.Append("(&(objectCategory=group)(|") | Out-Null
foreach ($value in $groupNamesToSkip)
{
    $filter.Append("(name=$value)") | Out-Null
}
$filter.Append("))") | Out-Null
$searcher.SearchFilter = $filter.ToString()
$searcher.SearchScope = "ADS_SCOPE_SUBTREE"
$searcher.PageSize = 500
$searcher.SetPropertiesToLoad(@("objectGuid"))

try
{
    $searchResult = $searcher.ExecuteSearch()
    $groups = $searchResult.FetchAll()

    $groupGuidsToSkip = New-Object "System.Collections.Generic.HashSet[System.Guid]"
    foreach ($groupId in $groups)
    {
        $guid = [Guid]$groupId.Properties["objectGuid"].Value
        $groupGuidsToSkip.Add($guid) | Out-Null
    }
}
finally
{
    $searchResult.Dispose()
}

# Get a list of GUIDs of the groups the selected object is a member of.
$sourceGroupGuids = $Context.TargetObject.GetEx("adm-DirectMemberOfGuid")

# Build a single-dimention array that will contain all GUIDs of the groups
$totalBytes = $sourceGroupGuids.Count * 16
$result = New-Object 'System.Collections.Generic.List[System.Byte]' $totalBytes
foreach ($groupGuidBytes in $sourceGroupGuids)
{
    if ($groupGuidsToSkip.Contains([Guid]$groupGuidBytes))
    {
        continue
    }

    $result.AddRange($groupGuidBytes)
}
# Save the data to the adm-CustomAttributeBinary1 virtual property of the operation initiator.
$Context.Initiator.UserAdsObject.Put("adm-CustomAttributeBinary1", $result.ToArray())
$Context.Initiator.UserAdsObject.SetInfo()

In the script, $groupNamesToSkip specifies the names of the groups that will be omitted.

0

Works great
Thanks

Related questions

0 votes
1 answer

Hello Back when we first started using Adaxes you created a couple of great scripts which worked together really well, the first one copied one users group membership and put in ... an addition to what groups the second user is already a member of? Thank you.

asked Aug 4, 2015 by CBurn (3.3k points)
0 votes
1 answer

We have several contractors that come and go, it would be helpful to have a custom command that will copy only the member of groups from one user to another. We have done this previously with ... ; write-warning "I'm sorry, Jay. I'm afraid I can't do that." }

asked Jan 9, 2017 by willy-wally (14.5k points)
0 votes
1 answer

I have a scheduled task that runs a Powershell script against an AD group, "Group 1". I need to get all of the members of Group 1, and add them to Group 2. The ... identity in the error message start with 'user;'? What is the correct way to accomplish this?

asked Aug 27 by ngb (280 points)
0 votes
1 answer

Hello, I created a Business Unites that contains groups that apecifc users can change members of.^ Then, I created a Security Role, set permissions ans assignments. When the user ... he get two errors (see printscreens) What is missing? Thanks for your help.

asked Dec 4, 2018 by tentaal (5.2k points)
0 votes
1 answer

Hi - How can I remove the option of allowing "Copy User Groups" during the copy user process in the interface. I'd like to have it hidden but still active so to not allow our HR team to accidently unclick it during the process.

asked Oct 15 by 6FigureMission (710 points)
2,031 questions
1,806 answers
5,156 comments
1,016 users