Active Directory'den bir kullanıcı listesini nasıl alabilirim?


109

Active Directory'den bir kullanıcı listesini nasıl alabilirim? Kullanıcı adı, soyadı ve soyadı almanın bir yolu var mı? Bunun kullanıldığı benzer bir gönderi gördüm:

 PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "YOURDOMAIN");

Active Directory ile hiçbir şey yapmadım, bu yüzden tamamen kayboldum. Herhangi bir yardım çok takdir edilecektir!


3
AD'yi .NET 3.5 ile kullanmaya dair harika bir giriş için .NET Framework 3.5'te Dizin Güvenliği İlkelerini Yönetme mükemmel MSDN makalesini okuyun
marc_s

@ Marc_s'in makalesi arşivlenmiş gibi görünüyor, işte güncellenmiş bir bağlantı
jb.

@marc_s Okumayı çok isterdim efendim, ama bağlantı ölü bir bağlantı. Bu blogs.msdn.microsoft.com/msdnmagazine/2008/01/16/… denedim ama bu makaledeki bağlantılar bile microsoft dergisi için genetik bir sayfaya yönlendiriyor
Malcolm Salvador

1
@ Malky.Kid Makaleye giden yolu buldum. Bu soruya ilk yorumun bağlantısını kullanın ve Ocak 2008 sayısını indirin . Okumadan önce Explorer özellikleri sayfasındaki chm dosyasının engelini kaldırmayı unutmayın.
OneWorld

Yanıtlar:


229

Active Directory'de yeniyseniz, öncelikle Active Directory'nin verileri nasıl depoladığını anlamanızı öneririm.

Active Directory aslında bir LDAP sunucusudur. LDAP sunucusunda depolanan nesneler hiyerarşik olarak saklanır. Dosyalarınızı dosya sisteminizde depolamanıza çok benzer. Bu yüzden Directory server ve Active Directory adını aldı.

Active Directory üzerindeki kapsayıcılar ve nesneler, bir distinguished name. Ayırt edici isim böyledir CN=SomeName,CN=SomeDirectory,DC=yourdomain,DC=com. Geleneksel bir ilişkisel veritabanı gibi, bir LDAP sunucusunda sorgu çalıştırabilirsiniz. Buna LDAP sorgusu denir.

.NET'te bir LDAP sorgusu çalıştırmanın birkaç yolu vardır. Sen kullanabilirsiniz DirectorySearcher gelen System.DirectoryServicesveya SearchRequest dan System.DirectoryServices.Protocol.

Özellikle kullanıcı asıl nesneyi bulmak için soruyorsunuz beri soru için, ben en kolay yoludur kullanmak olduğunu düşünüyorum PrincipalSearcher dan System.DirectoryServices.AccountManagement. Google'dan pek çok farklı örneği kolayca bulabilirsiniz. İşte tam olarak istediğiniz şeyi yapan bir örnek.

using (var context = new PrincipalContext(ContextType.Domain, "yourdomain.com"))
{
    using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
    {
        foreach (var result in searcher.FindAll())
        {
            DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;
            Console.WriteLine("First Name: " + de.Properties["givenName"].Value);
            Console.WriteLine("Last Name : " + de.Properties["sn"].Value);
            Console.WriteLine("SAM account name   : " + de.Properties["samAccountName"].Value);
            Console.WriteLine("User principal name: " + de.Properties["userPrincipalName"].Value);
            Console.WriteLine();
        }
    }
}
Console.ReadLine();

AD kullanıcı nesnesinde bir dizi öznitelik olduğunu unutmayın. Özellikle, givenNamesize verecektir First Nameve snsize verecektir Last Name. Kullanıcı adı hakkında. Sanırım kullanıcı oturum açma adını kastettiniz. AD kullanıcı nesnesinde iki oturum açma adı olduğunu unutmayın. Bunlardan biri samAccountName, Windows 2000 öncesi kullanıcı oturum açma adı olarak da bilinir. userPrincipalNamegenellikle Windows 2000'den sonra kullanılır.


2
Sunucu Etki Alanı

Bir AD grubundaki kullanıcıları listelemek için aynı kodu nasıl kullanıyorsunuz?
nJoshi

Aramayı yalnızca bir e-posta adresi atanmış olan dizinde bulunanlarla daraltmanın bu yöntemi kullanmanın bir yolu var mı?
ARidder101

Boşver, anladım. if (((UserPrincipal)result).EmailAddress != null)Sonucu listeme eklemeden önce eklemem gerekiyordu .
ARidder101

2
Ya mevcut bilgisayar etki alanına ait değilse?
Marcus

23

Eğer aktif hesabı filtrelemek istiyorsanız bunu Harvey'in koduna ekleyin:

 UserPrincipal userPrin = new UserPrincipal(context);
 userPrin.Enabled = true;

ilk kullanımdan sonra. Sonra Ekle

  searcher.QueryFilter = userPrin;

hepsini bulmadan önce. Ve bu size aktif olanları getirmeli.


searcher.QueryFilter = userPrin;Başlatma sırasında kullanıcı ilkesini zaten ana araştırıcıya ilettiğimiz için ihtiyacınız olduğunu sanmıyorum , aksi takdirde yalnızca aktif kullanıcıları filtrelemeyle ilgili ipucu için teşekkürler!
Andrey

1
Evet, Andrey haklı Yani temelde bu, ifadeyi kullanarak ikinci mülkün eklenmesiyle değiştirilebilir:using (var searcher = new PrincipalSearcher(new UserPrincipal(context){ Enabled = true }))
Marko Jovanov

Ama Enabledönce bir değerin olup olmadığını test etmeniz gerektiğini düşündüm :if (userPrincipal.Enabled.HasValue)
JohnB 18-18

4

Kesinlikle kredi burada @Harvey Kwok'a gidiyor, ancak bu örneği eklemek istedim çünkü benim durumumda gerçek bir UserPrincipals Listesi almak istedim. Bu sorguyu önceden filtrelemek muhtemelen daha etkilidir, ancak benim küçük ortamımda, her şeyi almak ve daha sonra listemden gerektiğinde filtrelemek daha kolay.

İhtiyacınız olan şeye bağlı olarak, DirectoryEntry'e çevirmeniz gerekmeyebilir, ancak bazı özellikler UserPrincipal'da mevcut değildir.

using (var searcher = new PrincipalSearcher(new UserPrincipal(new PrincipalContext(ContextType.Domain, Environment.UserDomainName))))
{
    List<UserPrincipal> users = searcher.FindAll().Select(u => (UserPrincipal)u).ToList();
    foreach(var u in users)
        {
            DirectoryEntry d = (DirectoryEntry)u.GetUnderlyingObject();
            Console.WriteLine(d.Properties["GivenName"]?.Value?.ToString() + d.Properties["sn"]?.Value?.ToString());
        }
}

'E' nedir lütfen?
Fandango68

1
Teşekkürler, bunu hiç fark etmedim. Ben değiştirdim, "u" olması gerekiyordu. Özellik eksikse null değerleri işlemek için? S de ekledim.
Jordan

1

System.DirectoryServices.dll dosyasını ekleyin ve ardından aşağıdaki kodu kullanın:

DirectoryEntry directoryEntry = new DirectoryEntry("WinNT://" + Environment.MachineName);
string userNames="Users: ";

foreach (DirectoryEntry child in directoryEntry.Children)
{
    if (child.SchemaClassName == "User")
    {
        userNames += child.Name + Environment.NewLine   ;         
    }

}
MessageBox.Show(userNames);

1
@ Fandango68: LOL, evet öyle !!! System.Windows.Forms.MessageBox.Show (ex.Message + ex.StackTrace);
Jhollman
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.