Zoho Banner September 2011

There was in interesting discussion the other day on the ActiveDir.org mailing list. Someone asked how many values can be stored within the proxyAddresses mutlivalued attribute in Active Directory. The responses were reasonably consistent, with most people indicating that in Windows 2000 the number was in the range of approximately 800 to 850 and from Windows 2000 the range is approximately 1200 to 1300.

This begs the question of why we can’t be specific about the number. Well, it comes down to how the data is stored within the Active Directory database (ntds.dit). Most of the attribute data for an individual object is stored within a single row in the Data Table within the database. I say “most” because linked attribute data (e.g. member/memberof, manager/directReports, etc.) is kept in a separate table (the Link Table). The AD schema determines how many attributes are available for a particular object and this obviously varies a lot from forest to forest, as does which of those possible attributes actually have populated values. There are also some overhead requirements that vary. All this combines to make it impossible to determine with any accuracy how many values an individual multivalued, nonlinked attribute can have.

Because I have an enquiring mind (some would say “nosey bastard”), I decided to try and hit the limit in my test lab. I did this by running a Powershell script to keep adding SMTP addresses to the proxyAddresses attribute for a user until an exception was thrown. I got to 1192 before I got the “The administrative limit for this request was exceeded” error (see below).

admin_limit

As Don Hacherl (former dev lead for AD at Microsoft) pointed out to me on the mailing list, the non-linked attribute limit is a limit across all non-linked attributes on the object. So for example, if I had added a telephone number before running the script then I would have only got to 1191 values on proxyAddresses.

Don also made is clear that under normal circumstances you shouldn’t need to be anywhere near the limit. In his words…

“The limit is supposed to be high enough that the only time you’ll hit it is when you have made an architectural error in your schema usage. Asking questions about the exact number of a limit that you have not yet hit is often a warning sign of your burning desire to make an architectural error in the future.”

I found a Powershell script on Experts Exchange that seemed to be useful for detecting errant objects that have a high number of values within an individual multivalued attribute. I’ve hacked with it a bit and have ensured that it now excludes linked values. Here it is for anyone that is interested.

#########################################################
#
# Name: Find-BloatedObjects.ps1
# Author: Tony Murray
# Version: 1.0
# Date: 18/09/2014
# Comment: PowerShell 2.0 script to
# find objects with an unusually large number of values
# within a non-linked multi-valued attribute
# Credit: Parts of the script are from a solution posted by 
# footech on Experts Exchange here:
# http://tinyurl.com/md3cvzn
#
#########################################################

Import-Module ActiveDirectory
$queryCount = 1000 # adjust this if you need to
$snc = (Get-ADRootDSE).SchemaNamingContext
$dnc = (Get-ADRootDSE).DefaultNamingContext
$def = "Microsoft.ActiveDirectory.Management.ADPropertyValueCollection*"
$objs = Get-ADObject -Filter * -Properties * -SearchBase $dnc

ForEach ($obj in $objs) {
    #Write-Output "Looking at object $obj.distinguishedname"
    $ADOprops = $obj | gm -MemberType Property `
    | Where { $_.Definition -like $def } `
    | Select -ExpandProperty Name
        foreach ($prop in $ADOprops) {
            #Write-Output "Looking at property $prop"
            $fl = "(&(objectclass=attributeschema)(ldapdisplayname=$prop))"
            $linked = (Get-ADObject -LDAPFilter $fl -SearchBase $snc -pr linkid).linkid
            #Write-Output $linked
            If (($linked -eq $null) -and (($obj.$prop).count -gt $queryCount)) {
                Write-Output "----------------------------------------------"
                Write-Output "AD Object ""$($obj.DistinguishedName)"""
                Write-Output "has attribute ""$prop"" with a count of $($obj.$prop.count)"
            } # end if
        } # end foreach
} # end foreach

Feedback is, as always, very welcome!

 

2 Comments

  1. Mike Crowley says:

    Helpful when dealing with user certificates!

  2. Exchange 2013 domainprep (prepareAD) fails with Microsoft.Exchange.Data.Directory.AdminLimitExceededException [ERROR_DS_ADMIN_LIMIT_EXCEEDED] - mahuynh - Site Home - TechNet Blogs says:

    […] and see it only has 17 values; that can't be our issue. We leverage the script from http://www.open-a-socket.com/index.php/2014/09/19/multivalued-attribute-limits-in-active-directory/ and realize that several attributes, including globalAddressList and globalAddressList2 have over […]

Leave a Reply