2009-09-24 6 views
3

Je voudrais a) programmer et b) déterminer à distance la dernière date/heure qu'un utilisateur a réussi à se connecter à une machine Windows (via le bureau à distance ou sur la console). Je serais prêt à prendre n'importe quel langage Windows typique (C, C#, VB, fichiers batch, JScript, etc ...) mais toute solution serait bien.Comment programmer la dernière heure de connexion à une machine?

Répondre

4

Essayez ceci:

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

Vous devrez ajouter des références à l'utilisation de l'aide System.DirectoryServices et System.DirectoryServices.AccountManagement

EDIT: Vous pouvez obtenir la dernière date de connexion à une machine spécifique en procédant comme suit:

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

} 
+0

Est-ce que cela donne la dernière connexion au domaine, ou à l'ordinateur sur lequel il est exécuté? – esac

+0

Bonne question.MSDN dit ceci: "Obtient le DateTime nullable qui spécifie la date et l'heure de la dernière connexion pour ce compte." Je suppose que cela dépend si ContextType est défini sur Domain ou Machine, mais je ne peux pas le vérifier car je cours sur une machine autonome, mais je pense que si vous utilisez un domaine C'est probablement la dernière connexion réussie pour ce compte sur le domaine –

+0

Darn, j'aime vos deux réponses, mais j'ai vraiment besoin de la dernière heure de connexion d'un utilisateur spécifique à l'ordinateur spécifié – esac

4

Vous pouvez utiliser DirectoryServices pour faire en 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()); 
       } 
      } 
     } 
+0

de Grande réponse, toute chance que vous sauriez pour le modifier afin d'inclure des utilisateurs de domaine tels que MYDOMAIN ou au moins un utilisateur de domaine spécifique comme MYDOMAIN \ MYUSER? – esac

0

Vous pouvez également utiliser CMD:

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

OU (plus courte)

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

La sortie sera quelque chose comme ceci:

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

Après beaucoup de recherches, je réussi à mettre en place un joli script PowerShell wh Je prends un nom d'ordinateur et liste les comptes et la dernière connexion ACTUAL sur l'ordinateur spécifique. ... MICROSOFT N'A JAMAIS PROGRAMMÉ CORRECTEMENT CETTE FONCTION, IL TENTE D'OBTENIR DES INFORMATIONS D'IDENTIFICATION DE L'ANNUAIRE ACTIF ET DE LE CONSERVER LOCALEMENT, AFIN QUE VOUS AYEZ CONNECTÉ AUX AUTRES MACHINES ET QU'IL METTE À JOUR LES DATES DE CONNEXION DE VOTRE MACHINE, MAIS JAMAIS CONNECTÉ DANS VOTRE MACHINE .... ÉCHEC COMPLÈTE!

$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: D'après ce que je peux comprendre, le Win32_NetworkLoginProfile utilise le "Win32API | USER_INFO_3 | Structures de gestion du réseau" structure. Donc, l'équivalent C# serait de pInvoquer [NetUserEnum] avec le niveau spécifiant les structures retournées dans le tampon si vous voulez éviter d'utiliser WMI.

Fait amusant: Le DateTime est retourné comme un Int32 à travers la structure USER_INFO_3, alors quand il est l'année 2038, la date ne sera plus correcte après une débordement d'entier se produit .... #UnixMillenniumBug

0

je me suis retrouvé à l'aide Pinvoke pour "RegQueryInfoKey" en C# pour récupérer LastWriteTime sur la clé de registre de chaque profil situé sous "HKLM \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ ProfileList"

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

Questions connexes