Listar todas las computadoras en el directorio activo
-
05-07-2019 - |
Pregunta
¿Me pregunto cómo obtener una lista de todas las computadoras / máquinas / pc del directorio activo?
(Tratando de hacer de esta página un cebo de motores de búsqueda, responderé yo mismo. Si alguien tiene una respuesta mejor, lo acepta)
Solución
Si tiene un dominio muy grande, o si su dominio tiene límites configurados sobre la cantidad de elementos que se pueden devolver por búsqueda, es posible que tenga que usar la paginación.
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;
}
Otros consejos
Lo que EKS sugiere es correcto , pero se está desempeñando un poco lento .
El motivo de esto es la llamada a GetDirectoryEntry ()
en cada resultado. Esto crea un objeto DirectoryEntry
, que solo es necesario si necesita modificar el objeto de Active Directory (AD). Está bien si su consulta devolvería un solo objeto, pero al enumerar todos los objetos en AD, esto degradará en gran medida el rendimiento.
Si solo necesita consultar AD, es mejor usar la colección Properties
del objeto resultante. Esto mejorará el rendimiento del código varias veces.
Esto se explica en documentación para la clase SearchResult
:
Lasinstancias de la clase
SearchResult
son muy similares a las instancias de ClaseDirectoryEntry
. La diferencia crucial es que la La claseDirectoryEntry
recupera su información del Active La jerarquía de Directory Domain Services cada vez que se crea un nuevo objeto. accedido, mientras que los datos deSearchResult
ya están disponibles enSearchResultCollection
, donde se devuelve de una consulta que se realiza con la claseDirectorySearcher
.
Aquí hay un ejemplo sobre cómo usar la colección Properties
:
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;
}
Documentación para < código> SearchResult.Properties
Tenga en cuenta que las propiedades pueden tener varios valores, por eso utilizamos Propiedades [" nombre "]. Count
para verificar el número de valores.
Para mejorar aún más las cosas, use la colección PropertiesToLoad
para que el buscador sepa qué propiedades va a usar por adelantado. Esto permite que el buscador solo lea los datos que realmente se van a utilizar.
Tenga en cuenta que los objetos
DirectoryEntry
yDirectorySearcher
deben Estar debidamente dispuesto para liberar todos los recursos utilizados. Su mejor hecho con unusando la cláusula
.
Una consulta LDAP como: (objectCategory = computer)
debería hacer el truco.