The LDIFDE utility exports and imports objects from and to Active Directory using the ldif format, which is kinda’ like csv when it gets really drunk and can’t stay on one line. Luckily, ldif can’t drive. Actually, each attribute/field is on a line (which allows for arrays) and an empty line starts the next record. Which can make for a pretty messy looking file the first time you look at one. The csvde command can be used to export data into the csv format instead. In it’s simplest form the ldifde command can be used to export AD objects just using a -f option to specify the location (the working directory that we’re running the ldifde command from if using powershell to do so or remove .\ if using a standard command prompt):
ldifde -f .\ADExport.ldf
This exports all attributes of all objects, which overlap with many in a target Active Directory and so can’t be imported. Therefore, you have to limit the scope of what you’re exporting, which you can do in a few ways. The first is to only export a given OU. To limit, you’ll define a dn with a -d flag followed by the actual dn of the OU you’re exporting and then you’d add a -p for subtree. In the following example we’ll export all of the objects from the sales OU to the SalesOUExport.ldf file:
ldifde -d "OU=sales,DC=krypted,DC=local" -p subtree -f .\SalesOUExport.ldf
Restoring objects still results in an error that the server is “Unwilling To Perform” the import because “The modification was not permitted for security reasons.” Basically, this just means “hey I’m not going to import into some of the fields that I know I have to reserve for objects managed by the system, such as creation date (whencreated), last changed date (whenchanged), etc. So we can take some of these and omit them from our export. You can use ADMT or just look at an ldif or csv file to determine which attributes from the schema that you think need to be omitted, but at a minimum it should include objectguid, uSNCreated, uSNChanged, whencreated and when changed (and a lot of the Exchange attributes if you’ve extended the schema for your forest). To omit use the -o and enclose the omitted attributes in parenthesis. In the following example, we’ll export to the SalesOUExportO.ldf file, and add the -o flag to the previous command:
ldifde -d "OU=sales,DC=krypted,DC=local" -p subtree -o "objectguid,uSNCreated,uSNChanged,whencreated,whenchanged" -f .\SalesOUExportO.ldf
You can also omit using the -m flag, which includes only the essential attributes, so we’ll add that to the command as well:
ldifde -d "OU=sales,DC=krypted,DC=local" -p subtree -o "objectguid,uSNCreated,uSNChanged,whencreated,whenchanged" -m -f .\SalesOUExportO.ldf
Use the -l option to limit the attributes being exported to only those specified.
The -r option restricts the export to a given category or class. For example, if we only wanted to export users, we can restrict to objectClass-User
ldifde -d "OU=sales,DC=krypted,DC=local" -p subtree -r "(objectClass=user)" -o "objectguid,uSNCreated,uSNChanged,whencreated,whenchanged" -m -f .\SalesOUExportOM.ldf
Now I’m feeling like we have a good restricted set of data that we’re moving. Let’s go ahead and give importing a shot on a target server. To do so, we’ll just use -i to specify this is an import, followed by -k to say “don’t stop if you have a problem with just one record”, -f to define a file and -j to write a log. We’ll use the working directory for the file path and the log path, assuming this is being done by calling the .exe from within powershell:
ldifde -i -k -f .\SalesOUExportOM.ldf -j .\
Once complete, the exported objects should appear once you close and re-open Active Directory Users and Computers. You can also export one object, then programmatically create objects in an ldif file as needed by importing them into Active Directoryusing ldifde.
Well, we knew it was possible, but we didn’t know anyone would actually do it. Based on the title here, you probably already know that someone deleted a whole OU. Given that about 6-7 people could have done it and none were owning up of course you’re gonna’ get forced to figure out who it was. Well, let’s get started then.
First, restore the OU. To do this we’re gonna’ use the ldp.exe utility from the Windows Server 2003 Support Tools. THen we’re going to open it up and click on the Connection menu and connect to your DC (and authenticate as a Domain Admin or above of course). Then click on the Options menu -> Controls ->Load Predefined -> Return Deleted Objects -> Control Type -> Server -> OK. Then View -> Tree -> enter the DN for the missing container (eg if it’s the Users container of 318.com that would be cn=Users, dc=318, dc=com). Now right-click the OU -> Modify. Click isDeleted -> Delete -> Enter. If it’s not present, add lastKnownParent value and paste DN in Values. Click Operations -> Replace -> Enter -> Synchronous -> Extended -> Run. Then, click Controls -> Options -> Check Out.
Whew, but you’re not done yet. Now you have to reset passwords, profile settings, home directories and group memberships. Then re-enable them. YAY! So by now you’ve got to want to figure out who did this. So let’s do so.
First make sure the 2003 Resource Kit Tools are installed. To start grab the objectGUID. Then type:
repadmin /showmeta GUID=<YOUR GUID HERE> <FQDN DOMAIN NAME>
Now look for that isDeleted attribute we got rid of earlier. This will tell you which DC it came from and you can comb through the logs there using the time stamp from your repadmin command. Good luck and may God have mercy on their soul.