|
using System;
using System.DirectoryServices;
using System.IO;
using System.Collections;
namespace ActiveDirectorySearch1 {
// This class reads a file containing an OU structure to be imported.
// The file lines are read into an ArrayList. Methods are provided to return the
// next line or the previous line from the ArrayList. The class has no
// knowledge of a file line's syntax or meaning.
public class OUFile{
private static ArrayList OULines = new ArrayList(); // complete lines (tabs & name) of OUs to import
private static int curLineNum = -1;
// Open the file that contains the OU strucure to be imported
// and get a StreamReader to it. Then read all its lines into the ArrayList OULines.
// Comment and blank lines are skipped.
public static void OpenOUFile( string fileName) {
StreamReader SR = File.OpenText( fileName);
string input;
while ((input = SR.ReadLine()) != null) {
if ((input != "") && (input[0] != '#') ) // not a blank line or comment
OULines.Add(input);
} // while
SR.Close();
if (OULines.Count == 0) {
Console.WriteLine( "Error - " + fileName + " is empty.");
System.Environment.Exit(1);
}
} //OpenOUFile()
public static string NextLine() {
if (curLineNum == OULines.Count -1)
return null;
return (string) OULines[++curLineNum];
} // NextLine()
public static string PrevLine() {
if (curLineNum == 0) {
Console.WriteLine( "ERROR - attempted to access line number -1.");
System.Environment.Exit(1);
}
return (string) OULines[--curLineNum];
} // PrevLine()
} // class OUFile
// All knowledge of AD is confined to this class.
// This class uses recursive methods to Export an AD's OU structure
// or IMport an OU structure from a file to the AD.
public class ADSearch {
public static string DomainDN; //example, DC=Doug,DC=org
private static string curLine; //Last line returned by OUFile class
//Init Class0 and return the Domain as a string
public static void InitAD() {
DirectoryEntry DomainDE = new DirectoryEntry("LDAP://rootDSE");
DomainDN = (DomainDE.Properties["defaultNamingContext"])[0].ToString();
} // InitAD()
//Given a path to the Parent Container, search for all OUs in the parent (children)
private static SearchResultCollection SearchOneLevel( string path ) {
DirectoryEntry entry = new DirectoryEntry(path );
DirectorySearcher mySearcher = new DirectorySearcher(entry);
mySearcher.Filter = ("(objectClass=organizationalUnit)");
mySearcher.SearchScope = SearchScope.OneLevel; //enum to restrict search
return mySearcher.FindAll();
} // SearchOneLevel()
// recursively go down OU structure. The SearchResultCollection level of
// the pervious level is passed as a parameter.
private static void OUExport(SearchResultCollection srcCollection, int level) {
foreach(SearchResult resEnt in srcCollection) {
for (int i=level; i>0; i--) Console.Write("\t");
// get rid of leading "OU=" in Name, just want only the name output.
Console.WriteLine(resEnt.GetDirectoryEntry().Name.ToString().Remove(0,3));
OUExport( SearchOneLevel(resEnt.GetDirectoryEntry().Path), level+1);
}
} // OuExport()
public static void KickoffOUExport() {
OUExport( SearchOneLevel( "LDAP://" + DomainDN), 0);
} // KickoffOUExport()
// ------------------- IMPORTING -------------------
//return the level of curLine by counting leading tabs
//spaces are ignored.
private static int GetLineLevel() {
int lvl = 0;
int i = 0;
while ((curLine[i] == ' ') || (curLine[i] == '\t') ) {
if (curLine[i] == '\t') lvl++;
i++;
}
return lvl;
}
//return only the OU name in curLine by deleting leading
// and trailing white space.
private static string GetLineName() {
return curLine.Trim();
}
// Creates an OU if it does not already exist
private static void OUCreate ( string p_curLvlPath, string OUName) {
// Do nothing if OU already exists.
if (DirectoryEntry.Exists("LDAP://OU=" + OUName + "," + p_curLvlPath) )
return; // outta here.
//Verify that parent container exists so you can create a child
if (!DirectoryEntry.Exists("LDAP://" + p_curLvlPath)) {
Console.WriteLine( "ERROR - parent container for new OU does not exist.");
Console.WriteLine( " parent: " + p_curLvlPath);
System.Environment.Exit(1);
} //parent does not exist
DirectoryEntry curDE = new DirectoryEntry( "LDAP://" + p_curLvlPath);
DirectoryEntries children = curDE.Children;
DirectoryEntry OUDE = children.Add( "OU="+OUName, "organizationalUnit");
OUDE.CommitChanges();
Console.WriteLine( OUName + " created.");
} // OUCreate
//p_curLvl is level of parent, p_curLvlPath is parent's path
//started at (0, domain) so there is no real parent when started.
public static void OUImport( int p_curLvl, string p_curLvlPath) {
int lvl;
while ( (curLine = OUFile.NextLine()) != null ) {
lvl = GetLineLevel(); // The level for the new OU
if (lvl == p_curLvl) {
OUCreate( p_curLvlPath, GetLineName() );
}
else if (lvl > p_curLvl) {
curLine = OUFile.PrevLine();
string newPath = "OU=" + GetLineName() + "," + p_curLvlPath;
OUImport( p_curLvl+1, newPath);
}
else {
int commaIndex = p_curLvlPath.IndexOf(",");
string newPath = p_curLvlPath.Remove(0,commaIndex+1);
curLine = OUFile.PrevLine();
OUImport( p_curLvl-1, newPath);
}
} //while NextLine()
} // OUImport()
} // ADSearch
class MainProg {
static void Main (string[] args) {
Console.WriteLine("#OUTransport Version 0.0");
ADSearch.InitAD(); //
if (args.Length == 0) {
Console.WriteLine("#Exporting from domain: " + ADSearch.DomainDN);
ADSearch.KickoffOUExport( );
}
else {
Console.WriteLine( "#Importing from file: " + args[0]);
OUFile.OpenOUFile( args[0]);
ADSearch.OUImport(0, ADSearch.DomainDN);
}
} // Main()
} // MainProg
} // namespace
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.