Elenca tutti i computer nella directory attiva
-
05-07-2019 - |
Domanda
Mi chiedo come ottenere un elenco di tutti i computer / macchine / pc dalla directory attiva?
(Cercando di rendere questa pagina un'esca per motori di ricerca, risponderò da solo. Se qualcuno ha una risposta migliore, lo accetto)
Soluzione
Se disponi di un dominio molto grande o il tuo dominio ha dei limiti configurati su quanti articoli possono essere restituiti per ricerca, potresti dover usare il paging.
using System.DirectoryServices; //add to references
public static List<string> GetComputers()
{
List<string> ComputerNames = new List<string>();
DirectoryEntry entry = new DirectoryEntry("LDAP://YourActiveDirectoryDomain.no");
DirectorySearcher mySearcher = new DirectorySearcher(entry);
mySearcher.Filter = ("(objectClass=computer)");
mySearcher.SizeLimit = int.MaxValue;
mySearcher.PageSize = int.MaxValue;
foreach(SearchResult resEnt in mySearcher.FindAll())
{
//"CN=SGSVG007DC"
string ComputerName = resEnt.GetDirectoryEntry().Name;
if (ComputerName.StartsWith("CN="))
ComputerName = ComputerName.Remove(0,"CN=".Length);
ComputerNames.Add(ComputerName);
}
mySearcher.Dispose();
entry.Dispose();
return ComputerNames;
}
Altri suggerimenti
Ciò che EKS ha suggerito è corretto , ma sta eseguendo un po ' lento .
Il motivo è la chiamata a GetDirectoryEntry ()
su ogni risultato. Ciò crea un oggetto DirectoryEntry
, necessario solo se è necessario modificare l'oggetto active directory (AD). Va bene se la tua query restituisce un singolo oggetto, ma quando elenchi tutti gli oggetti in AD, questo peggiora notevolmente le prestazioni.
Se hai solo bisogno di interrogare AD, è meglio usare semplicemente la collezione Proprietà
dell'oggetto risultato. Ciò migliorerà più volte le prestazioni del codice.
Questo è spiegato nella documentazione per la classe SearchResult
:
Le istanze della classe
SearchResult
sono molto simili alle istanze di ClasseDirectoryEntry
. La differenza cruciale è che il La classeDirectoryEntry
recupera le sue informazioni dall'Active Gerarchia dei servizi di dominio directory ogni volta che si trova un nuovo oggetto accessibile, mentre i dati perSearchResult
sono già disponibili in ilSearchResultCollection
, dove viene restituito da una query che viene eseguito con la classeDirectorySearcher
.
Ecco un esempio su come utilizzare la raccolta Proprietà
:
public static List<string> GetComputers()
{
List<string> computerNames = new List<string>();
using (DirectoryEntry entry = new DirectoryEntry("LDAP://YourActiveDirectoryDomain.no")) {
using (DirectorySearcher mySearcher = new DirectorySearcher(entry)) {
mySearcher.Filter = ("(objectClass=computer)");
// No size limit, reads all objects
mySearcher.SizeLimit = 0;
// Read data in pages of 250 objects. Make sure this value is below the limit configured in your AD domain (if there is a limit)
mySearcher.PageSize = 250;
// Let searcher know which properties are going to be used, and only load those
mySearcher.PropertiesToLoad.Add("name");
foreach(SearchResult resEnt in mySearcher.FindAll())
{
// Note: Properties can contain multiple values.
if (resEnt.Properties["name"].Count > 0)
{
string computerName = (string)resEnt.Properties["name"][0];
computerNames.Add(computerName);
}
}
}
}
return computerNames;
}
Documentazione per < code> SearchResult.Properties
Nota che le proprietà possono avere più valori, ecco perché usiamo Proprietà [" name "]. Count
per verificare il numero di valori.
Per migliorare ulteriormente le cose, usa la raccolta PropertiesToLoad
per far sapere al ricercatore quali proprietà utilizzerai in anticipo. Ciò consente al ricercatore di leggere solo i dati che verranno effettivamente utilizzati.
Nota che gli oggetti
DirectoryEntry
eDirectorySearcher
dovrebbero essere smaltito correttamente per liberare tutte le risorse utilizzate. Il suo meglio fatto con una clausolausing
.
Una query LDAP come: (objectCategory = computer)
dovrebbe fare il trucco.