If you want to retrieve the last logon time of an Active Directory user, the question arises: which attribute should be used—LastLogon or LastLogonTimestamp?
Index
Difference between LastLogon and LastLogonTimestamp
First, it is important to understand the difference between these attributes. Both attributes contain the timestamp of the user’s last logon, but is that all?

LastLogon indicates the time when a user logged onto a specific domain controller.
In contrast, LastLogonTimestamp indicates when the last login occurred in the domain. LastLogonTimestamp is replicated across all domain controllers in the AD forest.
On the other hand, LastLogon is only updated on the specific domain controller where the user logged in with their account. There is no replication to other domain controllers. This means that the LastLogon attribute for the same user account will be different on each domain controller.
Or in short: We can summarize by saying that LastLogonTimestamp is the replicated version of LastLogon (considering the replication period). If a user has never logged onto a domain controller, the attribute value is zero.
It is also important that the replication of LastLogonTimestamp does not occur immediately, but by default only after 14 days (minus a random value of 0 to 5 days). This limitation is intended to keep the network bandwidth used by AD replication as low as possible.
The time that individual domain controllers wait before the LastLogonTimestamp value of a user object is replicated to other domain controllers is defined in the attribute msDS-LogonTimeSyncInterval. This can be found in the properties of the LDAP object of the domain itself, and the value can also be changed. If the value is not set, the default is 9 to 14 days.

The values of LastLogon and LastLogonTimestamp are stored in AD as numeric (Large Integer) values with a length of 8 bytes (64-bit).
Retrieving attribute values with PowerShell
To retrieve the LastLogon and LastLogonTimestamp values for an AD user account:
Retrieving LastLogonTimestamp
Use the Get-ADUser
cmdlet (with Import-Module ActiveDirectory
) to retrieve the identity (distinguishedName, objectGuid, objectSid, or samAccountName) and return LastLogonTimestamp:
1 2 |
$samAccountName = "maximilian.muster" $user = Get-ADUser $samAccountName -Properties lastLogonTimestamp |
Converting values to date format
Convert the integer value into a readable date format using DateTime.FromFileTime(Int64)
, which converts Windows file time to local time:
1 |
$lastLogonTimestamp = [datetime]::fromFileTime($user.lastLogonTimestamp) |
Querying LastLogon across multiple domain controllers
Since LastLogon is not replicated, it is necessary to query all domain controllers and select the latest timestamp:
First, we search for all the names of the existing domain controllers in the domain using the cmdlet “Get-ADDomainController”:
1 |
$dcs = Get-ADDomainController -Filter * | Select-Object name |
After initializing the variables for the samAccountName of the user
1 |
$samAccountName = "maximilian.muster" |
and the time for LastLogon, which provides us with the lowest possible value for comparison with the other date values,
1 |
$lastlogon=New-Object System.DateTime |

we request the LastLogon attribute from each domain controller and convert it into a DateTime:
1 2 3 4 |
foreach($dc in $dcs) { try { $user = Get-ADUser $samAccountName -Server $dc.name -Properties lastLogon $lastlogonToCheck = [datetime]::fromFileTime($user.lastlogon)</code> } catch { continue } } |
LastLogon: Compare date values of different DCs
To obtain the most recent LastLogon value from all domain controllers, we need to compare the date values with each other. If the date stored in the $lastLogonToCheck variable is older than the current date from $lastLogon, this is set as the new LastLogon date until we have finally obtained the highest and most up-to-date date:
1 2 3 4 |
foreach($dc in $dcs) { try { $user = Get-ADUser $samAccountName -Server $dc.name -Properties lastLogon $lastlogonToCheck = [datetime]::fromFileTime($user.lastlogon) if($lastlogon -lt $lastlogonToCheck) {</code> $lastlogon = $lastlogonToCheck $lastLogonValue = $user.lastlogon } } catch { continue } } |
Format LastLogon and LastLogonTimeStamp
Finally, the values of LastLogon and LastLogonTimestamp can be formatted. If the value still corresponds to our initial value, this means that the user has never logged in. Otherwise, the date can be changed to any format:
1 2 3 4 5 6 7 8 9 10 11 12 |
if($lastlogon -ne (New-Object System.DateTime) -And $lastlogon -ne [datetime]::fromFileTime(0)) { $lastlogon = $lastlogon.ToString("dd.MM.yyyy HH:mm:ss") } else { $lastlogon = "-" } if($lastLogonTimestamp -ne (New-Object System.DateTime) -And $lastLogonTimestamp -ne [datetime]::fromFileTime(0)) { $lastLogonTimestamp = $lastLogonTimestamp.ToString("dd.MM.yyyy HH:mm:ss") } else { $lastLogonTimestamp = "-" } |
Here is the complete script and the console output:
1 2 3 4 5 6 7 |
$dcs = Get-ADDomainController -Filter * | Select-Object name $samAccountName = "maximilian.muster" $lastlogon=New-Object System.DateTime foreach($dc in $dcs) { try { $user = Get-ADUser $samAccountName -Server $dc.name -Properties lastLogon $lastlogonToCheck = [datetime]::fromFileTime($user.lastlogon) if($lastlogon -lt $lastlogonToCheck) {</code> $lastlogon = $lastlogonToCheck $lastLogonValue = $user.lastlogon } } catch { continue } } $user = Get-ADUser $samAccountName -Properties lastLogonTimestamp $lastLogonTimestamp = [datetime]::fromFileTime($user.lastLogonTimestamp) $lastLogonTimestampValue = $user.lastLogonTimestamp if($lastlogon -ne (New-Object System.DateTime) -And $lastlogon -ne [datetime]::fromFileTime(0)) { $lastlogon = $lastlogon.ToString("dd.MM.yyyy HH:mm:ss") } else { $lastlogon = "-" } if($lastLogonTimestamp -ne (New-Object System.DateTime) -And $lastLogonTimestamp -ne [datetime]::fromFileTime(0)) { $lastLogonTimestamp = $lastLogonTimestamp.ToString("dd.MM.yyyy HH:mm:ss") } else { $lastLogonTimestamp = "-" } Write-Host("`nLastLogon: ") -ForegroundColor Yellow Write-Host("Wert: " + $lastlogonValue) Write-Host("Datum: " + $lastlogon) Write-Host("`nLastLogonTimestamp: ") -ForegroundColor Yellow Write-Host("Wert: " + $lastlogonTimestampValue) Write-Host("Datum: " + $lastLogonTimestamp) |

Now that we can read the individual values from the AD, the following example shows a practical use case for this topic.
Example query: Finding inactive users for 90 Days
lastLogonTimestamp
is useful for identifying inactive accounts that haven’t logged in for an extended period. The following PowerShell script finds all users who haven’t logged in for 90 days:
1 2 |
$now = Get-Date $users = Get-ADUser -Filter * -Properties lastLogonTimestamp | Where {($now - [datetime]::FromFileTime($_.lastLogonTimestamp)).days -gt 90 } |
Alternatively, use the Search-ADAccount
cmdlet:
1 2 3 |
$now = Get-Date $users = Search-ADAccount -AccountInactive -DateTime (($now).adddays(-90)) -UsersOnly |
This retrieves one or more user, computer, or service accounts that meet the specified criteria. AccountInactive indicates accounts that haven’t logged in for a given period.
Fazit
Retrieving a user’s last logon time in Active Directory is straightforward once you understand which attribute to use. The difference between LastLogon and LastLogonTimestamp is outlined in the first section.
If you want to use these attributes for user management, this can be easily done with the IDM-Portal, where scripts can be integrated to read and convert LastLogon and LastLogonTimestamp into a readable format. This way, the last logon date is conveniently displayed in a graphical interface.
Further Reading:
Leave a Reply
Thank you for your suggestions, questions, and feedback. You can find our privacy policy here: https://activedirectoryfaq.com/privacy-policy/