C # Quoting through array to create Active Directory OUs
I am trying to create nested OUs in Active Directory and I am close to getting this to work. I have below problem, I need help. I check if the OU exists and if not, I need to create it, the strOUArray contains OU = Test OU = Test2 and OU = Test3. I need the code to create OU = Test first and then use it as parent on // PROBLEM LINE below to allow the next OU OU = Test2 to be created inside OU = Test. Currently, in the code below, all OUs will be created at the root as I don't know how to use the first created OU in // PROBLEM LINE. I've tried using:
parent = new DirectoryEntry("LDAP://" + strOUArray[x-1] + "," + dcSubString); //note x-1
This fails because the parent does not exist to create the first OU. Any help is really appreciated, I have a limited time limit and I just need to move away from this, so thanks for any help.
String strOUs = container.Substring(0, container.IndexOf(@",DC="));
int dcIndex = container.IndexOf("DC=");
string dcSubString = container.Substring(dcIndex); //dcSubString = DC=Internal,DC=Net
string[] strOUArray = strOUs.Split(new Char[] { ',' });
for (int x = 0; x < strOUArray.Length; x++)
{
if (DirectoryEntry.Exists("LDAP://" + strOUArray[x] + "," + dcSubString))
{
}
else
{
DirectoryEntry objOU;
DirectoryEntry parent = new DirectoryEntry("LDAP://" + dcSubString); //PROBLEM LINE
objOU = parent.Children.Add(strOUArray[x], "OrganizationalUnit");
objOU.CommitChanges();
}
}
It seems like yours is //PROBLEM LINE
coming out strOUArray[x]
of string concatenation. Was it a typo when published?
Also this snippet:
DirectoryEntry parent = new DirectoryEntry();
parent = new DirectoryEntry("...");
You create DirectoryEntry
and then immediately drop the link to it on the next line.
source to share
Well, I guess I would try to do something like this:
- bind to the first level first (which LDAP: //
- create the first division
- then recursively
- binding to the newly created container
- add next level down
- repeat until you're done
Something like this (untested - I don't have a server here to test it):
String strOUs = container.Substring(0, container.IndexOf(@",DC="));
int dcIndex = container.IndexOf("DC=");
string dcSubString = container.Substring(dcIndex); //dcSubString = DC=Internal,DC=Net
string[] strOUArray = strOUs.Split(new Char[] { ',' });
// create a bind path which we'll build up
string ldapPath = dcSubString;
// bind to the top-level container
DirectoryEntry workEntry = new DirectoryEntry("LDAP://" + ldapPath);
// loop through all sub-OU to create
foreach(string currentOU in strOUArray)
{
// add the next OU below the current entry
objOU = workEntry.Children.Add(currentOU, "OrganizationalUnit");
objOU.CommitChanges();
// bind to the newly created OU
ldapPath = currentOU + "," + ldapPath;
workEntry = new DirectoryEntry("LDAP://" + ldapPath);
}
Here's one catch I see: if you create a new unit, you won't be able to immediately link it to it - sometimes it takes a while to replicate in a directory.
Does it help?
Mark
source to share
Having run something like this in the past, I created a function that will return a directory object, either newly created or existing (sorry in VBScript):
Function GetOU(objParentOU, strOUName)
On error resume next
Set GetOU = Nothing
objParentOU.Filter = Array("organizationalUnit")
Dim OU : Set OU = Nothing
For Each OU in objParentOU
if lcase(OU.Name) = lcase("ou=" & strOUName) then
wscript.echo "Connected to existing OU: " & OU.Name
set GetOU = GetObject(OU.adsPath)
exit function
end if
Next
Set OU = Nothing
' If script made it to here then the OU must not already exist
Set GetOU = objParentOU.Create("organizationalUnit", "ou=" & strOUName)
GetOU.SetInfo
if err then
wscript.echo err.description
err.clear
else
wscript.echo "Created new OU: " & strOUName
end if
end function
Using this I can build my chain without considering the existing unit or not. First set the base path and then add on top of it:
Set objDomain = GetObject(LDAP_CONNECTION_STRING)
Set parentOU = GetOU(objDomain, "parentOU")
Set childOU = GetOU(parentOU, "childOU")
Set subchildOU = GetOU(childOU, "subchildOU")
As the code runs through the set commands, OUs are created either new or linked if they already exist.
source to share