Ranged AD query for msDS-ReplValueMetaData throws errors
Query Active Directory using the property msDS-ReplValueMetaData returns unexpected value if more than 1000 objects are stored in the attribute resulting in errors and an infinite loop:
Find-LdapObject -LdapConnection $LDAPServer -searchBase "CN=group,OU=Org,DC=domain,DC=net" -searchScope base -searchFilter "(objectclass=*)" -PropertiesToLoad "msDS-ReplValueMetaData" -RangeSize 1000
Index operation failed; the array index evaluated to null.
At C:\Program Files\WindowsPowerShell\Modules\s.ds.p\2.1.6\S.DS.P.psm1:2460
char:33
+ ... $data[$attrName] += $srAttr.Attributes[$returnedAttrName] ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
You cannot call a method on a null-valued expression.
At C:\Program Files\WindowsPowerShell\Modules\s.ds.p\2.1.6\S.DS.P.psm1:2462
char:32
+ ... if($returnedAttrName.EndsWith("-*") -or $returnedAttrName -e ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
The same does not happen retrieving member attribute.
This happens as AD returns for whatever reason the original asked attribute as well as the ranged value attritbute:
$rsp.Entries
DistinguishedName Attributes Controls
----------------- ---------- --------
CN=group,OU=Org,DC=domain,DC=net {member} {}
$rsp.Entries
DistinguishedName Attributes Controls
----------------- ---------- --------
CN=group,OU=Org,DC=domain,DC=net {msds-replvaluemetadata, msds-replvaluemetadata;range=0-999} {}
msds-replvaluemetadata;range=0-999 is not expected in the initial query.
The foreach($attrName in $AttributeNames) will fail when getting to the second, invalid, entry.
I solved this using an ugly workaround, slightly changing the loop
$AttributeNames = $sr.Attributes.AttributeNames | Where-Object {'' -eq $PropertiesToLoad -or ( $PropertiesToLoad -contains $_ ) -or ( $AdditionalProperties -contains $_ ) }
foreach($attrName in $AttributeNames) {
This should allow for no entries (like propertiesToLoad '') or a set of properties or even a manual ranged search (like propertiesToLoad "msDS-ReplValueMetaData;range=1000-1999") . Though I don't know if I can expect $PropertiesToLoad to either contain nothing () or the full list of attributes that might ever be returned in the first search.