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 (180 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 (216k 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 (700 points)
0 votes
1 answer

goal is to copy groups from one user to another during the crete user process. I created a variable on the create user form to input the UPN of the ... primaryGroupToken") -eq $primaryGroupId) { continue } $group.Remove($Context.TargetObject.AdsPath) } }

asked Nov 30, 2021 by Derek.Axe (480 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 (3.2k points)
0 votes
1 answer

Is it possible using PowerShell to copy group memberships from an already existing user without copying 2 specific groups named for example test and test 1 ? We are currently ... groups are not included. I can share the PowerShell script if needed. KR, Cas

asked Oct 30, 2023 by Cas (200 points)
0 votes
1 answer

Hi there, i know the multiple ways of copying the user groups - or all of them within the user creation wizard. I want to copy only a couple of groups ... is it possible to create an approval operation out of an powershellscript? Kind regards, Constantin

asked May 27, 2021 by Constey (190 points)
3,569 questions
3,259 answers
8,275 comments
547,954 users