0

我正在编写一个小应用程序,它可以审计我们环境中每个 DC 上用户的最后登录时间。在一些帮助下,我能够创建一个代码来迭代所有 DC 并查询用户的最后登录时间。正如我在此值未在 DC 之间同步之前读到的那样,这是 MS 设计的。这是我用来检查每个 DC 上的用户的代码:

        foreach (string DCInstance in DC_Collection)
        {
            try
            {
                using (PrincipalContext context = new PrincipalContext(ContextType.Domain,DCInstance))
                {
                    using (UserPrincipal userPrincipal = new UserPrincipal(context))
                    {                            
                        userPrincipal.Name = "TestUserName";

                        using (PrincipalSearcher searcher = new PrincipalSearcher(userPrincipal))
                        {

                            using (PrincipalSearchResult<Principal> results = searcher.FindAll())
                            {
                                foreach (UserPrincipal FoundUser in results)
                                {
                                    Console.WriteLine(FoundUser.SamAccountName + "," + FoundUser.LastLogon + "," + DCInstance);

                                }
                            }
                        }
                    }
                }
            }

            catch (PrincipalServerDownException PSDE)
            {
                MessageBox.Show(PSDE.Message + ": " + DCInstance);
            }
        }

我知道许多括号是不必要的,但这样对我来说更具可读性。

这是程序的核心。但是我认识到,在每个 DC 实例上找到的用户的最后登录时间都是相同的,这不太可能。为了确定这个问题,我做了一个小 PS 脚本来做同样的事情,所以我可以比较结果。这是PS脚本:

foreach($dc in $dcs)
 { 
   $hostname = $dc.HostName
   $user = Get-ADUser $userName -Server $hostname | Get-ADObject -Properties lastLogon
}

同样,这只是使实际工作的脚本的核心。

然而结果却完全不同。PS 脚本的结果与我预期的一样,几乎在每个 DC 上都有很大不同(并非所有 DC 都与其他 DC 不同,但大多数都不同)。然而,.Net 程序从所有 DC 实例返回相同的时间,此外它返回的时间不会显示在 PS 脚本中!

现在我很困惑。我相信 PS 脚本是正确的,但是我真的不知道我在 .Net 版本中错过了什么。

我对程序做了一些调试,但找到的用户只包含程序显示的时间,甚至与 PS 版本不同的文件时间值。我什至考虑过日期时间转换问题,但是结果的结构应该与不同的值相同,但事实并非如此。

提前谢谢任何形式的帮助。

4

1 回答 1

0

我找到了答案!:-)

我修改了 C# 代码以返回假定的上次登录数据的文件时间,还做了一个详细的 ps 脚本来列出用户的每个变量,以便我可以找到 c# 返回的相关属性。

这是一个PS脚本:

Get-ADUser TestUser | Get-ADObject -Properties *

此行返回存储在 AD 中的关于给定用户的每个属性。其中有两个我关心的价值:

lastLogonlastLogonTimestamp

在此之后,我检查了 c# 返回的lastlogon属性的文件时间版本,结果发现该值实际上与lastLogonTimestamp相同,并且没有(或我没有找到)请求确切的lastlogon数据的方法。

正确的解决方案是重新设计使用 LDAP 查询而不是 API 调用进行操作的代码。可以在这里找到一点帮助

于 2015-07-13T06:50:34.050 回答