Saturday, July 30, 2011

Shadow Groups in Active Directory

Shadow Groups (SG) is an interesting topic. It’s not an actual type of group in the sense of security, distribution, global, domain local or universal, but rather a concept. A shadow group is a global security group which reflects the users found in a specific organizational unit (OU) in its group membership.

Shadow groups can be used for Fine Grained Password Policies, which can be applied to users (or inetOrgPerson objects) and global security groups only. Or if every user within a specific OU will require the same access to a resource, you can use shadow groups.

This means that you always want to keep the shadow groups up to date. If a new user is moved to the OU, it must also be added to the group. Likewise if a user is removed from the OU, it must also be removed from the group. There is no difference between a regular group and a shadow group in the sense that shadow groups bring any new or extra functionality when it comes to administration. These are just regular groups, but with a very specific purpose.

Keeping them up to date manually is really not an option, unless perhaps you know every single employee in the company personally and you are the only one managing AD. People aren’t machines, they make mistakes, it’s only human. Sooner or later, someone will forget to update the group when a user is moved between OUs.

This is when automation comes in handy. Anything that does not require human input should be automated.

Here we have a very simple criteria:
Users found in a specific OU should always be a member of a specific security group.
This does not require any human input or modification. We just need a way to compare the users in the OU with the users in the group and make any necessary changes.

Trust me when I say that there are many ways to do this. More than I will show you. I will limit this to the ds-tools and the PowerShell AD-cmdlets.


The Quick and Dirty version:
dsquery user “<Organizational Unit distinguishedName>” –scope onelevel | dsmod group “<Shadow Group distinguishedName>” –chmbr

This will look for all users found in the specified OU, and limit the search to that OU only. Then it will clear the current group membership of the SG and add all users currently found in the OU.

The Clean and Clever batch file version:
Set OU=Organizational Unit distinguishedName (without quotes)
Set Group=Shadow Group distinguishedName (without quotes)

dsget group %Group% –members | find /v /i “%OU%” | dsmod group “%Group%” –rmmbr
dsquery * “%OU%” –filter “(&(sAMAccountType=805306368)(!memberOf=%Group%))” –scope onelevel | dsmod “%Group%” –addmbr

This will look at the group membership, pipe it to the find command, to find only the users where the OU’s distinguishedName is NOT present, and then pipe it to dsmod group to remove those users from the group. The next step is to look for all users in the specified OU that are NOT member of the Shadow Group already. It will then add any users found to the group.


Windows Server 2008 R2 with Active Directory cmdlets:
$OU=”Organizational Unit distinguishedName”
$Group=”Shadow Group distinguishedName”

Get-ADGroupMember –Identity $Group | Where-Object {$_.distinguishedName –NotMatch $OU} | ForEach-Object {Remove-ADPrincipalGroupMembership –Identity $_ –MemberOf $Group –Confirm:$false}
Get-ADUser –SearchBase $OU –SearchScope OneLevel –LDAPFilter “(!memberOf=$Group)” | ForEach-Object {Add-ADPrincipalGroupMembership –Identity $_ –MemberOf $Group}

This will do the same thing as the ds-tools clean and clever version, except it’s done in PowerShell with the AD cmdlets.

Once you’ve decided for what approach you want to take, you can easily create a scheduled task for this and ensure that the batch or PowerShell script runs at intervals that suits your organization. Just make sure that the user account the scheduled task runs under has got the proper privileges (such as log on as batch job and permission to update the Shadow Groups (write members) in Active Directory).


  1. Thanks for this very helpful, what can I do if I want the script to to check a number of OUs and add the accounts into the security group?

  2. To keep it neat, I would probably create several shadow groups (I'm guessing the users are in different OU:s for a reason -this way you can re-use the same shadow groups later) and then add these shadows groups to a regular security group which grants all the members of the shadow groups the proper access/permissions.

    Of course it's possible for the script to add users from many OU:s to a single group, but it gets a bit more complex when it comes to removing users, that should no longer be there, from the group. I'm thinking you'll want to add all the users from the different OU:s to an array first, and then compare the current group members to all the users contained within the array.

  3. Thanks for the reply. I have different OUs for each city, and in each City OU is an OU for Laptops.

    I need to join all computer accounts in the Laptop OU for every city to a security group.

    So you think I should create a shadow group for each Laptop OU, and then have each of those shadow groups a member of the security group?

  4. Yeah, that's how I would do it. I think it's the better solution. This way you can also single out a particular city's laptop, because they're already in a group of their own.

  5. I have universal groups I am managing and i need to automatically to remove members from another domain within the forest. Adding -Server $domain to Remove-ADGroupMember is not doing it.