【问题标题】:Reading Group Policy Settings using C#使用 C# 读取组策略设置
【发布时间】:2011-03-15 23:35:56
【问题描述】:

如何在 AD 域中的给定 GPO(使用名称或 GUID)中迭代可用和/或设置设置?无需使用 powershell 等导出为 XML/HTML。

我正在使用 C# (.NET 4.0)。

【问题讨论】:

  • 您好,您最后用什么方法来迭代 GPO 中的设置?
  • 正如我在对已接受答案的评论中提到的,我最终导出了 XML 文件并以编程方式比较了这些文件。对于 XML 比较选项,您可以参考这个 SO 线程:stackoverflow.com/questions/9713406/free-xml-compare-tool

标签: c# c#-4.0 active-directory gpo


【解决方案1】:

【讨论】:

  • 非常感谢。我会浏览这些链接,希望能找到一些实用的东西。将在今天晚些时候发布结果。
  • 好吧...有机会玩弄 COM 接口。 GPMC 库提供的 COM 接口不提供迭代设置的方法。有两个整体的 GenerateReport 和 GenerateReportToFile 函数。将继续四处寻找,看看是否还有其他问题,但现在,我想我会做 XML 报告并比较我需要的元素。感谢您的指导。
【解决方案2】:

我遇到了类似的问题,不想下载和安装 Microsoft GPO 库 (Microsoft.GroupPolicy.Management)。我想用 System.DirectoryServices 来完成这一切。花了一点时间挖掘,但可以做到。

首先使用 DirectorySearcher 检索您的容器。您需要已经打开一个目录条目才能传递给搜索器。你想要的过滤器是:

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

您感兴趣的属性名为“gPLink”,因此请创建一个包含该属性的数组:

string[] requestProperties = { "gPLink" };

现在检索结果,并提取 gPLink(如果可用)。

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;

如果 gpLink 为空,则没有与容器 (OU) 关联的 GPO。 否则,gpLink 将包含如下字符串:

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

在上面的文本中,您可以看到 GPO 的 CN。我们现在需要做的就是从 DC 中检索 GPO。

为此,我们使用如下所示的过滤器:

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

您需要创建一个包含以下内容的 Properties 数组:

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

现在使用 DirectorySearcher 检索 GPO。您将在包含 Properties 集合中所有上述字段的结果中返回一个 DirectoryEntry。有些是 COM 对象,因此您必须适当地处理它们。

【讨论】:

  • 感谢您的回答。但是,最初的问题是关于如何枚举由 ADM/ADMX 文件定义并存储在 GPO 中的实际策略和设置。你的回答没有解决这个问题。
  • 这是一个非常有趣的答案......即使它没有直接解决问题:-)
【解决方案3】:

这是一个比上面更好、更完整的例子。

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();
    }
}

【讨论】:

    【解决方案4】:

    更新:工作副本。您现在可以使用 c# 来读取和解析给定的 GPO,而无需使用 Powershell 或将任何内容写入磁盘。

    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
            }
        }            
    }
    

    这使用组策略管理控制台 (GPMC) 工具: https://msdn.microsoft.com/en-us/library/windows/desktop/aa814316(v=vs.85).aspx

    Microsoft.GroupPolicy 命名空间 https://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.grouppolicy(v=vs.85).aspx

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多