PowerShell V2 script to count the number of values in every non-linked multi-valued attribute of a specified object. The numbers are reported for each such attribute that has at least one value. Finally, the script reports the grand total number of values for all of the attributes. This grand total is limited by the system. If the forest functional level (FFL) is Windows 2000 Server, the limit is about 800 to 850 values. If the FFL is Windows Server 2003 or above, the limit is about 1200 to 1300 values.


The script accepts either a sAMAccountName or distinguished name. The script retrieves all multi-valued attributes of the object that have at least one value. For each attribute, the schema is checked to eliminate linked attributes, which are not limited. For each remaining attribute the script reports the lDAPDisplayName of the attribute, followed by the count of the number of values in parentheses. Finally, the script reports the sum of all of the counts. This last number is limited by Active Directory. When the limit is reached, the error reported is "The administrative limit for this request was exceeded".

 

PowerShell
Edit|Remove
# CountValues.ps1 
# PowerShell V2 script to count the total number of values in all non-linked 
# multi-valued attributes of an object in Active Directory. 
# Author: Richard Mueller 
 
# Credit: Parts of this script are based on ideas in the script 
# Find-BloatedObjects.ps1 by Tony Murray (dated Sept. 18, 2014). 
# http://www.open-a-socket.com/index.php/2014/09/19/multivalued-attribute-limits-in-active-directory/ 
 
# Note: This script considers attributes that are not replicated to all domain 
# controllers, like the dSCorePropagationData, repsFrom, repsTo, and subRefs attributes. 
# Such attributes can have different numbers of values on each DC. It is not known if 
# such attributes affect the limit on the total number of values for all non-linked 
# multi-valued attributes of any object in Active Directory. 
 
# Version 1.0 - August 13, 2015 
 
# Check for parameter identifying the object. 
# If the parameter has embedded "$" or "`" characters, either have the script prompt for 
# the value, or enclose the parameter in single quote characters on the command line. 
If ($Args.Count -eq 1) 
{ 
    $ADObjectName = $Args[0] 
} 
Else 
{ 
    $ADObjectName = Read-Host "Enter object sAMAccountName or distinguishedName" 
} 
 
Import-Module ActiveDirectory 
 
# Only consider multi-valued attributes. 
$Collection = "Microsoft.ActiveDirectory.Management.ADPropertyValueCollection*" 
 
# Check the schema for non-linked attributes. 
$SchemaNC = (Get-ADRootDSE).SchemaNamingContext 
 
# Retrieve the values of all default and extended properties exposed 
# by Get-ADObject, plus all AD attributes that have values. The Get-ADObject 
# cmdlet is used because it supports all classes of objects and exposes fewer 
# default and extended properties than other cmdlets. Also, the ones it does 
# expose are not multi-valued. This prevents attributes being included twice, 
# once by PowerShell property name, and a second time by lDAPDisplayName. 
$ADObject = $Null 
If ($ADObjectName -Like "*,*") 
{ 
    # $ADObjectName is the distinguished name of an object. 
    $ADObject = Get-ADObject -Identity $ADObjectName -Properties * 
} 
Else 
{ 
    # $ADObjectName is the sAMAccountName of an object. 
    $ADObject = Get-ADObject -LDAPFilter "(sAMAccountName=$ADObjectName)" -Properties * 
} 
If ($ADObject -eq $Null) 
{ 
    "Object $ADObjectName not found" 
    Break 
} 
 
# Retrieve lDAPDisplayNames of multi-valued attributes that have values or 
# correspond to default or extended properties exposed by Get-ADObject. 
$Props = $ADObject | Get-Member -MemberType Property ` 
    | Where {$_.Definition -Like $Collection| Select -ExpandProperty Name 
 
$NTName = $ADObject.sAMAccountName 
If ($NTName -eq $Null) 
{ 
    $ADObject.distinguishedName 
} 
Else 
{ 
    $ADObject.distinguishedName + " (" + $ADObject.sAMAccountName + ")" 
} 
"Non-linked multi-valued attributes with values:" 
"-----" 
$Total = 0 
ForEach ($Prop In $Props) 
{ 
    # Check if the attribute is linked. 
    $Linked = (Get-ADObject -SearchBase $SchemaNC ` 
        -LDAPFilter "(&(objectClass=attributeSchema)(lDAPDisplayName=$Prop))" ` 
        -Properties linkID).linkID 
    # Only consider non-linked attributes (no linkID) that have 
    # at least one value. 
    If (($Linked -eq $Null-And (($ADObject.$Prop).Count -gt 0)) 
    { 
        # Display the attribute lDAPDisplayName and the number of values. 
        $Prop + " (" + ($ADObject.$Prop).Count + ")" 
        # Sum the number of values of all non-linked multi-valued attributes 
        # for this object. 
        $Total = $Total + ($ADObject.$Prop).Count 
    } 
} 
 
"Total number of values: $Total"