15/11/2024

Obtenir la date et l’heure de dernière connexion d’un utilisateur Active Directory

I. Présentation

Quelle est la date et l'heure de la dernière connexion d'un utilisateur Active Directory ? Pour obtenir une réponse à cette question, nous allons devoir nous intéresser à deux attributs de l'Active Directory : "lastLogon" et "lastLogonTimestamp".

À l'aide de PowerShell, nous allons consulter la valeur de ces attributs afin de répondre à cette question et nous pourrons obtenir l'information pour un utilisateur ou un ensemble d'utilisateurs. Mais, avant cela, nous devons étudier le fonctionnement des deux attributs susmentionnés.

II. Les attributs lastLogon et lastLogonTimestamp

Le schéma Active Directory contient deux attributs nommés "lastLogon" et "lastLogonTimestamp" et que nous retrouvons sur les objets appartenant aux classes "User" et "Computer". Ici, ce sont bien les utilisateurs qui vont nous intéresser.

  • Attribut lastLogon

L'attribut "lastLogon" contient la date et l'heure de la dernière ouverture de session d'un utilisateur, c'est-à-dire sa dernière connexion au domaine Active Directory.

Il est important de savoir que la valeur de cet attribut n'est pas répliquée entre les contrôleurs de domaine. Cela signifie que la valeur sera mise à jour uniquement sur le contrôleur de domaine sollicité par l'utilisateur au moment de l'authentification. Si la valeur n'est pas répliquée, c'est pour des raisons de performances afin de ne pas surcharger le processus de réplication : cette valeur peut changer plusieurs fois par jour pour chaque utilisateur.

"Cette valeur est stockée sous la forme d’un grand entier qui représente le nombre d’intervalles de 100 nanosecondes depuis le 1er janvier 1601 (UTC).", peut-on lire dans la documentation de Microsoft. Si un compte a la valeur "0", "Jamais" ou une valeur faisant référence au "1er janvier 1601" (soit "01/01/1601 01:00:00"), c'est qu'il ne s'est jamais connecté.

  • Attribut lastLogonTimestamp

À l'instar du précédent attribut, celui nommé "lastLogonTimestamp" contient également la date et l'heure de la dernière ouverture de session. Il est répliqué entre les contrôleurs de domaine Active Directory (sans que ce soit un attribut répliqué en urgence), contrairement à "lastLogon", mais nous n'allons pas l'exploiter, car il n'est pas suffisamment précis. En effet, il n'est pas mis à jour dans toutes les circonstances, contrairement à "lastLogon" où il y a une mise à jour en temps réel.

La décision de mettre à jour l'attribut "lastLogonTimestamp" suite à une connexion est prise en effectuant un calcul : l'Active Directory prend la date actuelle et lui soustrait la valeur de l'attribut "ms-DS-Logon-Time-Sync". Si le résultat est égal ou plus grand à "lastLogonTimestamp", alors la valeur est actualisée. Par défaut, "ms-DS-Logon-Time-Sync" a une valeur de 14 jours et l'Active Directory applique en plus une randomisation faisant varier la valeur entre 9 et 14.

Pour approfondir ce point, je vous recommande la lecture de cet article :

Cet attribut est surtout utile pour détecter facilement les ordinateurs et utilisateurs inactifs, mais il n'est pas assez précis pour connaître la date et l'heure exacte de dernière connexion d'un utilisateur (ou d'un ordinateur).

Active Directory - Exemple LastLogon

III. Date et heure de dernière connexion avec PowerShell

Désormais, nous allons utiliser PowerShell pour obtenir la date et l'heure de dernière connexion d'un ou plusieurs utilisateurs Active Directory. L'attribut "lastLogon" sera utilisé pour obtenir cette information précise, mais nous allons devoir lire la valeur de cet attribut sur l'ensemble des contrôleurs de domaine afin d'identifier la plus récente. Ceci va complexifier la tâche, mais permettra d'avoir un résultat fiable.

Le script ci-dessous récupère la liste de tous les contrôleurs de domaine Active Directory et récupérer la valeur de l'attribut "lastLogon" sur chacun d'entre eux, pour l'utilisateur ciblé. Vous devez adapter la valeur de la variable "$TargetUser".

# Récupérer la liste de tous les DC du domaine AD
$DCList = Get-ADDomainController -Filter * | Sort-Object Name | Select-Object Name

# Utilisateur ciblé (SamAccountName)
$TargetUser = "admin.fb"

# Initialiser le LastLogon sur $null comme point de départ
$TargetUserLastLogon = $null
    
Foreach($DC in $DCList){

        $DCName = $DC.Name
 
        Try {
            
            # Récupérer la valeur de l'attribut lastLogon à partir d'un DC (chaque DC tour à tour)
            $LastLogonDC = Get-ADUser -Identity $TargetUser -Properties lastLogon -Server $DCName

            # Convertir la valeur au format date/heure
            $LastLogon = [Datetime]::FromFileTime($LastLogonDC.lastLogon)

            # Si la valeur obtenue est plus récente que celle contenue dans $TargetUserLastLogon
            # la variable est actualisée : ceci assure d'avoir le lastLogon le plus récent à la fin du traitement
            If ($LastLogon -gt $TargetUserLastLogon)
            {
                $TargetUserLastLogon = $LastLogon
            }
 
            # Nettoyer la variable
            Clear-Variable LastLogon
            }

        Catch {
            Write-Host $_.Exception.Message -ForegroundColor Red
        }
}

Write-Host "Date de dernière connexion de $TargetUser :"
Write-Host $TargetUserLastLogon

Quelques secondes plus tard, l'information est retournée :

Je peux affirmer avec certitude qu'il s'agit du "lastLogon" le plus récent pour cet utilisateur, car l'information a été collectée et comparée sur l'ensemble des DCs.

Ci-dessous, un script plus complet qui contient une fonction capable d'obtenir le "lastLogon" pour un utilisateur spécifique ou pour tous les utilisateurs activés dans l'Active Directory.

<#
.SYNOPSIS
	Obtenir la date et l'heure de dernière connexion d'un utilisateur ou de tous les utilisateurs activés, via lecture de l'attribut lastLogon sur tous les DC.

.EXAMPLE
    Get-ADUserLastLogon -Identity "admin.fb"
    Get-ADUserLastLogon
    
.INPUTS
.OUTPUTS
.NOTES
	NAME:	Get-ADUserLastLogon.ps1
	AUTHOR:	Florian Burnel
	EMAIL:	[email protected]
	VERSION HISTORY:
        1.0   14/05/2024

#>

function Get-ADUserLastLogon {

    [CmdletBinding()]
    
    param(
        [Parameter(Mandatory=$false)][ValidateScript({Get-ADUser $_})]$Identity=$null
    )

    # Création d'un tableau vide
    $LastLogonTab = @() 

    # Récupérer la liste de tous les DC du domaine AD
    $DCList = Get-ADDomainController -Filter * | Sort-Object Name | Select-Object Name

    # Déterminer la liste des utilisateurs (un utilisateur ou tous les utilisateurs activés)
    if($Identity -eq $null){

        $TargetUsersList = (Get-ADUser -Filter {Enabled -eq $true}).samAccountName
    }else{

        $TargetUsersList = $TargetUser
    }

    Foreach($TargetUser in $TargetUsersList){

    # Initialiser le LastLogon sur $null comme point de départ
    $TargetUserLastLogon = $null

        Foreach($DC in $DCList){

                $DCName = $DC.Name
 
                Try {
            
                    # Récupérer la valeur de l'attribut lastLogon à partir d'un DC (chaque DC tour à tour)
                    $LastLogonDC = Get-ADUser -Identity $TargetUser -Properties lastLogon -Server $DCName

                    # Convertir la valeur au format date/heure
                    $LastLogon = [Datetime]::FromFileTime($LastLogonDC.lastLogon)

                    # Si la valeur obtenue est plus récente que celle contenue dans $TargetUserLastLogon
                    # la variable est actualisée : ceci assure d'avoir le lastLogon le plus récent à la fin du traitement
                    If ($LastLogon -gt $TargetUserLastLogon)
                    {
                        $TargetUserLastLogon = $LastLogon
                    }
 
                    # Nettoyer la variable
                    Clear-Variable LastLogon
                    }

                Catch {
                    Write-Host $_.Exception.Message -ForegroundColor Red
                }
        }

        $LastLogonTab += New-Object -TypeName PSCustomObject -Property @{
            SamAccountName = $TargetUser
            LastLogon = $TargetUserLastLogon
        }

        Write-Host "lastLogon de $TargetUser : $TargetUserLastLogon"
    }

    return $LastLogonTab

}

Vous pouvez récupérer ce script sur le GitHub IT-Connect :

Une fois la fonction chargée, voici comment effectuer la requête pour un compte précis :

Get-ADUserLastLogon -Identity "admin.fb"

Sans paramètre, la fonction va rechercher l'information pour tous les comptes utilisateurs activés.

Get-ADUserLastLogon

Voici un exemple de résultat :

PowerShell - LastLogon utilisateurs actifs

IV. Conclusion

Désormais, vous êtes capable d'obtenir la date et l'heure de dernière connexion d'un utilisateur, de façon fiable, grâce à PowerShell et à l'attribut "lastLogon" ! Sans PowerShell, nous devrions nous connecter sur l'ensemble des DCs pour obtenir l'information et effectuer la comparaison nous-même, ce qui pourrait s'avérer très fastidieux...

author avatar
Florian BURNEL Co-founder of IT-Connect
Ingénieur système et réseau, cofondateur d'IT-Connect et Microsoft MVP "Cloud and Datacenter Management". Je souhaite partager mon expérience et mes découvertes au travers de mes articles. Généraliste avec une attirance particulière pour les solutions Microsoft et le scripting. Bonne lecture.
Partagez cet article Partager sur Twitter Partager sur Facebook Partager sur Linkedin Envoyer par mail

1 commentaire sur “Obtenir la date et l’heure de dernière connexion d’un utilisateur Active Directory

  • Bonjour

    Très interessant ce petit script
    est-il possible en plus de connaitre sur quel ordinateur il s’est connecté ?

    Merci d’avance

    Christophe

    Répondre

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.