Obtenir la date et l’heure de dernière connexion d’un utilisateur Active Directory
Sommaire
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).
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 :
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...
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