Lastlogon time on DC връща различна стойност в .Net и powershell

Пиша малко приложение, което може да проверява времето за последно влизане на потребител на всеки 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 (не всички се различават от другите, но повечето от тях). Програмата .Net обаче връща едно и също време от всички DC инстанции и в допълнение връща време, което не се показва в PS скрипта!

Сега съм доста объркан. Вярвам, че PS скриптът е правилният, но тогава наистина не знам какво съм пропуснал в .Net версията.

Направих известно отстраняване на грешки в програмата, но намереният потребител съдържа само времето, което програмата показва, и дори стойността на времето на файла, различна от PS версията. Дори си помислих за проблема с преобразуването на дата-час, но тогава структурата на резултата трябва да е една и съща с различни стойности, но не е така.

Благодаря предварително за всякакъв вид помощ.


person SecThor    schedule 06.07.2015    source източник


Отговори (1)


Намерих отговора! :-)

Модифицирах кода на C#, за да върне времето на файла на предполагаемите данни за последно влизане, а също така направих подробен ps скрипт, за да изброя всяка променлива на потребителя, така че да мога да намеря съответното свойство, върнато от c#.

Ето един PS скрипт:

Get-ADUser TestUser | Get-ADObject -Properties *

Този ред връща всяко свойство, което се съхранява в AD за дадения потребител. Сред другите има две ценности, които ме интересуват:

lastLogon и lastLogonTimestamp

След това проверих файловата версия на свойството lastlogon, върнато от c#, и се оказа, че тази стойност всъщност е същата като lastLogonTimestamp и няма (или Не намерих) начин да поискам точните данни за последно влизане.

Правилното решение е да преработите кода, който да работи с LDAP заявки вместо API извиквания. Малка помощ за това можете да намерите тук

person SecThor    schedule 13.07.2015