Enumerating Active Directory using PowerShell and .NET Classes
Let’s begin writing our script
by obtaining the required hostname for the PDC.
In the Microsoft .NET classes related to AD, we find the
System.DirectoryServices.ActiveDirectory namespace
While there are a few classes to choose from here, we’ll focus on the Domain Class
It specifically contains a reference to the PdcRoleOwner in the properties,
which is exactly what we need.
By checking the methods, we find a method called GetCurrentDomain(),
which will return the domain object for the current user, in this case stephanie.
To invoke the Domain Class and the GetCurrentDomain method,
let’s run this command:
The output reveals the PdcRoleOwner property,
which in this case is DC1.corp.com.
While we can certainly add this hostname directly into our script
as part of the LDAP path,
we want to automate the process so we can also use this script in future engagements
Let’s do this one step at a time.
First, we’ll create a variable that will store the domain object,
then we will print the variable
so we can verify that it still works within our script.
In order to run the script, we must bypass the execution policy,
which was designed to keep us from accidentally running PowerShell scripts.
We’ll do this with powershell -ep bypass:
Now let’s run our script and verify that it prints the domain object:
Our domainObj variable now holds the information about the domain object.
Although this print statement isn’t required,
it’s a nice way to verify that our command and the variable worked as intended.
Since the hostname in the PdcRoleOwner property is required for our LDAP path,
we can extract the name directly from the domain object.
In case we need more information from the domain object later in our script,
we will keep the $domainObj for the time being
and create a new variable called $PDC,
which will extract the value from the PdcRoleOwner property
held in our $domainObj variable:
Now let’s run the script again and inspect the output:
In this case we have dynamically extracted the PDC from the PdcRoleOwner property
by using the Domain Class.
Good!
While we can also get the DN for the domain via the domain object,
it does not follow the naming standard required by LDAP.
In our example, we know that the base domain is corp.com
and the DN would in fact be DC=corp,DC=com.
In this instance, we could grab corp.com from the Name property
in the domain object
and tell PowerShell to break it up and add the required DC= parameter.
However, there is an easier way of doing it,
which will also make sure we are obtaining the correct DN.
We can use ADSI directly in PowerShell to retrieve the DN.
We’ll use two single quotes to indicate
that the search starts at the top of the AD hierarchy.
This returns the DN in the proper format for the LDAP path.
Now we can add a new variable in our script
that will store the DN for the domain.
To make sure the script still works,
we’ll add a print statement and print the contents of our new variable:
Let’s run the script.
At this point, we are dynamically obtaining the Hostname
and the DN with our script.
Now we must assemble the pieces to build the full LDAP path.
To do this, we’ll add a new LDAP variable to our script that will contain the PDC
and DN variables, prefixed with “LDAP://”.
The final script will generate the LDAP path.
Note that in order to clean it up, we have removed the comments.
Since we only needed the PdcRoleOwner property’s name value
from the domain object,
we add that directly in our $PDC variable on the first line,
limiting the amount of code required:
Let’s run the script.
Great!
We have successfully used .NET classes and ADSI
to dynamically obtain the full LDAP path required for our enumeration.
Our script is also dynamic, so we can easily reuse it real-world engagements.