locked
Powershell Script ad or remove user into a new group according to their group RRS feed

  • Question

  • Hi,

    I've done this script because I want it to search every $user in $users who are in a specific group (group1) and if they are, ad them into another group(group2). I want that if I delete one of them in group1 it will be remove in group2 too but not the opposite. I hope you understand me (sry for my bad english).

    My script doesn't work I've got this error :

    Get-ADUser : Cannot validate argument on parameter "identity". the argument is null or a null element of the argument collection contains a null value.
    Au caractère C:\Users\lsoriano\Documents\compare group.ps1:13 : 21
    +     If ((Get-ADUser $user.PrincipalName -Properties MemberOf).MemberO ...
    +                     ~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidData : (:) [Get-ADUser], ParameterBindingValidationException
        + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.Ge 
       tADUser


    Import-Module ActiveDirectory

    # Group1
    $Source_Group = "CN=Group1,OU=Groups,OU=Leadformance,DC=leadformance,DC=local" 

    # GRoup2
    $Destination_Group = "CN=Group2,OU=Groups,OU=Leadformance,DC=leadformance,DC=local"

    $users = "OU=Users,OU=Leadformance,DC=leadformance,DC=local"

    Foreach ($user In $users)
    {
        If ((Get-ADUser $user.SamAccountName -Properties MemberOf).MemberOf -Contains $Source_Group)
            {
          
                Add-ADGroupMember -Identity $Destination_Group -Members $User.SamAccountName
            }
            Else 
            {
                Remove-ADGroupMember -Identity $Destination_Group -Members $User.SamAccountName
            }
    }


    Monday, March 11, 2019 3:04 PM

Answers

  • Hello,

    I created a function base on your requirements. Sync-ADGroup will look at both group members and will make DestinationGroup a mirror to SourceGroup.

    Additional Features:

    -Test SourceGroup - if exists, if the function is unable to find SourceGroup Break.

    -Test DestinationGroup - if unable to find DestinationGroup create DestinationGroup in the same OU as SourceGroup.

    -MODE Options: ADD, REMOVE, SYNC, TEST

       -ADD Add users only

        -REMOVE Remove users only

        -SYNC Add and Remove users

        -TEST Display Add and Remove users (No actions are taken, display only)


    Function Sync-ADGroup{
    <#
    .SYNOPSIS
        Compare two Active Directory security groups. Look at each groups members to SYNC, ADD, REMOVE, TEST.
    
    .DESCRIPTION
        Sync-ADGroup looks at your $SourceGroup security group members and compares them to $DestinationGroup security group members. MODE sets what happens.
    
        The function has some error checking if the function is unable to find $SourceGroup code Break. If $DestinationGroup is not available, create $DestinationGroup security group in the same OU as $SourceGroup
    
    .LINK
        https://www.cit-devops.com
    
    .NOTES
        Created By Ronnie Rosal
        Version 1
    
    .PARAMETER KEY
        -SourceGroup <String> 
            Soruce Security group with the users you want to SYNC, ADD, REMOVE, TEST
        
        -DestinationGroup <String>
            Destination Security group that will SYNC, ADD, REMOVE, TEST from Source Security group
        -Mode <String>
            Mode Options: ADD, REMOVE, SYNC, TEST
                ADD - Add users only
                REMOVE - Remove users only
                SYNC - Add and Remove users
                TEST - Display Add and Remove users (No actions will be ran)
    
    .EXAMPLE
    
    PS C:\Windows\system32> Sync-ADGroup -SourceGroup "test-staff" -DestinationGroup "test-help" -mode SYNC
    test-help was not detected, creating security group
    Adding qtrinidad to test-help
    Adding alowe to test-help
    Adding freid to test-help
    Adding nedwards to test-help
    Adding afigueroa to test-help
    Adding pguzman to test-help
    Adding bmilner to test-help
    Adding whutchison to test-help
    Adding sjohnson to test-help
    Adding pbaird to test-help
    End of Sync-ADGroup for test-help run
    
    PS C:\Windows\system32> Sync-ADGroup -SourceGroup "test-staff" -DestinationGroup "test-help" -mode TEST
    TESTING MODE-Adding qtrinidad to test-help
    TESTING MODE-Adding alowe to test-help
    TESTING MODE-Adding freid to test-help
    TESTING MODE-Adding nedwards to test-help
    TESTING MODE-Adding afigueroa to test-help
    TESTING MODE-Adding pguzman to test-help
    TESTING MODE-Adding bmilner to test-help
    TESTING MODE-Adding whutchison to test-help
    TESTING MODE-Adding sjohnson to test-help
    TESTING MODE-Adding pbaird to test-help
    End of Sync-ADGroup for test-help run
    
    PS C:\Windows\system32> Sync-ADGroup -SourceGroup "test-staff" -DestinationGroup "test-help" -mode SYNC
    No new members to add to test-help
    Removing ckelly from test-help
    Removing breno from test-help
    Removing cwilt from test-help
    End of Sync-ADGroup for test-help run
    #>
    [CmdletBinding()]
    Param (
        [Parameter(Position = 0,Mandatory = $True)]
        $SourceGroup,
        [Parameter(Position = 0,Mandatory = $True)]
        $DestinationGroup,
        [Parameter(Position = 0,Mandatory = $False)]
        [ValidateSet("ADD","REMOVE","SYNC","TEST")]
        $Mode = "SYNC")
    
    Import-Module ActiveDirectory
    
    $AllADGroups = Get-ADGroup -Filter *
    
    If(($AllADGroups | where {$_.SamAccountName -eq $SourceGroup}) -eq $NULL){
        Write-Warning "Warning Script Break - Unable to find security group $($SourceGroup)"
        Break
    }
    
    If(($AllADGroups | where {$_.SamAccountName -eq $SourceGroup}) -ne $NULL){
        $SourceGroupProperties = $AllADGroups | where {$_.SamAccountName -eq $SourceGroup}
        $SourceGroupOU = $SourceGroupProperties.DistinguishedName -replace "CN=$($SourceGroupProperties.Name),"
        $SourceGroupMembers = $(Get-ADGroupMember -Identity $SourceGroup)
    }
    
    If(($AllADGroups | where {$_.SamAccountName -eq $DestinationGroup}) -eq $NULL){
        New-ADGroup -Name $DestinationGroup -SamAccountName $DestinationGroup -GroupCategory Security -GroupScope Global -DisplayName $DestinationGroup -Path $SourceGroupOU
        Write-Host "$($DestinationGroup) was not detected, creating security group"
        Start-Sleep 10
        $DestinationGroupMembers = $(Get-ADGroupMember -Identity $DestinationGroup)
    }
    
    If(($AllADGroups | where {$_.SamAccountName -eq $DestinationGroup}) -ne $NULL){
        $DestinationGroupMembers = $(Get-ADGroupMember -Identity $DestinationGroup)
    }
    
    If($DestinationGroupMembers -eq $NULL){
        $DestinationGroupMembersSamaccountname = 'NULL'
    }Else{
        $DestinationGroupMembersSamaccountname = $DestinationGroupMembers.SamAccountName
    }
    
    $UsersToAdd = Compare-Object $SourceGroupMembers.SamAccountName $DestinationGroupMembersSamaccountname | where {$_.SideIndicator -eq "<="}
    $UsersToAddInputObject = $UsersToAdd.InputObject
    
    $UsersToRemove = Compare-Object $SourceGroupMembers.SamAccountName $DestinationGroupMembersSamaccountname | where {$_.SideIndicator -eq "=>"}
    $UsersToRemoveInputObject = $UsersToRemove.InputObject
    
    If($Mode -eq "ADD" -or $Mode -eq "SYNC"){
        If($UsersToAddInputObject -ne $NULL){
            If($UsersToAddInputObject -ne "NULL"){
                ForEach($MembersToAdd in $UsersToAddInputObject){
                    Add-ADGroupMember -Identity $DestinationGroup -Members $MembersToAdd
                    Write-Host "Adding $MembersToAdd to $DestinationGroup" -foregroundcolor "Green"
                }
            }
        }
        If($UsersToAddInputObject -eq $NULL){
            Write-Host "No new members to add to $DestinationGroup" -foregroundcolor "Yellow"
        }
    }
    
    If($Mode -eq "REMOVE" -or $Mode -eq "SYNC"){
        If($UsersToRemoveInputObject -ne $NULL){
            If($UsersToRemoveInputObject -ne "NULL"){
                ForEach($MembersToRemove in $UsersToRemoveInputObject){
                    Remove-ADGroupMember -Identity $DestinationGroup -Members $MembersToRemove -Confirm:$false
                    Write-Host "Removing $MembersToRemove from $DestinationGroup" -foregroundcolor "Red"
                }
            }
        }
        If($UsersToRemoveInputObject -eq $NULL){
            Write-Host "No new members to remove from $DestinationGroup" -foregroundcolor "Red"
        }
    }
    
    If($Mode -eq "TEST"){
        If($UsersToAddInputObject -ne $NULL){
            If($UsersToAddInputObject -ne "NULL"){
                ForEach($MembersToAdd in $UsersToAddInputObject){
                    Write-Host "TESTING MODE-Adding $MembersToAdd to $DestinationGroup" -foregroundcolor "Green"
                }
            }
        }
        If($UsersToAddInputObject -eq $NULL){
            Write-Host "TESTING MODE-No new members to add to $DestinationGroup" -foregroundcolor "Yellow"
        }
        If($UsersToRemoveInputObject -ne $NULL){
            If($UsersToRemoveInputObject -ne "NULL"){
                ForEach($MembersToRemove in $UsersToRemoveInputObject){
                    Write-Host "TESTING MODE-Removing $MembersToRemove to $DestinationGroup" -foregroundcolor "Red"
                }
            }
        }
        If($UsersToRemoveInputObject -eq $NULL){
            Write-Host "TESTING MODE-No new members to remove to $DestinationGroup" -foregroundcolor "Yellow"
        }
    }
    
    Write-Host "End of Sync-ADGroup for $($DestinationGroup) run"
    }

    I hope this fulfills what you are trying to accomplish.

    This seems like a good topic to cover in my blog (www.cit-devops.com), I will write about it in the next few days in detail.

    Cheers!

    Ronnie

    • Proposed as answer by CITLead Monday, March 11, 2019 6:21 PM
    • Marked as answer by Nightingal Tuesday, March 12, 2019 9:30 AM
    Monday, March 11, 2019 5:36 PM

All replies

  • Thanks for your answer

    I need this operation to be automatic so that's why i create a script that I will put on a planned task.

    Monday, March 11, 2019 3:48 PM
  • Hello,

    I created a function base on your requirements. Sync-ADGroup will look at both group members and will make DestinationGroup a mirror to SourceGroup.

    Additional Features:

    -Test SourceGroup - if exists, if the function is unable to find SourceGroup Break.

    -Test DestinationGroup - if unable to find DestinationGroup create DestinationGroup in the same OU as SourceGroup.

    -MODE Options: ADD, REMOVE, SYNC, TEST

       -ADD Add users only

        -REMOVE Remove users only

        -SYNC Add and Remove users

        -TEST Display Add and Remove users (No actions are taken, display only)


    Function Sync-ADGroup{
    <#
    .SYNOPSIS
        Compare two Active Directory security groups. Look at each groups members to SYNC, ADD, REMOVE, TEST.
    
    .DESCRIPTION
        Sync-ADGroup looks at your $SourceGroup security group members and compares them to $DestinationGroup security group members. MODE sets what happens.
    
        The function has some error checking if the function is unable to find $SourceGroup code Break. If $DestinationGroup is not available, create $DestinationGroup security group in the same OU as $SourceGroup
    
    .LINK
        https://www.cit-devops.com
    
    .NOTES
        Created By Ronnie Rosal
        Version 1
    
    .PARAMETER KEY
        -SourceGroup <String> 
            Soruce Security group with the users you want to SYNC, ADD, REMOVE, TEST
        
        -DestinationGroup <String>
            Destination Security group that will SYNC, ADD, REMOVE, TEST from Source Security group
        -Mode <String>
            Mode Options: ADD, REMOVE, SYNC, TEST
                ADD - Add users only
                REMOVE - Remove users only
                SYNC - Add and Remove users
                TEST - Display Add and Remove users (No actions will be ran)
    
    .EXAMPLE
    
    PS C:\Windows\system32> Sync-ADGroup -SourceGroup "test-staff" -DestinationGroup "test-help" -mode SYNC
    test-help was not detected, creating security group
    Adding qtrinidad to test-help
    Adding alowe to test-help
    Adding freid to test-help
    Adding nedwards to test-help
    Adding afigueroa to test-help
    Adding pguzman to test-help
    Adding bmilner to test-help
    Adding whutchison to test-help
    Adding sjohnson to test-help
    Adding pbaird to test-help
    End of Sync-ADGroup for test-help run
    
    PS C:\Windows\system32> Sync-ADGroup -SourceGroup "test-staff" -DestinationGroup "test-help" -mode TEST
    TESTING MODE-Adding qtrinidad to test-help
    TESTING MODE-Adding alowe to test-help
    TESTING MODE-Adding freid to test-help
    TESTING MODE-Adding nedwards to test-help
    TESTING MODE-Adding afigueroa to test-help
    TESTING MODE-Adding pguzman to test-help
    TESTING MODE-Adding bmilner to test-help
    TESTING MODE-Adding whutchison to test-help
    TESTING MODE-Adding sjohnson to test-help
    TESTING MODE-Adding pbaird to test-help
    End of Sync-ADGroup for test-help run
    
    PS C:\Windows\system32> Sync-ADGroup -SourceGroup "test-staff" -DestinationGroup "test-help" -mode SYNC
    No new members to add to test-help
    Removing ckelly from test-help
    Removing breno from test-help
    Removing cwilt from test-help
    End of Sync-ADGroup for test-help run
    #>
    [CmdletBinding()]
    Param (
        [Parameter(Position = 0,Mandatory = $True)]
        $SourceGroup,
        [Parameter(Position = 0,Mandatory = $True)]
        $DestinationGroup,
        [Parameter(Position = 0,Mandatory = $False)]
        [ValidateSet("ADD","REMOVE","SYNC","TEST")]
        $Mode = "SYNC")
    
    Import-Module ActiveDirectory
    
    $AllADGroups = Get-ADGroup -Filter *
    
    If(($AllADGroups | where {$_.SamAccountName -eq $SourceGroup}) -eq $NULL){
        Write-Warning "Warning Script Break - Unable to find security group $($SourceGroup)"
        Break
    }
    
    If(($AllADGroups | where {$_.SamAccountName -eq $SourceGroup}) -ne $NULL){
        $SourceGroupProperties = $AllADGroups | where {$_.SamAccountName -eq $SourceGroup}
        $SourceGroupOU = $SourceGroupProperties.DistinguishedName -replace "CN=$($SourceGroupProperties.Name),"
        $SourceGroupMembers = $(Get-ADGroupMember -Identity $SourceGroup)
    }
    
    If(($AllADGroups | where {$_.SamAccountName -eq $DestinationGroup}) -eq $NULL){
        New-ADGroup -Name $DestinationGroup -SamAccountName $DestinationGroup -GroupCategory Security -GroupScope Global -DisplayName $DestinationGroup -Path $SourceGroupOU
        Write-Host "$($DestinationGroup) was not detected, creating security group"
        Start-Sleep 10
        $DestinationGroupMembers = $(Get-ADGroupMember -Identity $DestinationGroup)
    }
    
    If(($AllADGroups | where {$_.SamAccountName -eq $DestinationGroup}) -ne $NULL){
        $DestinationGroupMembers = $(Get-ADGroupMember -Identity $DestinationGroup)
    }
    
    If($DestinationGroupMembers -eq $NULL){
        $DestinationGroupMembersSamaccountname = 'NULL'
    }Else{
        $DestinationGroupMembersSamaccountname = $DestinationGroupMembers.SamAccountName
    }
    
    $UsersToAdd = Compare-Object $SourceGroupMembers.SamAccountName $DestinationGroupMembersSamaccountname | where {$_.SideIndicator -eq "<="}
    $UsersToAddInputObject = $UsersToAdd.InputObject
    
    $UsersToRemove = Compare-Object $SourceGroupMembers.SamAccountName $DestinationGroupMembersSamaccountname | where {$_.SideIndicator -eq "=>"}
    $UsersToRemoveInputObject = $UsersToRemove.InputObject
    
    If($Mode -eq "ADD" -or $Mode -eq "SYNC"){
        If($UsersToAddInputObject -ne $NULL){
            If($UsersToAddInputObject -ne "NULL"){
                ForEach($MembersToAdd in $UsersToAddInputObject){
                    Add-ADGroupMember -Identity $DestinationGroup -Members $MembersToAdd
                    Write-Host "Adding $MembersToAdd to $DestinationGroup" -foregroundcolor "Green"
                }
            }
        }
        If($UsersToAddInputObject -eq $NULL){
            Write-Host "No new members to add to $DestinationGroup" -foregroundcolor "Yellow"
        }
    }
    
    If($Mode -eq "REMOVE" -or $Mode -eq "SYNC"){
        If($UsersToRemoveInputObject -ne $NULL){
            If($UsersToRemoveInputObject -ne "NULL"){
                ForEach($MembersToRemove in $UsersToRemoveInputObject){
                    Remove-ADGroupMember -Identity $DestinationGroup -Members $MembersToRemove -Confirm:$false
                    Write-Host "Removing $MembersToRemove from $DestinationGroup" -foregroundcolor "Red"
                }
            }
        }
        If($UsersToRemoveInputObject -eq $NULL){
            Write-Host "No new members to remove from $DestinationGroup" -foregroundcolor "Red"
        }
    }
    
    If($Mode -eq "TEST"){
        If($UsersToAddInputObject -ne $NULL){
            If($UsersToAddInputObject -ne "NULL"){
                ForEach($MembersToAdd in $UsersToAddInputObject){
                    Write-Host "TESTING MODE-Adding $MembersToAdd to $DestinationGroup" -foregroundcolor "Green"
                }
            }
        }
        If($UsersToAddInputObject -eq $NULL){
            Write-Host "TESTING MODE-No new members to add to $DestinationGroup" -foregroundcolor "Yellow"
        }
        If($UsersToRemoveInputObject -ne $NULL){
            If($UsersToRemoveInputObject -ne "NULL"){
                ForEach($MembersToRemove in $UsersToRemoveInputObject){
                    Write-Host "TESTING MODE-Removing $MembersToRemove to $DestinationGroup" -foregroundcolor "Red"
                }
            }
        }
        If($UsersToRemoveInputObject -eq $NULL){
            Write-Host "TESTING MODE-No new members to remove to $DestinationGroup" -foregroundcolor "Yellow"
        }
    }
    
    Write-Host "End of Sync-ADGroup for $($DestinationGroup) run"
    }

    I hope this fulfills what you are trying to accomplish.

    This seems like a good topic to cover in my blog (www.cit-devops.com), I will write about it in the next few days in detail.

    Cheers!

    Ronnie

    • Proposed as answer by CITLead Monday, March 11, 2019 6:21 PM
    • Marked as answer by Nightingal Tuesday, March 12, 2019 9:30 AM
    Monday, March 11, 2019 5:36 PM
  • Wow that seems very nice, huge thanks for this !!

    I try to use it and that is what my parameters look like 

    [CmdletBinding()]
    Param (
        [Parameter(Position = 0,Mandatory = $True)]
        $SourceGroup = "CHY", 
        [Parameter(Position = 0,Mandatory = $True)]
        $DestinationGroup = "Miroirtest",
        [Parameter(Position = 0,Mandatory = $False)]
        [ValidateSet("ADD","REMOVE","SYNC","TEST")]
        $Mode = "TEST")

    the group "CHY" and "Miroirtest" are in the same OU, CHY as a lot of members and Miroirtest nothing, but nothing is happening when I run the script 

     

    PS C:\Windows\system32> C:\Users\lsoriano\Documents\SyncAdGroup.ps1

    PS C:\Windows\system32> 

    0 error but nothing is happening ;-( any idea ?

    Thanks again for your time !!!

    Tuesday, March 12, 2019 9:03 AM
  • My bad I checked on your site and see the exemple in video now I understand and it work perfectly !!! Thank you very much !!
    Tuesday, March 12, 2019 9:30 AM
  • No problem, visit my site in a few weeks I have a few ideas on how to improve the code. I want to test out a few things before I post anything. Just a hint, I want to expand on the idea to help manage distribution lists or distribution list manage security groups.
    Tuesday, March 12, 2019 3:16 PM