none
Understanding the Computer login process and 'lastLogon' AD property

    Question

  • I wrote a function in c# that goes to all DC's in our domain ( total 52 spread around the world ), and run a query to find if "lastLogon" property for a specified computer account, in case it does it stores the value in a collection, at the end it finds the Max value and returns the date and time the last login for this particular computer. the script works find there are no issues with it, the only problem is the dates actually pulled ( from 52 40 values are being returned in average since the rest didn't authenticated the computer ever ) but the Max value ( the most recent date ) is not accurate as it seems , sometimes 24 hours behind from current time sometimes more, the question is, the computer perform a login during the boot process after the kernel is loaded,  if the computer remains in session is it re login again after period of time ? Please help me understand it in a detailed way:) the process and any valuable information in this matter, thanks a lot P.S the domain func level is 2008R2
    Monday, February 13, 2017 2:20 PM

Answers

  • I do not see a problem with your code. I would only comment that the datetime values retrieved will always be in the time zone of the computer where the code is run. The values saved in AD are always in UTC. The FromFileTime method does the conversion. Keep this in mind when looking at a computer in another time zone. Of course this is not a factor for computers in your time zone.

    Richard Mueller - MVP Enterprise Mobility (Identity and Access)

    • Marked as answer by Wavestone Friday, February 17, 2017 11:05 AM
    Monday, February 13, 2017 10:31 PM

  • last thing, people suggest to get this information directly from event viewer will be the most accurate.

    Probably most accurate, definitely most expensive! :)

    You do not want to query all events in event viewer per DC and func(MAX) them, do you? Not to mention the killer formula: ((GetEvents -> FilterEvents ) * Number of DC's)

    I remember I once wanted to achieve the same thing of finding the exact lastlogon time with use of PowerShell per DC and I had the same problem of you: "They just do not report the correct last logon". That was the reason that I moved to lastlogontimestamp within my application and ignored the 9~14 days of replication interval. Honestly speaking, most of the third party applications do query based on lastlogontimestamp.


    Mahdi Tehrani   |     |   www.mahditehrani.ir
    Please click on Propose As Answer or to mark this post as and helpful for other people.
    This posting is provided AS-IS with no warranties, and confers no rights.

    • Marked as answer by Wavestone Friday, February 17, 2017 11:05 AM
    Tuesday, February 14, 2017 1:54 PM
    Moderator
  • I want to sum this post for others that might need an answer :

    1) the method I'm using indeed query all the DC's successfully and return true data, the data ( DateTime object converted to string ) is not the most accurate but this is the exact data that is being stored in the DC's.

    2) As many DC's available and the quality of connection to those DC's can bring a long process to get the data returned, for example 52  DC's spread around the world takes around 1 min of processing.

    3) using LastLogOnStamp is fast and oppose to LastLogon attribute, its a replicated attribute and way faster to achieve, but its caveat is the replication time accrue between 9 to 14 days ( random interval )

    4) the lastLogon is being updated while computer in session even though some people claim that the update is taking place only during boot time, this i couldn't solve with a real sound answer :) i hope i will not die wondering about it one day :D

    Good luck to you all


    • Edited by Wavestone Wednesday, February 15, 2017 4:04 PM
    • Proposed as answer by AlvwanModerator Thursday, February 16, 2017 2:52 AM
    • Marked as answer by Wavestone Friday, February 17, 2017 11:05 AM
    Wednesday, February 15, 2017 4:02 PM

All replies

  • Computers AFAIK only "log on" at boot.
     
    Monday, February 13, 2017 3:27 PM
  • The computer object lastLogon attribute should only be updated at startup. Per this blog post:

    https://blogs.technet.microsoft.com/ken_brumfield/2008/09/16/identifying-stale-user-and-computer-accounts/

    I quote ====

    Updating only when logon occurs also affects computers if they are not rebooted.  If the computers have remained up and running, the lastLogon is when they booted up.  This is highly unlikely to impact client systems, but may impact servers if they are up for greater than a specified threshold.

    ==== end of quote

    However, I have also seen lastLogon dates that seem more recent than the last known restart. I have never been able to track down the cause.


    Richard Mueller - MVP Enterprise Mobility (Identity and Access)

    Monday, February 13, 2017 3:57 PM
  • thanks for the comment Richard,

    This really bugs me, since lastLogon isnt a replicated attribute and we have many DC's with all kind of latency, it takes nearly 1 min for the query to finish, even though i get actual results, it seems so unreliable to depends on,  the reason i was asking the question is because testing i made, i ran the script to check up a computer beside me that was logged in for at least 2-3 days, and i found the the 'lastlogon' is almost as the same time i ran the script at, from there i found that this is a common behavior and on top of that i found computers that didn't updated for 2 weeks and more while i know they  had to reboot  at least once a week. i wish i could get to understand this. 

    Monday, February 13, 2017 4:12 PM
  • So as I, im trying to understand why the attribute is being updated while computer in session or maybe idle for a few hours,   or not being updated even though the computer performed a full restart

    Wavestone

    Monday, February 13, 2017 4:14 PM
  • The behavior you describe makes me think there is a problem with you script. Can you post the script here? Use the "Insert code block" button in the editor.

    Richard Mueller - MVP Enterprise Mobility (Identity and Access)

    Monday, February 13, 2017 4:54 PM
  • Sure can, its part of a WPF much bigger project, the c ode behind is c# 

    public static DateTime GetComputerLastLog(TextBox computerName, string externalErrorLog) {         
                var lastLogins = new List<DateTime>();
                DirectoryEntry directoryEntry = null;
                DomainControllerCollection domains = Domain.GetCurrentDomain().DomainControllers;
                foreach (DomainController controller in domains) {
                        try {
                            directoryEntry = new DirectoryEntry(string.Format("LDAP://{0}", controller.Name));
                        } catch (Exception err) {
                            ComputerInformationAD.externalErrorLog = err.Message;
                            ErrorsLogModel.CreateErrorLog(externalErrorLog);
                        }
    
                    if (directoryEntry != null) {
                        var searcher = new DirectorySearcher(directoryEntry);
                        searcher.PageSize = 1000;
                        searcher.Filter = "(&(objectClass=computer)(objectCategory=computer)(name=" + computerName.Text + "))";
                        searcher.PropertiesToLoad.AddRange(new[] { "distinguishedName", "lastLogon" });
                        try {
                            foreach (SearchResult searchResult in searcher.FindAll()) {
                                if (searchResult.Properties.Contains("lastLogon"))
                                    lastLogins.Add(DateTime.FromFileTime((long)searchResult.Properties["lastLogon"][0]));
                            }
                            searcher.Dispose();
                        } catch (Exception err) {
                            ComputerInformationAD.externalErrorLog = controller + " " + err.Message;
                            ErrorsLogModel.CreateErrorLog(externalErrorLog);
                        }
                    }
                }
                if (directoryEntry != null) {
                    directoryEntry.Close();
                    directoryEntry.Dispose();
                }
    
                DateTime temp = DateTime.MinValue;
                temp = lastLogins[0];
                //Find Max vlue for DateTime to find the latest records around the forest
                for (int i = 0; i < (lastLogins.Count) - 1; i++) {
                    if (temp.CompareTo(lastLogins[i + 1]) < 0)
                        temp = lastLogins[i];
                }
                return temp;
            }

    Monday, February 13, 2017 5:18 PM
  • I do not see a problem with your code. I would only comment that the datetime values retrieved will always be in the time zone of the computer where the code is run. The values saved in AD are always in UTC. The FromFileTime method does the conversion. Keep this in mind when looking at a computer in another time zone. Of course this is not a factor for computers in your time zone.

    Richard Mueller - MVP Enterprise Mobility (Identity and Access)

    • Marked as answer by Wavestone Friday, February 17, 2017 11:05 AM
    Monday, February 13, 2017 10:31 PM
  • If the DC's are int variety of time zones,  what would be the best way to convert the time date to my local machine ( the one that run the script ) time  ? if my machine is  GMT + 0 and the target DC is GMT +4 for example 
    Tuesday, February 14, 2017 7:03 AM
  • I read about is so more, i understood the UTC concept better now, some claim that it might glitch from time to time but i dont think that this is the issue. another thing and i think this will sum everything - in the following link

    https://social.technet.microsoft.com/Forums/windowsserver/en-US/70227035-6fcd-4d7f-958e-f9b2dd325cd8/finding-the-accurate-last-logon-time-of-an-ad-account?forum=winserverDS

    I read that a computer time stamp is changing when the computer is logged in ( which is obvious ) and when a computer is authenticating with user name and password in front of a DC, if its true than its all i care about at this point :)

    last thing, people suggest to get this information directly from event viewer will be the most accurate.

    Tuesday, February 14, 2017 9:06 AM

  • last thing, people suggest to get this information directly from event viewer will be the most accurate.

    Probably most accurate, definitely most expensive! :)

    You do not want to query all events in event viewer per DC and func(MAX) them, do you? Not to mention the killer formula: ((GetEvents -> FilterEvents ) * Number of DC's)

    I remember I once wanted to achieve the same thing of finding the exact lastlogon time with use of PowerShell per DC and I had the same problem of you: "They just do not report the correct last logon". That was the reason that I moved to lastlogontimestamp within my application and ignored the 9~14 days of replication interval. Honestly speaking, most of the third party applications do query based on lastlogontimestamp.


    Mahdi Tehrani   |     |   www.mahditehrani.ir
    Please click on Propose As Answer or to mark this post as and helpful for other people.
    This posting is provided AS-IS with no warranties, and confers no rights.

    • Marked as answer by Wavestone Friday, February 17, 2017 11:05 AM
    Tuesday, February 14, 2017 1:54 PM
    Moderator
  • Your code does convert all datetime values into your time zone. The FromFileTime method converts the AD value in UTC into the time zone of the computer where the code runs. A reference:

    https://msdn.microsoft.com/en-us/library/system.datetime.fromfiletime(v=vs.110).aspx


    Richard Mueller - MVP Enterprise Mobility (Identity and Access)

    Tuesday, February 14, 2017 2:07 PM
  • yes Mahdi :) i already wrote a few versions of code for this event, it took it forever to complete because of 2 reasons , 1) the amount of logs 2) the latency

    I even ran a test against a local desktop in the local LAN which is very fast in our environment and still yet it was slowwwwww.

    I guess LastlOgonStamp will do better after all considering that we know the 9-14 days caveat in trade of being a replicated property.

    I was trying to avoid WMI based queries since of its lack of performances and the tendency of being buggy at some devices, by getting the last boot time directly from the device, when query mass computers it can get slow.

    thx for the comment

    Wavestone,

    Wednesday, February 15, 2017 3:36 PM
  • yes In the final method i even pass the time zone and concetinate  with the string for the convenient of it.

    thx Richard for all the help and time you spare helping me :)

    Wavestone

    Wednesday, February 15, 2017 3:38 PM
  • I want to sum this post for others that might need an answer :

    1) the method I'm using indeed query all the DC's successfully and return true data, the data ( DateTime object converted to string ) is not the most accurate but this is the exact data that is being stored in the DC's.

    2) As many DC's available and the quality of connection to those DC's can bring a long process to get the data returned, for example 52  DC's spread around the world takes around 1 min of processing.

    3) using LastLogOnStamp is fast and oppose to LastLogon attribute, its a replicated attribute and way faster to achieve, but its caveat is the replication time accrue between 9 to 14 days ( random interval )

    4) the lastLogon is being updated while computer in session even though some people claim that the update is taking place only during boot time, this i couldn't solve with a real sound answer :) i hope i will not die wondering about it one day :D

    Good luck to you all


    • Edited by Wavestone Wednesday, February 15, 2017 4:04 PM
    • Proposed as answer by AlvwanModerator Thursday, February 16, 2017 2:52 AM
    • Marked as answer by Wavestone Friday, February 17, 2017 11:05 AM
    Wednesday, February 15, 2017 4:02 PM