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

回眸只為那壹抹淺笑 提交于 2019-11-28 01:49:42

问题


I would like to a) programatically and b) remotely find out the last date/time that a user successfully logged into a Windows machine (via remote desktop or at the console). I would be willing to take any typical windows language (C, C#, VB, batch files, JScript, etc...) but any solution would be nice.


回答1:


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;

 }



回答2:


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());
                }
            }
        }



回答3:


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



回答4:


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




回答5:


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



来源:https://stackoverflow.com/questions/1474293/how-to-programatically-find-out-the-last-login-time-to-a-machine

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