Yes, it is 2023 and you did read the title correctly. Searching LDIF Files with PowerShell. But why?
Something I learned a few decades ago in Identity Management is that when you go live with an identity solution that updates Active Directory, you will get blamed for changes you didn’t do. Essentially if something screws up with changes to Active Directory Users or Groups and you just went live with a solution that can make changes to Active Directory you will likely get blamed without any evidence to support such allegations. It is up to you to be able to quickly substantiate with evidence that such changes were not caused by you.
This post details using PowerShell to load LDIF files and then search for objects and compare them.
What is LDIF?
LDAP Data Interchange Format (LDIF) is a standard for plain text data interchange format for representing Lightweight Directory Access Protocol (LDAP) directory objects.
Simply put you extract objects (e.g., Users) from an LDAP directory service (Active Directory) and you can then update the text extract and then replay it to update Active Directory with the changes. In my case though, export Active Directory objects in LDIF Format and store the extract as a before backup that can be referenced if inference is made that your new systems have incorrectly made changes in Active Directory.
Generating an LDIF Export of Active Directory Objects
Exporting Active Directory objects in LDIF format is best achieved using LDIFDE that is available in Windows Server. The options I’m using for the export are to provide the output filename and path, the BaseDN (Organisational Unit) to export and the objects to export. There are many other options available for LDIFDE here.
Parameter | Description |
---|---|
-f <FileName> | Identifies the import or export file name. |
-d <BaseDN> | Sets the distinguished name of the search base for data export. |
-r <LDAPFilter> | Creates an LDAP search filter for data export. For example, to export all users with a surname that you specify, you can use the following filter:-r (and(objectClass=User)(sn=Surname)) |
The following example exports Active Directory User objects from the Employees OU that resides under the AU OU in the customer.com.au AD Domain.
ldifde -f C:\Files\AU_export.ldf -d "OU=Employees,OU=AU,DC=customer,DC=com,DC=au" -r "(objectClass=User)"
Importing LDIF Files into PowerShell
I’d been here before but could not locate my previous solutions for managing LDIF files with PowerShell. A few quick searches and I found fellow MVP Gil Kirkpatrick’s module (LDIFPowerShell) from 2014. Sure, it was 9 years old, but LDAP and LDIF hasn’t changed much in that time.
Whilst LDAP and LDIF haven’t changed much in 9 years PowerShell sure has.
Download the three files from Gil’s GitHub Repo for LDIFPowerShell from here. Put those three files in the same directory as your script, or somewhere else that makes sense. But you will need to reference the path to these. I put them under my PowerShell Modules directory in a folder called LDIFPowerShell.
In your PowerShell Script you need to import the Module and the DLL.
import-module C:\Users\darrenjrobinson\Documents\PowerShell\Modules\LDIFPowerShell\LDIFDistinguishedName.dll import-module C:\Users\darrenjrobinson\Documents\PowerShell\Modules\LDIFPowerShell\LDIF.psm1
Here is a GIST with that, but also a helper function named Get-LDIFUser that will allow you to search the LDIF file for a particular Active Directory User object using the EmployeeID attribute.
Finding User LDIF Objects in PowerShell
Before we can use the Get-LDIFUser function listed above we need to import the LDIF export using Gil’s LDIFPowerShell cmdlet Get-LDIFRecords. Below is an example of that. It assumes that the LDIF export is located in the same directory as your PowerShell prompt.
$AUUsers = Get-LDIFRecords -InputFile .\AU_export.ldf
Now we can search for an AD User Object using the employeeID attribute.
Get-LDIFUser -employeeID 1001001 -LDIFObject $AUUsers
Comparing LDIF Objects for changes in PowerShell
Great, we can import the LDIF file and find the user we want along with all their attributes. Using the example above what we need to be able to do is compare a user in a before and after scenario. E.g., what has changed on the user.
The following sample imports two LDIF files. One with the export before go-live and the other after go-live. It then creates a new PSObject for each user with just the attributes and uses Compare-Object to identify the differences between the before and after.
To show the extent of the capability I’ve used the above to compare two completely different user objects. Obviously, this means that almost every attribute is different. Differences in Object 1 compared to Object 2 and then Object 2 compared to Object 1.
Summary
If nothing else this documents it for the next time I need to do this or show someone else how to.