Adding/removing members from another forest or domain to groups in Active Directory


Adding/removing members belonging to the same domain from a group is very simple using AD Powershell cmdlets. All you have to do is pass an identifier (either samAccountName, distinguishedName, securityIdentifier or GUID) of the member and group to one of the membership cmdlets:

· Add-ADGroupMember

· Remove-ADGroupMember

· Add-ADPrincipalGroupMembership

· Remove-ADPrincipalGroupMembership

Example:

C:\PS> Add-ADGroupMember SvcAccPSOGroup -Member SQL01, SQL02   ## Adds the user accounts with SamAccountNames SQL01,SQL02 to the group SvcAccPSOGroup.

C:\PS> Remove-ADPrincipalGroupMembership -Identity "Wilson Pais" -MemberOf "Administrators" ## Remove the user 'Wilson Pais' from the administrators group.

However, when it comes to adding and removing cross-forest or cross-domain members from a group, things become a little difficult. Here is an example of the error message that you would see while trying to do cross-forest/domain operations the regular way:

image

The issue here is that Add-ADGroupMember cmdlet tries to resolve the identity supplied in its -MemberOf parameter first and then update the group membership. Since the identity supplied in –MemberOf parameter is from ForestBBB the cmdlet fails while trying to resolve the identity against ForestAAA and throws an identity not found exception (ADIdentityNotFoundException).

The correct way to update cross-forest/domain membership is to first fetch the cross-forest/domain object using any of the ADPowershell cmdlets and then supply the fetched object as input to –Members or –MemberOf parameter of the cmdlets.

Example:

image

If you want to use Add-ADPrincipalGroupMembership cmdlet then first fetch the group object and save it in a variable and then execute Add-ADPrincipalGroupMembership cmdlet targeting ForestBBB.

image

Here are the commands that are executed in the screenshots above.

PS ForestAAA:\> $forestBBBUser = Get-ADUser swami -Server $forestBBB
PS ForestAAA:\> Add-ADGroupMember Administrators -Members $forestBBBUser
PS ForestAAA:\>
PS ForestAAA:\> $forestAAAGroup = Get-ADGroup Administrators
PS ForestAAA:\> Add-ADPrincipalGroupMembership -Server $forestBBB swami -MemberOf $forestAAAGroup
PS ForestAAA:\> Remove-ADPrincipalGroupMembership -Server $forestBBB swami -MemberOf $forestAAAGroup

Remove members from group
Do you want to remove all the specified member(s) from the specified group(s)?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"): y
PS ForestAAA:\>
PS ForestAAA:\>

The reason why the above commands work is that ADPowershell cmdlets stores session information in the objects returned.

      The variable $forestBBBUser in the above example contains “server = $forestBBB” in its session information, which is stored internally and is not visible/accessible via command line.

This session information is used by Add-ADGroupMember (and other membership cmdlets) to resolve the identity and add it to the group in $forestAAA.

NOTE: In the above examples I have connected to the forest where the group resides.

Hope this post helps you in managing your group membership via ADPowershell.

 

Cheers,

Swami

Swaminathan Pattabiraman

Developer – Active Directory Powershell Team

Comments (18)

  1. Lepide says:

    The below code can be used as well

    public static ArrayList EnumerateDomains()

    {

       ArrayList alDomains = new ArrayList();

       Forest currentForest = Forest.GetCurrentForest();

       DomainCollection myDomains = currentForest.Domains;

       foreach (Domain objDomain in myDomains)

       {

           alDomains.Add(objDomain.Name);

       }

       return alDomains;

    }

    http://www.lepide.com/

  2. anthony lee says:

    There is something called Corporate Directory. It is an <a href="http://www.corporate-directory.net">address book software</a> that automatically detects you MS domain and reads all contact information from it. It is a client application that runs as a tray icon. The best thing about it is that it uses a "google like" search box. You find results as soon as you start typing a person's name or any other property like title, department etc… The company name is View2C. Let me know if this is what you are looking for.

  3. Teddy says:

    thanks for sharing this.

    This is working for adding user from remote forest to local forest's group, but it seems it does not work for adding group from remote forest to local forest group. From the error message, it is still trying to find the remote group DN from local forest domain NC inside AD.  

    Trying to add forestAGroup to ForestB's builtin administrators group:

    $ForestAGroup = Get-ADGroup "ForestAGroup" -Server ForestA    

    $ForestBBuildinAdministraotrsGroup = Get-ADGroup "Administrators" -Server ForestB

    Add-ADGroupMember $ForestBBuildinAdministraotrsGroup -Members $ForestAGroup.DistinguishedName

    Is that because Get-ADGroup's session information does not contain  the "Server=ForestA " ?

    Any other solutions? Thanks

  4. For removing users it seems does'nt work. In my environment it fails. This is my code:

    $probeta = get-aduser "probeta" -server ServerDomainB

    $Grupo = get-adgroup "Grouper" -server ServerDomainA

    Remove-ADGroupMember $Grupo -Members $probeta -server ServerDomainA

    Result: Remove-ADGroupMember :Specied account name does not belongs to group.

  5. Hello,

    I think Remove-ADGroupMember AD-PowerShell has a bug with parent and child domain Scenario, but worked find with 2x forest Scenario.

    Please check this link:

    social.technet.microsoft.com/…/b44c5459-b89a-4e7a-bb6f-3cd002635676

    But Remove-QADGroupMember QUEST Active Directory command worked fine.

    Regards

  6. Cross domain support in the AD cmdlets is essentially appalling.

    I've just written a script to remove expired users from groups and those groups exist cross forest. In order to do this in a script that runs against many users I've had to use multiple try catches to make it work.

    try domain1 catch try domain2 catch etc.

    This script also works against mailboxes, with exchange 2010 I can run one cmdlet to work cross forest: set-adserversettings -viewentireforest $true

    Please sort this for the AD cmdlets.

    Please note that with the get cmdlets you can get away with using the GC port, but only if the attributes you want to look at are replicated to the GC. The Set cmdlets, no dice.

  7. Jason Sherry says:

    This doesn't seem to work if the User is in Domain A and the group is Domain B.

    At least I wasn't able to figure it out, when running it in Domain A. Domain A & B are in the same forest.

  8. Mat says:

    Hi Swami

    "The variable $forestBBBUser in the above example contains “server = $forestBBB” in its session information, which is stored internally and is not visible/accessible via command line."

    How do you create the “server = $forestBBB” ?

  9. John Jones says:

    How can I adapt this to add a contact in DOMAIN A to a GROUP in Domain B.  This works GREAT for USERS, but I can NOT get it to work for CONTACTS….AT ALL…I have tried a hundred different things, but it does NOT like my contact variable.

  10. Arjun Prasad says:

    Thanks Swami

    Works like a Charm

    Adding to what you have already mentioned

    If the Trust between your Forest is One-Way

    The script should be run from the Trusted Forest

    Running it from the Trusting Forest will only end up in the error "Server has rejected your credentials"

  11. Dan Reeder says:

    found a different method… no matter what I tried, the remove-adgroupmember (and similar) commands just wouldn't work across domains (my situation = two domains within one forest)

    This worked:

    $user = get-aduser <username> -server abc.domain.com

    $group = get-adgroup <group> -server xyz.domain.com

    Set-ADObject -identity $group -remove @{member=$user.DistinguishedName} -server staff.ad.bond.edu.au

  12. Anirudh says:

    @Dan Reeder .

    Wow! Thank you so much! After some intense search, people! this is the answer!!

  13. Baterias says:

    @Dan Reeder . Yes, it Works for me. Thanks.

  14. JBS says:

    Set-ADObject worked for me – 2008R2. Thanks.

  15. DRs says:

    Something like this would be nice.

    add-adgroupmember NameOfGroup -Member domainusername

    or

    add-adgroupmember NameOfGroup -Member user@domain.net

  16. DRs says:

    This would be nice…

    add-adgroupmember groupname -member NTAccountName

    or

    add-adgroupmember groupname -member UPN

  17. Mitch says:

    The problem with this is…it adds the user into the group and displays LOGON NAME not the firstname lastname format you get when using the gui…is there a way to mirror the values shown when using the gui?

  18. Jan Ryen says:

    I just did like this:

    $sourceusers = Get-ADGroupMember -Identity "CN=bbb-users,OU=Security Groups,DC=bbb,DC=domain,DC=com" -Server bbb.domain.com

    Add-ADGroupMember -Identity "CN=test,OU=Security Groups,DC=aaa,DC=domain,DC=com" -Members $sourceusers