0

AD で一部のユーザー属性をクエリしたいのですが、特定の DC で C# を使用しています。数十の DC があり、それらの間にレプリケーションの問題があると思われます。未使用のアカウントのクリーンアップを行い、最終ログオン時間属性を使用して、すべての DC でこれを 1 つずつ照会したいと考えています (これは総当たり攻撃に少し似ていることはわかっていますが、ただし、あまり頻繁に行うつもりはありません) ので、最新の値が最新かどうかを確認できます。すべての DC を照会するコードがありました。

            Domain TestDomain = Domain.GetCurrentDomain();
            Console.WriteLine("Number of found DCs in the domain {0}", TestDomain.DomainControllers.Count);
            foreach (DomainController dc in TestDomain.DomainControllers)
            {
                Console.WriteLine("Name: " + dc.Name);
                ///DO STUFF
            }

また、AD からユーザーにクエリを実行できるコードを作成するためのヘルプも見つけました。

    PrincipalContext context = new PrincipalContext(ContextType.Domain, "test.domain.com");
            string userName = "testusername";
            UserPrincipal user = UserPrincipal.FindByIdentity(context, userName);
            Console.WriteLine(user.LastLogon.Value.ToString());                
            Console.ReadKey();

そしてここで私は立ち往生しました。ここで、すべての DC からユーザーの最終ログオン タイムスタンプを取得したいと考えています。過去に、ユーザーが毎日使用していることが判明したため、DC からの情報が同期されていないことが判明したため、長い間使用されていないように思われるアカウントを誤って削除しました (1 つの DC のみを確認してください)。最も合理的な行動は、この誤った同期現象の原因を確認することであることは承知していますが、私の現在の状態では、時間がかかり、おそらく何の発見もなく終了するでしょう...建設的な応答/コメントを事前にありがとう!

4

2 に答える 2

0

編集:あなたの質問を読み直した後、実際の問題が何であるかを理解しました。ユーザーの最終ログオン属性がすべてのドメイン コントローラで一致しないため、レプリケーションの問題が発生していると思われますか? これは設計によるものです。その属性はドメイン コントローラ固有であり、複製されていません。ユーザーの真の最終ログオン時刻を確認するには、常にすべてのドメイン コントローラにクエリを実行して、最新の時刻を見つける必要があります。

あなたはほとんどそこにいます、これを試してください:

public static List<UserPrincipal> GetInactiveUsers(TimeSpan inactivityTime)
{
    List<UserPrincipal> users = new List<UserPrincipal>();

    using (Domain domain = Domain.GetCurrentDomain())
    {
        foreach (DomainController domainController in domain.DomainControllers)
        {
            using (PrincipalContext context = new PrincipalContext(ContextType.Domain, domainController.Name))
            using (UserPrincipal userPrincipal = new UserPrincipal(context))
            using (PrincipalSearcher searcher = new PrincipalSearcher(userPrincipal))
            using (PrincipalSearchResult<Principal> results = searcher.FindAll())
            {
                users.AddRange(results.OfType<UserPrincipal>().Where(u => u.LastLogon.HasValue));
            }
        }
    }

    return users.Where(u1 => !users.Any(u2 => u2.UserPrincipalName == u1.UserPrincipalName && u2.LastLogon > u1.LastLogon))
        .Where(u => (DateTime.Now - u.LastLogon) >= inactivityTime).ToList();
}

ただし、ログインしたことがない人は表示されません。それが必要な場合は、おそらくそれを理解できます。

于 2015-05-19T15:15:11.477 に答える