简体   繁体   English

读取本地组策略/ Active Directory设置

[英]Reading Local Group Policy / Active Directory Settings

I'm writing a C# program that will enforce password complexity in accordance with the Windows Group Policy setting "Password must meet complexity requirements". 我正在编写一个C#程序,它将根据Windows组策略设置“密码必须满足复杂性要求”来强制设置密码复杂性。 Specifically, if that policy is set to Enabled either on the local machine (if it's not part of a domain) or by the Domain Security Policy (for domain members), then my software needs to enforce a complex password for its own internal security. 具体来说,如果在本地计算机(如果它不是域的一部分)上或通过域安全策略(对于域成员)将该策略设置为“已启用”,则我的软件需要为其自身的内部安全性强制执行复杂的密码。

The issue is that I can't figure out how to read that GPO setting. 问题是我不知道如何读取该GPO设置。 Google searches have indicated that I can read GPO settings with one of these two APIs: the System.DirectoryServices library in .NET Framework, and Windows Management Instrumentation (WMI), but I haven't had any success so far. Google搜索表明,我可以使用以下两个API之一读取GPO设置:.NET Framework中的System.DirectoryServices库和Windows Management Instrumentation(WMI),但是到目前为止,我还没有取得任何成功。

Any insights would be helpful. 任何见解都会有所帮助。

There doesn't appear to be a documented API for this task, managed or otherwise. 似乎没有针对此任务的文档化API,无论是托管API还是其他方法。

Managed Attempt 管理尝试

I tried the managed route using the System.Management assembly: 我尝试使用System.Management程序集管理路线:

        ConnectionOptions options = new ConnectionOptions();
        ManagementScope scope = new ManagementScope(@"\\.\root\RSOP\Computer", options);

        ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, new ObjectQuery("SELECT * FROM RSOP_SecuritySettingBoolean"));
        foreach(ManagementObject o in searcher.Get())
        {
            Console.WriteLine("Key Name: {0}", o["KeyName"]);
            Console.WriteLine("Precedence: {0}", o["Precedence"]);
            Console.WriteLine("Setting: {0}", o["Setting"]);
        }

This however will not return results. 但是,这不会返回结果。 It doesn't appear to be a permission issue as providing a username/password pair to ConnectionOptions results in an exception telling you that you can not specify a username when connecting locally. 它似乎不是权限问题,因为向ConnectionOptions提供用户名/密码对会导致异常,告诉您在本地连接时无法指定用户名。

Unmanaged Attempt 不受管的尝试

I looked at NetUserModalsGet . 我看着NetUserModalsGet While this will return some information on password settings: 虽然这将返回有关密码设置的一些信息:

typedef struct _USER_MODALS_INFO_0 {
  DWORD usrmod0_min_passwd_len;
  DWORD usrmod0_max_passwd_age;
  DWORD usrmod0_min_passwd_age;
  DWORD usrmod0_force_logoff;
  DWORD usrmod0_password_hist_len;
} USER_MODALS_INFO_0, *PUSER_MODALS_INFO_0, *LPUSER_MODALS_INFO_0;

..it will not let tell if the Password Complexity policy is enabled. ..it不会告诉您是否启用了密码复杂性策略。

Tool Output Scraping 'Success' 工具输出报废“成功”

So I resorted to parsing secedit.exe output. 因此,我诉诸解析secedit.exe输出。

    public static bool PasswordComplexityPolicy()
    {
        var tempFile = Path.GetTempFileName();

        Process p = new Process();
        p.StartInfo.FileName = Environment.ExpandEnvironmentVariables(@"%SystemRoot%\system32\secedit.exe");
        p.StartInfo.Arguments = String.Format(@"/export /cfg ""{0}"" /quiet", tempFile);
        p.StartInfo.CreateNoWindow = true;
        p.StartInfo.UseShellExecute = false;
        p.Start();
        p.WaitForExit();

        var file = IniFile.Load(tempFile);

        IniSection systemAccess = null;
        var passwordComplexityString = "";
        var passwordComplexity = 0;

        return file.Sections.TryGetValue("System Access", out systemAccess)
            && systemAccess.TryGetValue("PasswordComplexity", out passwordComplexityString)
            && Int32.TryParse(passwordComplexityString, out passwordComplexity)
            && passwordComplexity == 1;
    }

Full code here: http://gist.github.com/421802 完整代码在这里: http : //gist.github.com/421802

You can use the Resultant Set of Policy (RSOP) tools. 您可以使用策略结果集(RSOP)工具。 Eg here's a VBScript (lifted from here ) which will tell you what you need to know. 例如,这是一个VBScript(从此处提升),它将告诉您您需要了解的内容。 It should be simple enough to translate this into C#. 将其转换为C#应该足够简单。

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\rsop\computer")
Set colItems = objWMIService.ExecQuery _
    ("Select * from RSOP_SecuritySettingBoolean")
For Each objItem in colItems
    Wscript.Echo "Key Name: " & objItem.KeyName
    Wscript.Echo "Precedence: " & objItem.Precedence
    Wscript.Echo "Setting: " & objItem.Setting
    Wscript.Echo
Next

I came across your this Microsoft forum answer http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/f3f5a61f-2ab9-459e-a1ee-c187465198e0 我碰到了您这个Microsoft论坛的答案http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/f3f5a61f-2ab9-459e-a1ee-c187465198e0

Hope this helps somebody who comes across this question in the future. 希望这对将来遇到这个问题的人有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM