Active Directory Shadow Groups: How To Automatically Add OU Users To Security Groups

Remember Novell? Remember NDS or eDirectory as it later became known? NDS might be mostly dead, in favor of AD (Active Directory), but NDS did have many advantages over AD, and one of them was the ability to assign rights (permissions) via OU membership. Want to give users in a specific OU access to a particular file system folder? No problem in NDS, just assign the OU (container) to the folder. But there is no direct way to do this kind of OU (container) assignment in Active Directory. Some applications with integrated access to AD allow for OU assignments, but that doesn’t help you with your day-to-day maintenance of your Active Directory domain.

What cannot be done out-of-the-box in Active Directory can be accomplished with a simple PowerShell script (below). You can use this script to automatically add members to a “shadow group.” This is not an actual type of group, but more or less an adopted term for the process of automatically assigning users to a group. It isn’t just limited to OUs. You could, for example, create a script that assigns all users with a specific attribute value to a group. But this article will just focus on OU shadow groups.

Members Only - photo by momopeche

THE TASK

Assign all members of an Organizational Unit (OU) to a Security Group automatically, without manual intervention. This will not be a real-time sync, but this group should reflect the current OU user list within a reasonable time frame (for example: every 24 hours).

PREREQUISITES

The PowerShell script requires access to the Active Directory cmdlets for PowerShell.

Run this command in PowerShell to install the cmdlets:

Import-Module ActiveDirectory

If that doesn’t work, you will need to follow these instructions.

THE POWERSHELL SCRIPT

$OU="OU=TheOUName,DC=yourdomain,DC=com"

$ShadowGroup="CN=ShadowGroupName,OU=TheOUName,DC=yourdomain,DC=com"

Get-ADGroupMember –Identity $ShadowGroup | Where-Object {$_.distinguishedName –NotMatch $OU} | ForEach-Object {Remove-ADPrincipalGroupMembership –Identity $_ –MemberOf $ShadowGroup –Confirm:$false}

Get-ADUser –SearchBase $OU –SearchScope OneLevel –LDAPFilter "(!memberOf=$ShadowGroup)" | ForEach-Object {Add-ADPrincipalGroupMembership –Identity $_ –MemberOf $ShadowGroup}

HOW IT WORKS

First you set the variables. — $OU defines the “distinguishedName” of the organization unit. You can find the distinguishedName in the Attribute Editor tab in the properties of the OU. Make sure you are in “Advanced Features” view in Active Directory Users and Computers. This is set in the View menu. — $ShadowGroup defines the distinguishedName of the Security Group you intend to use as your “shadow group.” This group MUST EXIST before you run the PowerShell script.

The Get-ADGroupMember portion of the script will parse all existing users who are a member of the “shadow group” and remove users who no longer are in the OU. The Get-ADUser portion of the script will parse all users in the OU and add them to the “shadow group.”

After you run the script, your shadow group user membership will be identical to the OU user membership.

RUN IT AUTOMATICALLY

I did say this process would not require manual intervention and for that to be true you need to schedule this PowerShell script to run via Task Scheduler. You can copy the above script, paste it into a text file with a “ps1″ file extension, and edit it for your environment. You can run this scheduled task on a domain controller, although it is typically frowned upon to run scripts on DCs. So you might want to pick another domain member server for this task. How often the task runs will depend on your environment. In most cases every 24 hours is fine, but if you need something that is closer to real-time, you might need to schedule it to run every hour (or less).

Below is an example Action on a scheduled task to run a PowerShell script on a Windows 2008 Server.

Action: Start a program

Program/script: C:\Windows\system32\windowspowershell\v1.0\powershell.exe

Add arguments (optional): -command C:\scripts\shadow-group.ps1

 

PLEASE NOTE: Some of our readers have offered great suggestions for customizing this script. Check out the comments section below for their ideas, and please share your own ideas as well.

photo by momopeche

Special thanks to blogger Andreas (Talk nerdy to me) for the PowerShell script.

Get The Roo In Your Inbox

Receive The Roo Report only when new content is posted. We promise the Roo will be on his best behavior!

About David K. Sutton

Primary Contributor and Founder — With over two decades experience in Information Technology including: Active Directory, Remote Desktop Services, Citrix XenApp and Netscaler, SQL Server, VMware vSphere and vCenter, NetApp SAN, Cisco routers, switches and firewalls.

Related Posts

  • Matt Montgomery

    How do you bypass the sizelimit or maxresults? I have an OU with about 7,000 users in it and I want to use this script.

    • http://leftcall.com/ David K. Sutton

      I can’t say I’ve ever encountered this (don’t have any OUs with more than a few hundred users). Have you tried?…

      -ResultSetSize $null

      …on the Get-ADUser command?

      • Rafael Dorville

        Good morning Matt and David,

        Regarding your question Matt, you just need to replace the –SearchScope OneLevel to –SearchScope subtree on the Get-ADUser command and it should do the trick.

        Thank you David for this great script.

        • Biddyman

          You actually have to use .NET LDAP to get past the size limit Matt. Of course, I’m still researching what I need to do as I’m in same boat with over 10,000 users in OUs. The only other way to overcome size limit that I know of is to change setting on DC(s) web config.

  • Guest

    Hi, Thanks for this script. Do you think there’s a way to add users from a trusted domain, which is not part of the same forest? When I try to do this using the DN of the OU in the trusted domain I get “The supplied distinguishedName must belong to one of the following partitions” and it just lists the current domain.

  • Sebastian Grigoleit

    I am a script noob, but is there a way to add more OUs in same script? insert another line or something?

    • http://leftcall.com/ David K. Sutton

      I assume you are asking to include users from multiple OUs in one Shadow Group? I’m not sure of the syntax to make that happen with this script, but I can offer an alternative approach. You could create Shadow Groups for each OU, then for the OUs that you want to have combined, create another group and add the corresponding Shadow Groups to that group. Hopefully that made sense.

      • Guest

        This may be too late to help you, but for future reference I just tested this exact thing. If the other OU’s are nested under the one you’ve set as $OU, you simply need to remove the “–SearchScope OneLevel” from the last command (the default is “subtree” so it will then include everything under your OU you specify).

        For a totally separate OU, you need to add a few things:

        1. Declare variables for the other OU’s to include.

        2. In the Get-ADGroupMember command, incorporate the OUs into the Where-Object filter. Using “-and” here means it will find group members that do not exist in ANY of the included OUs.

        Get-ADGroupMember –Identity $ShadowGroup | Where-Object {($_.distinguishedName –NotMatch $OU1) -and ($_.distinguishedName -notmatch $OU2)} …

        3. Duplicate the Get-ADUser command for each OU, replacing the variable. No need to combine them into one command, since the group is intended to be a combination of all the OUs anyway.

        • http://www.davidksutton.com/ David K. Sutton

          Thanks for taking the time to reply with your findings. It’s great to give people options beyond the scope of this article. In fact, there are now several great replies to this article, so I’m going to edit the original article to mention that people should check out the comments section for more ideas and suggestions. Thanks again.