6

Windowsグループポリシー設定「パスワードは複雑さの要件を満たす必要があります」に従って、パスワードの複雑さを強制するC#プログラムを作成しています。具体的には、そのポリシーがローカル マシン (ドメインの一部ではない場合) またはドメイン セキュリティ ポリシー (ドメイン メンバーの場合) で有効に設定されている場合、ソフトウェアは独自の内部セキュリティのために複雑なパスワードを適用する必要があります。

問題は、その GPO 設定を読み取る方法がわからないことです。Google 検索によると、.NET Framework の System.DirectoryServices ライブラリと Windows Management Instrumentation (WMI) の 2 つの API のいずれかを使用して GPO 設定を読み取ることができますが、これまでのところ成功していません。

どんな洞察も役に立ちます。

4

3 に答える 3

7

管理されているかどうかにかかわらず、このタスク用の文書化された API はないようです。

管理された試み

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"]);
        }

ただし、これは結果を返しません。ユーザー名とパスワードのペアを提供すると、ConnectionOptionsローカルに接続するときにユーザー名を指定できないという例外が発生するため、アクセス許可の問題ではないようです。

管理されていない試み

NetUserModalsGetを見ました。これはパスワード設定に関するいくつかの情報を返しますが:

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;

..Password Complexityポリシーが有効になっているかどうかはわかりません。

ツール出力スクレイピング「成功」

そこで、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;
    }

完全なコードはこちら: http://gist.github.com/421802

于 2010-06-02T01:45:37.390 に答える
0

この Microsoft フォーラムの回答に出会いましたhttp://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/f3f5a61f-2ab9-459e-a1ee-c187465198e0

これが、将来この質問に出くわした人に役立つことを願っています。

于 2010-10-27T18:30:06.130 に答える
0

ポリシーの結果セット (RSOP) ツールを使用できます。たとえば、これは、知っておくべきことを教えてくれるVBScript (ここから持ち上げたもの) です。これを 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
于 2009-11-02T18:10:58.233 に答える