Copy AD group member to new AD group if they don't already exist

Tagged: 

This topic contains 4 replies, has 3 voices, and was last updated by Profile photo of Aapeli Hietikko Aapeli Hietikko 6 months, 4 weeks ago.

Viewing 5 posts - 1 through 5 (of 5 total)
  • Author
    Posts
  • #35535
    Profile photo of Grant Harrington
    Grant Harrington
    Participant

    I'm trying to create a script that takes an Source ADUC Group and add the members to a Destination ADUC Group. If for any reason, a member exists in both the Source ADUC group and Destination ADUC Group, I want them to be skipped. The code I have is below (added the [BOOLEAN] for troubleshooting.)

    Results are:
    IsPublic IsSerial Name BaseType
    ——– ——– —- ——–
    True True Boolean System.ValueType
    User01.Last exists in DEST-GROUP-ALL and will be skipped
    True True Boolean System.ValueType
    User02.Last exists in DEST-GROUP-ALL and will be skipped
    True True Boolean System.ValueType
    User03.Last exists in DEST-GROUP-ALL and will be skipped
    True True Boolean System.ValueType
    User04.Last does not exist does not exist in DEST-GROUP-ALL and will be added now....

    I'm curious why User04.Last shows a boolean value of True, but correctly drops down to the False (ELSE) condition?

    # This is the Legacy AD Security Group you want to migrate from
    $SourceGroup = 'SOURCE-GROUP-ALL'
    # This gets the group members sAMAccountNames as an array
    $SourceGroupMembers = Get-ADGroupMember $SourceGroup | select sAMAccountName
    # This is the EAD Security Group you want to migrate to
    $DestGroup = 'DEST-GROUP-ALL'
    
    # Loops through the sAMAccountName array of the SourceGroupMembers
    foreach ($SourceMember in $SourceGroupMembers) {
        
        # Loops through the sAMAccountName array of the DestGroup
        foreach ($DestMember in $DestGroup) {
    
        $DestGroupMembers = Get-ADGroupMember $DestMember | select sAMAccountName
            
            if ($DestGroupMembers.sAMAccountName -match $SourceMember.sAMAccountName) {[boolean]
                 Write-Output "$($SourceMember.sAMAccountName) exists in $DestGroup and will be skipped"
                          } ELSE {[boolean]
                Write-Output "$($SourceMember.sAMAccountName) does not exist does not exist in $DestGroup and will be added now...."
                #Add-ADGroupMember $ToGroup -Members $FromMember -WhatIf
            }
        }
    }
    
    #35536
    Profile photo of Don Jones
    Don Jones
    Keymaster

    Well...

    [boolean]

    Outputs... I'm not sure what you're doing here. What's the [boolean] for? That's creating:

    True True Boolean System.ValueType

    Every time you use it, and you've got it in both portions of the If block.

    #35537
    Profile photo of Grant Harrington
    Grant Harrington
    Participant

    I was just adding to see on-screen results for testing. I was curious as to why it was reporting "True" on a expression that was returned as "False" (by virtue of looping through the ELSE statement).

    Mostly trying to troubleshoot my script.

    That said, does the intent of the script seem "logical"? I'll pull the [boolean] syntax from production of course.

    #35539
    Profile photo of Don Jones
    Don Jones
    Keymaster

    Just [boolean] by itself is making the shell output "What is the data type [boolean]." The data type is always the same, and so the output is always the same. If you wanted to output True/False, you'd use $True and $False. It isn't "reporting True," it's reporting the fact that [boolean], as a type, Is Public, Is Serial(izable), has a name, and has a base type. The output of [boolean] had nothing to do with your code's logic.

    So it does seem logical (without the [boolean]), although I'd use Write-Verbose for that output (and set $VerbosePreference=Continue at the top of the script), since Write-Output goes to the pipeline. As-is, you're not building a tool that will play well in the pipeline, which should always be a goal in PowerShell.

    #35803
    Profile photo of Aapeli Hietikko
    Aapeli Hietikko
    Participant

    This might do the trick for you

    Testing:

    $SourceGroup = 'Source-Group'
    $SourceGroupMembers = Get-ADGroupMember $SourceGroup | select sAMAccountName
    $DestGroup = 'Destination-Group'
    $DestGroupMembers = Get-ADGroupMember $DestGroup | select -ExpandProperty sAMAccountName
    
    
    foreach ($SourceMember in $SourceGroupMembers) {
        $SamID = $SourceMember.sAMAccountName
        if ($SamID -in $DestGroupMembers) {
            write-output "Skipping $SamID"
            continue
            } #End if ($SamID -in $DestGroupMembers)
        
        if ($SamID -notin $DestGroupMembers) {
            write-output "Adding $SamID to $DestGroup"
            } #End if ($SamID -notin $DestGroupMembers)
    
        } #End foreach ($SourceMember in $SourceGroupMembers) 
    
    

    And then maximum force on the execution

    $SourceGroup = 'Source-Group'
    $SourceGroupMembers = Get-ADGroupMember $SourceGroup | select sAMAccountName
    $DestGroup = 'Destination-Group'
    $DestGroupMembers = Get-ADGroupMember $DestGroup | select -ExpandProperty sAMAccountName
    
    
    foreach ($SourceMember in $SourceGroupMembers) {
        $SamID = $SourceMember.sAMAccountName
    
        if ($SamID -notin $DestGroupMembers) {
    	Add-ADPrincipalGroupMembership -Identity $SamID -MemberOf $DestGroup -verbose
            } #End if ($SamID -notin $DestGroupMembers)
    
        } #End foreach ($SourceMember in $SourceGroupMembers) 
    
Viewing 5 posts - 1 through 5 (of 5 total)

You must be logged in to reply to this topic.