Get all possible AD Attributes for User or Group

Get all possible AD Attributes for User or Group

I recently had to work out what the full set of attributes was that could be set against a user or a group in Active Directory.  My first thought was ok why not just grab a user in PowerShell and ask to see all properties

Get-ADUser -ResultSizeLimit 1 -Filter * -Properties *

However that only returns a subset of properties, to be precise it returns the properties of all Structural classes that a user is derived from.  So how do I get the full set…

We know that Active Directory is built from classes and attributes, and we know that an AD object has an attribute called ObjectClass which is the class that this object is instantiated from. (It’s a multi-valued attribute but the first value is the actual class that this object is from)  For a user this is generally organizationalPerson.

$ADUser = Get-ADUser -ResultSetSize 1 -filter * -Properties objectClass

Now we have the class we can check the schema for other related classes.  We need to look for SubClassOf, AuxiliaryClass, and SystemAuxiliaryClass which are the three ways that classes can be related.  Now they in turn can also be a subclass or have auxiliary/systemAuxiliary classes, so recursion is a good way to get the full list

Function Get-RelatedClass {
  param( [string]$ClassName )
  
  $Classes = @($ClassName)
  
  $SubClass = Get-ADObject -SearchBase "$((Get-ADRootDSE).SchemaNamingContext)" -Filter {lDAPDisplayName -eq $ClassName} -properties subClassOf |Select-Object -ExpandProperty subClassOf
  if( $Subclass -and $SubClass -ne $ClassName ) {
    $Classes += Get-RelatedClass $SubClass
  }
  
  $auxiliaryClasses = Get-ADObject -SearchBase "$((Get-ADRootDSE).SchemaNamingContext)" -Filter {lDAPDisplayName -eq $ClassName} -properties auxiliaryClass | Select-Object -ExpandProperty auxiliaryClass
  foreach( $auxiliaryClass in $auxiliaryClasses ) {
    $Classes += Get-RelatedClass $auxiliaryClass
  }

  $systemAuxiliaryClasses = Get-ADObject -SearchBase "$((Get-ADRootDSE).SchemaNamingContext)" -Filter {lDAPDisplayName -eq $ClassName} -properties systemAuxiliaryClass | Select-Object -ExpandProperty systemAuxiliaryClass
  foreach( $systemAuxiliaryClass in $systemAuxiliaryClasses ) {
    $Classes += Get-RelatedClass $systemAuxiliaryClass
  }
  Return $Classes  
}

The above function returns all of the classes related to a given classname, so let’s call it to get the full set
$AllClasses = ( Get-RelatedClass $ADUser.ObjectClass | sort -Unique )
Ok so we have a full list of classes, and for better performance we’ve made it a unique list.  Now we need to get the attributes which can be in any of four attributes on a class
  • mustContain
  • systemMustContain
  • mayContain
  • systemMayContain
So we just need to cycle through all classes and collect up all of the attribute names
$AllAttributes = @()
Foreach( $Class in $AllClasses ) {
  $attributeTypes = 'MayContain','MustContain','systemMayContain','systemMustContain'
  $ClassInfo = Get-ADObject -SearchBase "$((Get-ADRootDSE).SchemaNamingContext)" -Filter {lDAPDisplayName -eq $Class} -properties $attributeTypes 
  ForEach ($attribute in $attributeTypes) {
    $AllAttributes += $ClassInfo.$attribute
  }
}
$AllAttributes = ( $AllAttributes | sort -Unique )
We now have a complete list of attributes and we can use that list to get the rest of the properties for each attribute.
$AttributesOfInterest = @()
Foreach( $Attribute in $AllAttributes ) {
  $AttributeInfo = Get-ADObject -SearchBase "$((Get-ADRootDSE).SchemaNamingContext)" -Filter {lDAPDisplayName -eq $Attribute} -properties ldapDisplayName, attributeId, isSingleValued, attributeSyntax, systemOnly, linkId, isDeleted, rangeLower, rangeUpper
  $AttributesOfInterest += $AttributeInfo
}
$AttributesOfInterest = $AttributesOfInterest | sort ldapDisplayName -Unique
You can filter out SystemOnly attributes (although beware that you need to look for not equal to True, as it can be null, false or true).  You can filter out backlinks by using mod 2 not equal to 1, since backlinks always have an odd LinkID, etc. (Find out more about Back Links)
There you have it, a ‘simple’ script to grab all of the attributes for a user.  If you change the first two lines to get an AD group then it will get everything for a group.  It will work with other objects just the same.  Hopefully this helps someone and avoids them looking for ways to get every possible attribute 🙂
Related posts: