Querying Oracle Internet Directory (LDAP) with PowerShell

If you are an IT Professional it is highly likely you are very familiar with Microsoft Active Directory and in turn PowerShell and LDAP. At some point though you may need to integrate with another LDAP directory such as Oracle Internet Directory and you find it isn’t as straight forward as Active Directory and the rich tooling it comes with. I’ve had to create interfaces with numerous LDAP directories over the years but its been quite a long time since I had to integrate with Oracle Internet Directory. That changed recently (as also seen in this post) and I had to get up to speed again with it, and work through the gotchas.

This post details a few steps to discovering and integrating with Oracle Internet Directory using PowerShell and the .NET System.DirectoryServices.Protocols.LDAPConnection Class. We start with connecting using LDP, validating our connectivity and credentials before translating that to PowerShell. You will need:

  • LDAP Servername (or IP Address)
    • check to see you have connectivity to it by being able to resolve the DNS name
  • LDAP Server Port
    • 389 and 636 are default ports for Standard and SSL connections. Chances are OID is on a different Port though
  • Username
    • e.g cn=ldapUser
  • Password
    • password for the ldapUser Account
  • Bind DN
    • the namespace of the LDAP Directory. e.g. dc=customer,dc=com,dc=au

Testing Connectivity to Oracle Internet Directory using Microsoft LDP

Using Microsoft LDP (that comes with the Remote Server Administration Tools (RSAT) for Windows operating systems) is the best approach to start with connecting to a foreign LDAP Directory such as Oracle Internet Directory.

Using the Connection => Connect function and providing the LDAP Server and Port provides us with the RootDSE Information. That, as shown below immediately tells us two important pieces of information. The version of Oracle Internet Directory (11.1.1.5.0) and where ChangeLog is (more on that later).

LDP Connect to OID.PNG
LDP Connect to OID

With a connection to the Oracle Internet Directory now established with can Bind (connect with credentials). From the Connection menu select Bind.

Simple BIND to OID.PNG
Simple BIND to OID

With credentials correct we can then go to the View menu and select Tree

Tree View of OID.PNG
Tree View of OID

Now we can see the OU Structure of Oracle Internet Directory.

Tree View of OID.PNG
Tree View of OID

Connecting to Oracle Internet Directory with PowerShell

Now that we have verified that the information we have for the LDAP Server, Directory and connection information is all correct we can try connecting using PowerShell.

Sample PowerShell LDAP Connection Script

Below is a sample PowerShell script to connect to Oracle Internet Directory. Change;

  • Line 3 for your LDAP Username
  • Line 4 for your LDAP Account password
  • Line 5 for the LDAP Servername
  • Line 6 for the LDAP Port
  • Line 9 for the base OU to start searching for users from

Line 18 is configured to only search one level under the base OU. If you have a complex OU structure you may need to change this to Subtree.

The script will then connect to Oracle Internet Directory and find the account we connected with displaying the values of its attributes.

Below shows running the script and returning the details of the account we connected with.

LDAP PowerShell Connection to Oracle Internet Directory.PNG
LDAP PowerShell Connection to Oracle Internet Directory

Immediately you can see the first problem connecting to OID. The attribute values are returned as a Byte Array. This isn’t ideal.

LDAP Helper Functions

From the PowerShell Gallery and this LDAP Module we can leverage the Get-LdapObject and Expand-Collection functions that will convert the LDAP responses for us. Put these two functions at the top of your script (or as a separate .ps1 script) and load in the script at the beginning of PowerShell LDAP Script.

The LDAP Request and Response change a little to use these functions but still leverage the same LDAP Connection. The timeout is specified against our connection and we call Get-LdapObject using that connection and our previous Filter and SearchBase. Scope is still OneLevel but can be changed to SubTree if required.

# Connect and Search
$ldapConnection.Timeout = new-timespan -Seconds 60
$ldapResponse = Get-LdapObject -LdapConnection $ldapConnection -LdapFilter $ldapSearchFilter -SearchBase $ldapSearchBase -Scope OneLevel
$ldapResponse

PowerShell Get-Ldap Object Script

Here is the full script with the two helper Functions.

The screenshot below shows the output in text rather than Byte Array. Excellent.

LDAP PowerShell Result in Text from Oracle Internet Directory.PNG
LDAP PowerShell Result in Text from Oracle Internet Directory

Oracle Internet Directory Change Log

Change Log is a function of many LDAP directories. It is especially useful when we are synchronising an LDAP Directory to another system as it means we don’t have to return all objects in it each time, but we can get the incremental changes (hence Change Log).

To query the Change Log in Oracle Internet Directory there are a couple of gotchas. You will need;

  • to query OID to see the latest Changenumber
  • only use OneLevel as the Scope for queries. Anything else and OID won’t return the info
  • The Base DN is what is shown when we initially connected using LDP (e.g cn=changelog)

Again starting with LDP we can query and get the Changenumbers. Using LDP Search;

  • use cn=changelog for the Base DN
  • objectclass = * for the Filter
  • One Level for the Scope
  • * for Attributes

And the last of the results will have the most recent changenumber.

Change Number from Oracle Internet Directory.PNG
Change Number from Oracle Internet Directory

Change Log with PowerShell

Now that we know we can get the ChangeLog with LDP, lets do it with PowerShell.

The following script re-uses our previous connection and all you should need to do is change the changeNumber in line 2 inline with your environment.

The screenshot below shows retrieving Change Log entries that are equal or newer that the Changenumber we used in our Filter. The changeFilter scopes down the changes to users in the searchBase so that we see the changes for users rather than other operational changes.

Change Log Results from Oracle Internet Directory
Change Log Results from Oracle Internet Directory

The individual users that have changed can be identified using the following one-liner.

$uniqueUsers = $changeResponse.Entries | ForEach-Object { $_.attributes["targetdn"][0] } | Get-Unique
$uniqueUsers

The Last Changenumber present in Change Log can be found with;

$lastChangeNumber= [int]$ChangeResponse.Entries[($ChangeResponse.Entries.Count-1)].Attributes["changeNumber"][0]

Summary

I recently had to reacquaint myself with OID. I’ve written it up so that next time isn’t as painful.