Pregunta

¿Cómo hago para iterar sobre la configuración disponible y/o configurar en un GPO determinado (usando el nombre o GUID) en un dominio AD? Sin tener que exportar a XML/HTML usando PowerShell, etc.

Estoy usando C# (.NET 4.0).

¿Fue útil?

Solución

Otros consejos

Tuve un problema similar y no quería descargar e instalar la Biblioteca GPO de Microsoft (Microsoft.GroupPolicy.Management). Quería hacerlo todo con System.DirectoryServices. Tomó un poco de excavación, pero se puede hacer.

Primero recupere su contenedor con DirectorySearcher. Deberá haber abierto una entrada de directorio para pasar al buscador. El filtro que quieres es:

string filter = "(&" + "(objectClass=organizationalUnit)" + "(OU=" + container + "))";

Y la propiedad que le interesa se llama "GPlink", así que cree una matriz con esa propiedad:

string[] requestProperties = { "gPLink" };

Ahora recupere los resultados y extraiga el GPLINK, si está disponible.

using (var searcher = new DirectorySearcher(directory, filter, properties, SearchScope.Subtree))
{
    SearchResultCollection results = searcher.FindAll();
    DirectoryEntry entry = results[0].GetDirectoryEntry();
    string gpLink = entry.Properties["gPLink"].Value;

Si GPLINK es nulo, no hay GPO asociado con el contenedor (OU). De lo contrario, GPlink contendrá una cadena como esta:

"[LDAP://cn={31B2F340-016D-11D2-945F-00C04FB984F9},cn=policies,cn=system,DC=Test,DC=Domain;0]"

En el texto de arriba, puede ver un CN para el GPO. Todo lo que necesitamos hacer ahora es recuperar el GPO del DC.

Para eso, usamos un filtro que se ve así:

string filter = "(&" +
    "(objectClass=groupPolicyContainer)" +
    "(cn={31B2F340-016D-11D2-945F-00C04FB984F9}))";

Querrá crear una matriz de propiedades que incluya lo siguiente:

Properties = { "objectClass", "cn", "distinguishedName", "instanceType", "whenCreated",
    "whenChanged", "displayName", "uSNCreated", "uSNChanged", "showInAdvancedViewOnly",
    "name", "objectGUID", "flags", "versionNumber", "systemFlags", "objectCategory", 
    "isCriticalSystemObject", "gPCFunctionalityVersion", "gPCFileSysPath",
    "gPCMachineExtensionNames", "dSCorePropagationData", "nTSecurityDescriptor" };

Ahora use DirectorySearcher para recuperar el GPO. Recibirá un directorio de directorio en los resultados que contienen todos los campos anteriores en la colección de propiedades. Algunos son objetos COM, por lo que tendrá que manejarlos adecuadamente.

Aquí hay un ejemplo mejor y más completo que arriba.

class Program
{
    static void Main(string[] args)
    {
        DirectoryEntry rootDse = new DirectoryEntry("LDAP://rootDSE");
        DirectoryEntry root = new DirectoryEntry("GC://" + rootDse.Properties["defaultNamingContext"].Value.ToString());
        DirectorySearcher searcher = new DirectorySearcher(root);
        searcher.Filter = "(objectClass=groupPolicyContainer)";

        foreach (SearchResult gpo in searcher.FindAll())
        {
            var gpoDesc = gpo.GetDirectoryEntry().Properties["distinguishedName"].Value.ToString();
            Console.WriteLine($"GPO: {gpoDesc}");

            DirectoryEntry gpoObject = new DirectoryEntry($"LDAP://{gpoDesc}");

            try
            {
                Console.WriteLine($"DisplayName: {gpoObject.Properties["displayName"].Value.ToString()}");
            }
            catch
            {
            }

            try
            {
                Console.WriteLine($"PCFileSysPath: {gpoObject.Properties["gPCFileSysPath"].Value.ToString()}");
            }
            catch
            {
            }

            try
            {
                Console.WriteLine($"VersionNumber: {gpoObject.Properties["versionNumber"].Value.ToString()}");
            }
            catch
            {
            }

            try
            {
                Console.WriteLine($"UserExtensionNames: {gpoObject.Properties["gPCUserExtensionNames"].Value.ToString()}");
            }
            catch
            {
            }

            try
            {
                Console.WriteLine($"MachineExtensionNames: {gpoObject.Properties["gPCMachineExtensionNames"].Value.ToString()}");
            }
            catch
            {
            }


            try
            {
                Console.WriteLine($"PCFunctionality: {gpoObject.Properties["gPCFunctionalityVersion"].Value.ToString()}");
            }
            catch
            {
            }

        }

        Console.ReadKey();
    }
}

Actualizado: copia de trabajo. Ahora puede usar C# para leer y analizar un GPO dado sin tener que usar PowerShell o escribir nada en el disco.

using Microsoft.GroupPolicy;

var guid = new Guid("A7DE85DE-1234-F34D-99AD-5AFEDF7D7B4A");
var gpo = new GPDomain("Centoso.local");
var gpoData = gpo.GetGpo(guid);
var gpoXmlReport = gpoData.GenerateReport(ReportType.Xml).ToString();

using (XmlReader reader = XmlReader.Create(new StringReader(gpoXmlReport)))
{
    string field;
    while (reader.MoveToNextAttribute())
    {
        foreach (string attr in attributes)
        {
            // do something
        }
    }            
}

Esto utiliza las herramientas de la consola de gestión de políticas grupales (GPMC):https://msdn.microsoft.com/en-us/library/windows/desktop/aa814316(v=vs.85).aspx

Microsoft.https://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.groupolicy(v=vs.85).aspx

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top