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).
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!
Helpful when dealing with user certificates!
Pingback: Exchange 2013 domainprep (prepareAD) fails with Microsoft.Exchange.Data.Directory.AdminLimitExceededException [ERROR_DS_ADMIN_LIMIT_EXCEEDED] - mahuynh - Site Home - TechNet Blogs
that someone was me. good old dayz.
“I used to work at a bank in those days. They were requesting a single email address for all bank branches nationwide, alongside a phone number for each branch.
0216xxxxxxx@bank.com etc.
So I asked that question for that purpose and I had to create 3 mailboxes because we had ~1000 branches and it didn’t fit in a single proxyaddresses attribute.
Those were the days indeed :-). Thanks for providing the background.