Partager via


Active Directory PowerShell: Private Clouds and the Tale of Too Many Nested AD Groups

 

I’ve ran into this issue a few times now so I’m assuming its becoming more and more of a trend.  There are lots of blogs that talk about how to clean up token bloat and how to deal with SID history but very few address cleaning up unused groups and how to deal with groups that have been over nested.

This explains what could happen if a group is nested into many groups: Logging on as user account that is a member of more than 1,010 groups may fail on a Windows Server-based computer

What it Looks like when a user tries to log in with a large number of group memberships.  Not Good!!

image

The Scenario

Private Cloud is implemented into Enterprises. when a VM is provisioned, The Cloud Admins have decided to provision a set of Active Directory (AD) objects to go along with each and every VM. 

image

The idea is simple (However Not Recommended):

  • Create AD Groups for different task required for a server, Nest the AD Group into a local group on the server.
  • Create services accounts, the server’s application MAY need.
  • Place Server Admins / Application Admins User accounts into the appropriate group when they need to perform task on the server. (“Just in Time”)

 

image

Usually the problem:

  • No solution is in place to move Admin’s User Account in and out of AD Groups as needed.
  • When server is decommissioned, nothing in place to clean up the AD Group or Service Account User Objects.
  • Admin Staff gets lazy and starts nesting these groups in other groups to simplify their access.

What happens if Domain Users accidentally becomes a member of one of the many nested groups?  (refer back to link provided above)?

 

Removal of Server not resulting in removal of groups Sad smile

image

 

How to clean this up:

  1. Discovery,  has the environment seen an increase of AD groups created over the last year.  Usually the number is higher or has a pattern that will result in higher than previous years.
  2. Is there any groups that are members of a large number of groups or are nested in a large number of groups
  3. Has a stale group clean up process been implemented?

 

Discover Group Growth

This script will show the number of groups added to Active Directory over the history of the forest.  Usually you will see a trend that groups are being created at a faster pace than previous years.

Demo Script can be found here:  Github Link: DetectADSecurityGroupGrowth

Results will look something like this:

image

This shows that this month had a huge amount of groups created and the location of a majority of the groups created over the last year was in a Private Cloud OU.

Discover Group “Over” Nesting

The next step will be to go out and determine if any groups are in a over nesting scenario.  This is were the group is a member of several other groups.  Small numbers aren’t the concern, we want to watch for groups that are over nested.

Demo Script can be found here:  Github Link: ExpandADGroupMembership  (this will take a while to run if a lot of group nesting exist)

image

The groups found in the results are over nested, and need to be evaluated. Work with the object owners to come up with a different solution. In this case adding the allserveradmin group directly to every server would have ended with the same results and wouldn’t have increased the admins group token count.

 

Implement Clean Up

All of these scripts use the group attribute msDS-ReplValueMetaData, which contains replication data around linked attributes.  I could have easily combined the queries into one but wanted to allow granularity between possible ad group clean up task as I see them.  Each script is a wrapper functions that leverage the Active Directory Module cmdlets.

  1. Retrieve groups that have never ever been used (member, memberof and msDS-ReplValueMetaData will be empty). Consider creating a process to discover and remove groups that have been created but never used after 6 months.
  2. Retrieve groups with no members but have had members in the past (member is currently empty and msDS-ReplValueMetaData contains date info).  Display the last date the last member was removed.  Review the list, If a group hasn’t been modified in last 2 years consider removing.
  3. Retrieve groups with members and leverage data out of the msDS-ReplValueMetaData to determine the last time group membership truly changed.  If a group hasn’t been changed in 3+ years is it still being used?  Determine if any of its members are groups before removing.

 

The idea of these scripts are to assist in helping identify the problem before it becomes a problem.  Ideally a mapping of where all the groups are leveraged would be preferred, but auditing every resource and application is a big task.  Microsoft Premier Customers can work with their Technical Account Manager on signing up for the ACLXRAY Delivery which does auditing of Active Directory Object using throughout a forest.

That is all for today

-Chad

 

Possible Solutions:

Privileged Access Management for Active Directory Domain Services

Just Enough Administration

More Reading about msDS-ReplValueMetaData:

Metadata #2 – The ephemeral admin, or how to track the group membership

Accessing Replication Metadata using ADPowerShell

Comments

  • Anonymous
    June 01, 2018
    Great entry Chad. I like your usage of msDS-ReplValueMetaData to determine whether a group has been used frequently. I’ll be making use of this no doubt.I have one suggestion for an additional feature. If you it’s not already there, being able to export the data produced during discovery to a CSV would be great. That data could then be fed into a BI tool like PowerBI to produce visual representations of the data. I’ve found from direct experience that communicating this problem to non-technical folks is much easier with the visuals.
    • Anonymous
      June 01, 2018
      all of the scripts dump to a csv file just for that reason, I could always add a pbix file to consume the information. I also need to update the scripts to use a hashtable instead of an array. I found in large complex nesting scenarios the expanding the nesting takes a little longer than I would like.