8

Sto utilizzando System.DirectoryServices.AccountManagement.dll per gestire Active Directory per ottenere tutti gli utenti nel gruppo "Domain Users".Ottieni solo gli account abilitati da Active Directory

Ciò restituisce tutti gli utenti nel dominio ma è necessario ottenere solo quelli abilitati.

Ecco alcuni esempi di codice:

List<string> users = new List<string>(); 

PrincipalContext pcContext = GetPrincipalContext(); 

GroupPrincipal grp = GroupPrincipal.FindByIdentity(pcContext, 
           IdentityType.Name, 
           "Domain Users"); 

foreach (Principal user in grp.GetMembers(true).OfType<UserPrincipal>()) 
{ 
    if (user.Enabled != false) 
    { 
     users.Add(user.Name); 
    } 
} 

altri gruppi di lavoro bene, ma quando il gruppo è "Domain Users", il valore della proprietà è Enabledfalse per tutti gli utenti. Ciò rende impossibile distinguere tra utenti abilitati e disabilitati senza eseguire ulteriori query per ciascun utente.

+0

Hai solo bisogno del nome dell'account? È necessario utilizzare lo spazio dei nomi AccountManagement? Fai qualcosa con l'oggetto UserPrincipal tranne che memorizzi il nome? Chiedo solo perché i tuoi requisiti possono essere meglio serviti usando lo spazio dei nomi DirectoryServices e DirectorySearcher con un filtro LDAP come qualcosa di simile: (& (objectclass = user) (memberOf = CN = Domain Users, dc = company, dc = com) (! (userAccountControl: 1.2.840.113556.1.4.803: = 2))) Che restituirebbe tutti gli utenti di quel gruppo abilitati. – randcd

+1

randcd: preferirei utilizzare lo spazio dei nomi AM poiché fornisce un'API molto pulita. Potrei certamente usare LDAP, ma poi tutto diventa molto più complicato (specialmente nel caso in cui gli utenti siano solo membri di Domain Users perché è il loro gruppo principale, dato che non è elencato in 'memberOf' in quel caso). – RobSiklos

+0

Il "Principal" nel ciclo ForEach dovrebbe essere in realtà "UserPrincipal" - "Enabled" non è un metodo o una proprietà accessibile su un oggetto Princpal. Almeno non in. 4.6.1. Tutto ciò può essere fatto con lo spazio dei nomi System.DirectoryServices.AccountManagement. – DtechNet

risposta

1

Gli oggetti UserPrinciple hanno una proprietà bool Enabled per questo.

http://msdn.microsoft.com/en-us/library/system.directoryservices.accountmanagement.userprincipal_properties.aspx

// Add this to GetUserDetails 
objUserDetails.EmployeeId = UserPrinical.EmployeeId; 


// Then condition the add to only add enabled 
if (objUserDetails.Enabled) { 
    objUserDetails.Add(GetUserDetails(p.Name)); 
} 
+0

Questo non risolve il problema, poiché la proprietà 'Enabled' non sembra essere popolata correttamente quando il gruppo interrogato è" Domain Users " – RobSiklos

0

C'è un'osservazione sul MSDN page of the Enabled property dicendo:

Se il capitale non è stato persistito nel negozio, questa proprietà restituisce null. Dopo che il principal è persistito, l'impostazione predefinita abilitata dipende dal negozio. AD DS e AD LDS memorizzano i nuovi principal disabilitati quando sono persistenti, mentre SAM abilita i nuovi principal quando sono persistenti. L'applicazione può solo impostare questa proprietà su un valore dopo che è stato mantenuto nell'archivio.

Forse è correlato se il valore predefinito è falso?

Inoltre, c'è un post sul forum MSDN su UserPrincipal.Enabled returns False for accounts that are in fact enabled? e sembra davvero simile al tuo problema. Secondo il post c'è forse una soluzione qui:

Penso di aver frainteso. Ignora ciò che ho postato prima. Penso che io sappia cosa sta succedendo . Il metodo GetMembers non sta caricando apparentemente i dati UserPrincipal. Non so se c'è una soluzione migliore, ma le seguenti opere (almeno sul mio dC):

foreach (UserPrincipal user in group.GetMembers(false)) 
{ 
    UserPrincipal tempUser = UserPrincipal.FindByIdentity(context, user.SamAccountName); 
    // use tempUser.Enabled 
    // other code here 
} 
+0

Gli utenti sono già persistenti, quindi la prima parte della risposta non è rilevante per la domanda. Per il resto, sì - so che posso farlo - la domanda afferma che vogliamo avere un valore corretto per la proprietà 'Enabled' * senza * dover fare altre query (specialmente non una per utente come in quel foreach ciclo continuo). Il post che stai citando dice anche che questa soluzione è troppo lenta per essere utile. – RobSiklos

1

Metodo a questo problema potrebbe essere quella di prima ricerca per gli utenti abilitati utilizzando l'PrincipalSearcher classe e quindi utilizzare il metodo Principal di IsMemberOf()

List<string> users = List<string>(); 
PrincipalContext pcContext = GetPrincipalContext(); 
GroupPrincipal grp = GroupPrincipal.FindByIdentity(pcContext, IdentityType.Name, "Domain Users"); 
UserPrincipal searchFilter = new UserPrincipal(pcContext){ Enabled = true } 
PrincipalSearcher searcher = new PrincipalSearcher(searchFilter); 
PrincipalSearchResult<Principal> results = searcher.FindAll(); 
foreach (Principal user in results) 
    if (user.IsMemberOf(grp)) 
     users.Add(user.SamAccountName);