Laden...

C# User aus dem ActiveDirectory auslesen

Erstellt von enokad vor 13 Jahren Letzter Beitrag vor 13 Jahren 33.680 Views
E
enokad Themenstarter:in
14 Beiträge seit 2011
vor 13 Jahren
C# User aus dem ActiveDirectory auslesen

Hallo zusammen,

erstmal schonmal eine Entschuldigung, für das vielleicht falsche Forum. Ich weiß nicht, wo ich das Thema genau ansiedeln soll. 😦
(Da ich mir nicht sicher bin, wo das Active Directory zugehörig ist)

Zu meiner Frage:
Ich befinde mich derzeit dabei, ein Telefonbuch auf Basis des AD zu entwickeln. Dazu sollen alle Benutzer aus dem AD ausgelesen werden, mitsamt Telefon-Nummer etc.

Ich habe mich auf ein paar Seiten umgeschaut und mit folgendem Code bekomme ich bereits einige User in einer CMD ausgegeben: (Den Anfang mit der Klasse etc. habe ich mal ausgelassen)

string dom = "meinedomaene";

			System.DirectoryServices.DirectoryEntry entry = new System.DirectoryServices.DirectoryEntry("LDAP://" + dom);
			System.DirectoryServices.DirectorySearcher mySearcher = new System.DirectoryServices.DirectorySearcher(entry);
			//mySearcher.Filter = ("(objectClass=user)");
            mySearcher.Filter = ("(sAMAccountType=805306368)");
			Console.WriteLine("Listing of users in the Active Directory");  
			Console.WriteLine("========================================");    
  

			foreach(System.DirectoryServices.SearchResult resEnt in mySearcher.FindAll())
			{
				try
				{
					System.DirectoryServices.DirectoryEntry de=resEnt.GetDirectoryEntry();
					Console.WriteLine("Display Name  : " + de.Properties["DisplayName"].Value.ToString());
					Console.WriteLine("Email         : " + de.Properties["Mail"].Value.ToString());	
					Console.WriteLine("Title         : " + de.Properties["Title"].Value.ToString());			
					Console.WriteLine("User Name     : " + de.Properties["sAMAccountName"].Value.ToString());
					Console.WriteLine("First Name    : " + de.Properties["GivenName"].Value.ToString());					
					Console.WriteLine("Last Name     : " + de.Properties["sn"].Value.ToString());	
					Console.WriteLine("Initials      : " + de.Properties["Initials"].Value.ToString());	
					Console.WriteLine("Company       : " + de.Properties["Company"].Value.ToString());
					Console.WriteLine("Department    : " + de.Properties["Department"].Value.ToString());
					Console.WriteLine("Telephone No. : " + de.Properties["TelephoneNumber"].Value.ToString());	
				}
				catch(Exception e)
				{
				}
				Console.WriteLine("===========    End of user   =============");                                   
				
			}
			Console.WriteLine("===========    End of Listing   ============="); 

Soweit so gut. Die Problematik besteht jedoch darin, dass ich nicht alle User ausgelesen kriege, weil die Domäne so aufgebaut ist:

+Gesellschaften
++Deutschland
+++Berlin
++++Gesellschaft1
+++++Users
++++Gesellschaft2
+++++Users

Das Ganze gibt es dann natürlich auch für andere Städte, andere Länder.
Irgendwie muss ich jetzt an die jeweiligen User kommen, weiß jedoch nicht wie.

Könnt Ihr mir da einen Tipp geben?

Vielen Vielen Dank!

Lieben Gruß
eno

16.827 Beiträge seit 2008
vor 13 Jahren

Hi,

aufgrund Deines Aufbaus lohnt es sich hier alle OUs der Gesellschaften/Standorte einzeln zu durchlaufen und die Treffer eines einzelnen Standortes in ein Dictionary zu packen. So kannst Du dem User auch sehr einfach die Suche innerhalb eines Standorts ermöglichen.
Am Besten Du machst das zB alle 15 Minuten, um Resourcen zu sparen und die Performance zu erhöhen - so viel ändert sich ja bei euch nicht nehm ich an.

Es gibt ein wirklich guten Einstieg ins AD via C# auf CodeProject Almost Everything In Active Directory (Enumerate Objects in an OU)
Bedenke auch, dass Werte wie die EMail mehrere Einträge enthalten können.

Grüße

T
108 Beiträge seit 2005
vor 13 Jahren

Hi,

setz mal den Filter des DirectorySearcher auf


dirS.Filter = "(&(|(objectCategory=person)(objectCategory=contact)))";

Gruß
Tokka

Was einmal war, wird nie wieder sein...

E
enokad Themenstarter:in
14 Beiträge seit 2011
vor 13 Jahren

Guten Morgen zusammen und schonmal vielen Dank für die Antworten! 😃

Den Einstieg auf CodeProject hatte ich bereits gefunden, der ist echt gut auch wenn ich manchmal nicht verstehe was da genau gemacht wird. 😉

Das mit dem Dictionary ist eine gute Idee, werde ich auch so realisieren.

@Tokka:
Danke das hat mich schonmal weiter gebracht, jetzt spuckt mir das Programm auf jedenfall schonmal mehr Informationen und Leute aus. Danke. 😃


Noch eine Frage, wie genau greife ich auf einen bestimmten Pfad zu?
D.h. wenn ich nur die User aus einer OU haben möchte heißt z.B.

Nur Berlin, Gesellschaft1, Users <--

Habt ihr da eine Möglichkeit für mich?
Danke nochmal!

T
108 Beiträge seit 2005
vor 13 Jahren

.....
Noch eine Frage, wie genau greife ich auf einen bestimmten Pfad zu?
D.h. wenn ich nur die User aus einer OU haben möchte heißt z.B.

Nur Berlin, Gesellschaft1, Users <--

Habt ihr da eine Möglichkeit für mich?
Danke nochmal!

Dazu musst du einfach nur den LDAP Pfad anpassen.


DirectoryEntry dirE = new DirectoryEntry("LDAP://domaincontroller.domain.zz/ou=Users,ou=Gesellschaft1,ou=Berlin,dc=domain,dc=zz");

Lade dir mal einen LDAP Browser z.B. von softerra herunter. Mit dem kannst Du dann entsprechende LDAP Abfragen gegen das AD abdrücken.
Das Hilft durchaus bei der Fehlersuche, und auch am Anfang, wenn man LDAP queries noch nicht so gut hinbekommt.

Sehr hilfreich ist auch noch SelfADSI.

Gruß
tokka

Was einmal war, wird nie wieder sein...

E
enokad Themenstarter:in
14 Beiträge seit 2011
vor 13 Jahren

Hi Tokka und vielen Dank für die Antwort!

Der LDAP Browser hat mir schon gut geholfen, ich krieg jetzt die User nur aus dem Verzeichnis "Gesellschaft1" "Users". Das ist super 😃

Auch das es mir anzeigt, wie die jeweiligen Attribute der einzelnen User heißen ist 1a. Bin begeistert! Großen Dank an dich!

(Und für die super schnelle Antwort 😉 )

E
enokad Themenstarter:in
14 Beiträge seit 2011
vor 13 Jahren

So, ich brauche wieder eure Hilfe.
Ich habe mich gewundert, dass immer einige User fehlen (Ich find z.B. meinen Chef nicht. g)

Jetzt habe ich einfach mal eine Variable hochzählen lassen, um zu überprüfen wieviele Datensätze das Programm wirklich findet.
Die Ergebnisse waren irgendwie "Lustig":

**1. Start: **803
**2. Start: **830
3. Start: 854
**4. Start: **847

Das soll natürlich nicht so sein, vor allem weil dann einfach Leute fehlen.
Ich habe mich dabei erstmal auf eine User-OU gerichtet. (Die von Gesellschaft1) Zum testen reicht mir das vollkommen aus.
Wie folgt sieht der Code jetzt aus:


System.DirectoryServices.DirectoryEntry entry = new System.DirectoryServices.DirectoryEntry("LDAP://" + "domain/OU=Users,OU=Gesellschaft1,OU=BERlin,OU=Germany,OU=Companies,DC=xxxx,DC=xxxx,DC=xxxx,DC=com");
System.DirectoryServices.DirectorySearcher mySearcher = new System.DirectoryServices.DirectorySearcher(entry);
            mySearcher.Filter = ("(&(|(objectCategory=person)(objectCategory=contact)))"); 
			Console.WriteLine("Listing of users in the Active Directory");  
			Console.WriteLine("========================================");
foreach(System.DirectoryServices.SearchResult resEnt in mySearcher.FindAll())
			{

                try
                {
                    
                    System.DirectoryServices.DirectoryEntry de = resEnt.GetDirectoryEntry();
                   

(Dort oben ist nichts auskommentiert, dass macht hier nur die Quellcode-Färbung)
Die Domaine habe ich hier mal durch xxxx und durch das vorherige Beispiel ersetzt.

Warum spuckt der mir verschiedene Ergebnisse aus?
Irgendwie scheint der Code auch jedesmal bei einer anderen Person anzufangen...
Selbst wenn es die 850 sind fehlen immer noch Personen. (Sollten knapp 1000 sein!)

Irgend eine Idee?
Schonmal vielen Dank! 😃

Gruß
eno

T
108 Beiträge seit 2005
vor 13 Jahren

Hi,

hiermit lese ich unser gesamtes Directory aus...


using System;
using System.Collections.Generic;
using System.DirectoryServices;
using System.IO;


namespace ReadOut_AD_Accounts
{
    class Program
    {
        static void Main(string[] args)
        {
            DirectoryEntry dirE = new DirectoryEntry("LDAP://dchostname.vmlab.zz/dc=vmlab,dc=zz");
            DirectorySearcher dirS = new DirectorySearcher(dirE);

            StreamWriter outFile = new StreamWriter("C:\\out.csv", false, System.Text.Encoding.Default);

            dirS.PageSize = 100;
            //dirS.Filter = "(&(mail=*)(|(objectCategory=person)(objectCategory=contact)))";
            dirS.Filter = "(&(|(objectCategory=person)(objectCategory=contact)))";

            HashSet<string> properties = new HashSet<string>();

            properties.Add("sAMAccountname");
            properties.Add("displayName");
            properties.Add("sn");
            properties.Add("givenName");
            properties.Add("title");
            properties.Add("description");
            properties.Add("physicalDeliveryOfficeName");
            properties.Add("telephoneNumber");
            properties.Add("streetAddress");
            properties.Add("l");
            properties.Add("st");
            properties.Add("postalCode");
            properties.Add("homePhone");
            properties.Add("mobile");
            properties.Add("facsimileTelephoneNumber");
            properties.Add("info");
            properties.Add("department");
            properties.Add("company");
            properties.Add("manager");
            properties.Add("memberOf");

            foreach (string property in properties)
            {
                Console.Write(property + ";");
                outFile.Write(property + ";");
            }
            Console.WriteLine();
            outFile.WriteLine();

            foreach (SearchResult result in dirS.FindAll())
            {
                foreach (string property in properties)
                {
                    Console.Write(getValue(result, property));
                    outFile.Write(getValue(result, property));
                }
                Console.WriteLine();
                outFile.WriteLine();
            }
            outFile.Close();
            Console.ReadKey();
        }
        
        static string getValue(SearchResult result, string propName)
        {
            if (result.Properties[propName].Count > 0)
                return result.Properties[propName][0].ToString().Replace(Environment.NewLine, "\\") + ";";
            return ";";
        }
    }
}

Was einmal war, wird nie wieder sein...

E
enokad Themenstarter:in
14 Beiträge seit 2011
vor 13 Jahren

Dank dir Tokka.
Dein Code hat mir sehr geholfen. 😃

Ich musste lediglich noch die Option dirS.PageSize = 100; setzen und schon bin ich von den unterschiedlichen Werten auf konstante 1864 gekommen.

😃

T
108 Beiträge seit 2005
vor 13 Jahren

Hi,

sehr schön, ja die blöde PageSize... damit habe ich auch gekämpft.

Was einmal war, wird nie wieder sein...