No Matter Where You Go, There You Are: Retrieving Data from Active Directory
One of the more common things IT Pros who work with Active Directory need to do is actually view or collect information from AD. That is true for AD administrators, application or service administrators, security specialists-pretty much any role in an environment where Active Directory is the store for user identities. The related roles which need data from AD are as varied as the methods with which you can collect that data. There’s a lot of both.
It seems go without saying, right? There can be difficulties in how and from where that data can be collected though. Those difficulties can be an obstacle to get the information needed to get your role done.
The difficulties can boil down to simply not having the Remote Server Administration Tools on the computer the data retrieval is coming from which ultimately leads to having the Active Directory PowerShell module available or installed.
This is particularly relevant in a scenario where you have a PowerShell code which may be executed on remote computers which may not have the Remote Server Administrations Tools (and hence the AD PS module) on them.
In addition, there is one thing the AD PowerShell module does not do and that is retrieve Active Directory object replication metadata. AD object replication metadata is a set of information which domain controllers use to track the update applicability for attributes. It is commonly referred to when attempting to track an update through AD to see if it has applied successfully or to gather some forensic information about where an update originated from and when it originated.
The typical way to glean this data is to use Repadmin.exe’s “Showobjmeta” switch and specify the distinguished name (DN) of the object you are interested in. DNs can be tough to simply jot down even when you know the entire path to an object. Often we don’t know the path to an object and must search for it in AD first to get the DN in order to then use it with Repadmin.exe.
To work around these obstacles, and as part of the needs for the Microsoft support diagnostics, I’ve written a PowerShell script. The script can be downloaded from the Microsoft Technet Script Gallery at this link.
The GetADObjectData.ps1 script will do Active Directory searches for a specified objects attribute values and can also retrieve the AD replication metadata for the object.
More about the script:
- The script has four switches
- “ObjectName”: The switch should contain the name or samaccountname (string) of the target object to retrieve data from. If none is supplied then the script will use the locally logged on user’s $env:username variable.
- “ADAttrs”: This is a Boolean switch to tell the script whether to collect AD attribute values or not. Defaults to $true.
- “ReplMetadata”: This is a Boolean switch to tell the script whether to collect the AD replication metadata for the specified object. Defaults to $false.
- “ToVariable”: This is a Boolean switch to tell the script to return all of the data to a variable or not. Defaults to $false. If this switch is $false then the values will be piped out to the PowerShell console.
- The script saves the results to %systemroot%\temp\ADObjectData.txt.
- The distinguished name of the object does not need to be known. Only the name or (depending on objectclass of the object) the samaccountname needs to be supplied.
- The object name which is specified may be what is in the “name” attribute for an object or the “samaccountname” of the object. This allows for a wider scope of object types to be retrieved from AD and adds some resiliency to the tendency to use a name value instead of samaccountname for user class objects-something I’m guilty of doing,
- The attributes which are returned are unformatted. This means that strings and integer value attribute types will be human readable while other attribute types will appear unreadable. An example would be the lastlogontimestamp attribute which will appear as an integer value and must be translated in PowerShell into a DateTime object in order to be readable as an actual date and time.
- The data which is returned when requesting the AD replication metadata from an object is from a single writable domain controller in the domain the user object is in. If updates to an object are “in flight” and have not yet applied to the domain controller which the query is against then the data will not show them.
- The data which is returned when requesting the AD object attribute values is retrieved from a Global Catalog query. Keep this in mind if you are expecting to see data which is not published to the partial attribute set. That data won’t appear.
- The script uses the System.DirectoryServices namespace and several of it’s “children” namespaces. These methods are used for constructing the LDAP queries (which is a common method to use for constructing LDAP queries using .Net code) as well as querying the domain controllers for the AD replication metadata.
- If using the ToVariable switch the returned data is in a PSObject. If both AD attributes and replication metadata are being returned the returned PSObject will have two noteproperties. The first one is a PSObject value named “Attributes”. The second one is named “Metadata” and is a hash table. Since the Metadata infromation is a hash table you have to add some code (which you can copy from lines 105-119 of the script) to handle the values and put them in a usable format. They will be readable in the output text file already however.
- You need to be a domain users for the domain or forest. You do not need to have domain administrator permissions to run this script, however some environments may be more restrictive than the default AD environment and as a result prevent the script from working.
- The “ToVariable” switch can be very useful if you have a list of objects you need to collect data on and would like to send all of a list of objectnames through the script as a foreach.
Here’s an example of the command line use of the script. In this case I put the values into a variable…
PS C:\Testing> $TestGroup3 = .\GETADOBJECTDATA.PS1 -Objectname "testgroup3" -ADAttrs $true -ReplMetadata $true –ToVariable $true
..and here is a snippet of the returned AD replication metadata from the object and how it will appear in the output text file:
Active Directory Replication Metadata for CN=TestGroup3,OU=TestOU,DC=tspring,DC=com
***************************************
Replication Metadata: nTSecurityDescriptor
********************
version : 1
OriginatingChangeUsn : 155871
LastOriginatingChangeTime : 09/03/2014 07:19:53
LastOriginatingInvocationID : 304d2ae0-7cd4-44a4-ae2d-55cfa1c0f332
LocalChangeUsn : 393561
OriginatingServer : WIN-F55P9G8HQVQ.tspring.com
Replication Metadata: whenCreated
********************
version : 1
OriginatingChangeUsn : 155871
LastOriginatingChangeTime : 09/03/2014 07:19:53
LastOriginatingInvocationID : 304d2ae0-7cd4-44a4-ae2d-55cfa1c0f332
LocalChangeUsn : 393561
OriginatingServer : WIN-F55P9G8HQVQ.tspring.com
The script is meant to be a good alternative to using Repadmin.exe or the AD PowerShell module if those aren’t available. One of the most handy things I’ve done with it are to retrieve a list of security group members for a large list of security groups. I didn’t know the domain or forest the groups always resided in, and I definitely didn’t know the group’s DNs, and this script did a great job getting that data without my having to have elevated privileges in the environment or spend a lot of time on the matter.
I hope this helps folks out in troubleshooting and maintaining their AD environments.