How to programatically find out the last login time to a machine?

不羁岁月 提交于 2019-11-29 08:06:15

Try this:

  public static DateTime? GetLastLogin(string domainName,string userName)
  {
        PrincipalContext c = new PrincipalContext(ContextType.Domain,domainName);
        UserPrincipal uc = UserPrincipal.FindByIdentity(c, userName);
        return uc.LastLogon;
   }

You will need to add references to using using System.DirectoryServices and System.DirectoryServices.AccountManagement

EDIT: You might be able to get the last login Datetime to a specific machine by doing something like this:

 public static DateTime? GetLastLoginToMachine(string machineName, string userName)
 {
        PrincipalContext c = new PrincipalContext(ContextType.Machine, machineName);
        UserPrincipal uc = UserPrincipal.FindByIdentity(c, userName);
        return uc.LastLogon;

 }

You can use DirectoryServices to do this in C#:

using System.DirectoryServices;

        DirectoryEntry dirs = new DirectoryEntry("WinNT://" + Environment.MachineName);
        foreach (DirectoryEntry de in dirs.Children)
        {
            if (de.SchemaClassName == "User")
            {
                Console.WriteLine(de.Name);
                if (de.Properties["lastlogin"].Value != null)
                {
                    Console.WriteLine(de.Properties["lastlogin"].Value.ToString());
                }
                if (de.Properties["lastlogoff"].Value != null)
                {
                    Console.WriteLine(de.Properties["lastlogoff"].Value.ToString());
                }
            }
        }

You could also use CMD:

C:\Windows\System32>query user /server:<yourHostName>

OR (shorter)

C:\Windows\System32>quser /server:<yourHostName>

Output will be something like this:

USERNAME    SESSIONNAME    ID    STATE    LOGONTIME
userXYZ     console         1    Active   19.01.2017 08:59

After much research, I managed to put together a nice PowerShell script which takes in a computer name and lists out the accounts and the ACTUAL last logon on the specific computer. ... TURNS OUT MICROSOFT NEVER PROGRAMMED THIS FUNCTION CORRECTLY, IT TRIES TO GET LOGON INFORMATION FROM ACTIVE DIRECTORY AND STORE IT LOCALLY, SO YOU HAVE USERS LOG INTO OTHER MACHINES AND IT'LL UPDATE THE LOGIN DATES ON YOUR MACHINE, BUT THEY NEVER LOGGED INTO YOUR MACHINE.... COMPLETE FAILURE!

$REMOTEMACHINE = "LoCaLhOsT"

$NetLogs = Get-WmiObject Win32_NetworkLoginProfile -ComputerName $REMOTEMACHINE
foreach ($NetLog in $NetLogs) 
{ 
  if($NetLog.LastLogon)
  {
    $LastLogon = [Management.ManagementDateTimeConverter]::ToDateTime($NetLog.LastLogon)
    if($LastLogon -ne [DateTime]::MinValue)
    {
      Write-Host $NetLog.Name ' - ' $LastLogon
    }
  }
}

Note: From what I can gather, the Win32_NetworkLoginProfile is using the "Win32API|Network Management Structures|USER_INFO_3" structure. So the C# equivalent would be to pInvoke [NetUserEnum] with the level specifying the structures returned in the buffer if you wanted to avoid using WMI.

Fun Fact: The DateTime is returned as an Int32 through USER_INFO_3 structure, so when it's the year 2038, the date will no longer be correct once integer overflow occurs.... #UnixMillenniumBug

I ended up using pInvoke for "RegQueryInfoKey" in C# to retrieve LastWriteTime on the registry key of each profile located under "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"

https://stackoverflow.com/a/45176943/7354452

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!