I ran across a situation like this recently. Over the course of several meetings we developed the “perfect” OU structure for our new AD. The old structure was not configured properly (no, OUs are not just folders and they aren’t the same as security groups). Once we got the new structure set up on a VM, I had a dilemma. I decided there must be an easier way. Enter PowerShell.
I used the PowerShell AD cmdlets from Quest (have I said how awesome these tools are recently?) to export all of my OUs from the test network into a CSV file. Since I like clean, I only took what I needed which was the DN and the Name. Here is the code:
get-qadobject -type 'organizationalUnit' select 'dn','name' export-csv 'c:\NewOUs.csv' |
From there, I had a CSV that listed every OU my new domain would need. You would think I could just import the file into PowerShell and loop through it, but noooo. That would be too easy. You see, we need to know what the distinguished name is for the parent container. Some of you may be saying that I forgot to include that in my original query. There is a property called ParentContainer that you can get for an OU. It sounds good until you try to use it. That is when everything breaks. It seems that the ParentContainer property stores the data in path format (domain name\ou\ou\etc.) not Distinguished Name format. Not to worry, I had a plan. See if you can figure it out:
import-csv 'c:\ NewOUs.csv' foreach-object {new-qadobject -parentcontainer $_.dn.substring($_.dn.indexof(",")+1) -type 'organizationalUnit' -NamingProperty 'ou' -name $_.name} |
What I did was I took the DN of the OU (which includes the OU itself in the name), and stripped off the first OU (which would be…the OU itself). I found where the first comma was then did a substring of the DN starting from the first character after the comma through the end of the string.
Every OU now populates into the fresh new domain controller. If you run this in a test environment (please don’t do it in live until you do – if you mess something up, don’t mention my name), you may see some errors as the script runs (if it is a fresh AD you are importing the structure to, you should see one error only). These errors can be ignored. What is happening is the system is detecting duplicate OUs and it errors out instead of overwriting an OU. That is a good thing. In a fresh system, the duplicate OU it finds is the “Domain Controllers” OU that ships by default.
Now that these commands have been set up properly, you will notice the added benefits they provide. What if you wanted to play around with changing your OU structure? No problem. Just export your current structure and import it into a test environment. Combine this with a user and group export through PowerShell and you could move over your entire AD easily without bringing over the baggage that sometimes comes with a backup and restore.