Script Repository

Last logon time of all users

February 23, 2021

The script emails a report on the last logon time of all users in all domains managed by Adaxes.

To schedule a report, create a scheduled task configured for the Domain-DNS object type that runs the necessary script and assign it over any of your AD domains. To add the script to a scheduled task, use the Run a program or PowerShell script action.


  • $to - Specifies a comma separated list of recipients of the report.
  • $subject - Specifies the email message subject.
  • $reportHeader - Specifies the email message header.
  • $table - Specifies a header for the table that will be used in the report.
  • $reportFooter - Specifies the email message footer.
Edit Remove
Import-Module Adaxes

$to = "" # TODO: modify me
$subject = "Last Logon Time of All Users" # TODO: modify me
$reportHeader = "<h2><b>Last Logon Time of All Users</b></h2>" # TODO: modify me
$table = @"
<table border="1">
        <th>Full name</th>
        <th>Last logon time</th>
"@ # TODO: modify me
$reportFooter = "<hr /><p><i>Please do not reply to this e-mail, it has been sent to you for notification purposes only.</i></p>" # TODO: modify me

# Find all users in all domains managed by Adaxes
$searcher = $Context.BindToObject("Adaxes://rootDSE")
$searcher.SearchFilter = "(sAMAccountType=805306368)"
$searcher.PageSize = 500
$searcher.SearchScope = "ADS_SCOPE_SUBTREE"
$searcher.ReferralChasing = "ADS_CHASE_REFERRALS_NEVER"
$searcher.SetPropertiesToLoad(@("cn", "sAMAccountName", "lastLogonTimestamp", "distinguishedName", "objectGuid"))
$searcher.VirtualRoot = $True

# Get the default Web Interface address
$webInterfaceAddress = "%adm-WebInterfaceUrl%"
if ([System.String]::IsNullOrEmpty($webInterfaceAddress))
    $Context.LogMessage("Default web interface address not set for Adaxes service. For details, see", "Warning")

    $searcherResult = $searcher.ExecuteSearch()
    $users = @{}
    foreach ($userId in $searcherResult.FetchAll())
        # Get user information
        $fullName = $userId.Properties["cn"].Value
        $username = $userId.Properties["sAMAccountName"].Value
        $lastLogonTimestamp = $userId.Properties["lastLogonTimestamp"].Value
        $guid = [Guid]$userId.Properties["objectGuid"].Value
        if ($lastLogonTimestamp -ne $NULL)
            $lastLogonTime = [DateTime]::FromFileTime([Int64]::Parse($lastLogonTimestamp))
            $lastLogonTime = "never"
        $reportRecord = "<tr><td><a href='$webInterfaceAddress`ViewObject.aspx?guid=$guid'>$fullName</a></td><td>$username</td><td>$lastLogonTime</td></tr>"

        $domainName = $Context.GetObjectDomain($userId.Properties["distinguishedName"].Value)
        if ($users.ContainsKey($domainName))
            $users[$domainName] += $reportRecord
            $users.Add($domainName, $reportRecord)

foreach ($domainName in $users.Keys)
    $reportHeader += "<h3><b>Domain: $domainName</b></h3>"
    $reportHeader += $table
    $reportHeader += $users[$domainName]
    $reportHeader += "</table>"

# Build the report
$htmlReport = $reportHeader + $reportFooter

# Send mail
$Context.SendMail($to, $subject, $NULL, $htmlReport)

Comments ( 1 )
Sep 04, 2018
I am wondering about multiple DCs I don't see in the script where it may query for the most recent timestamp, is this accounted for?

Thant you
Sep 05, 2018
Unlike the Last Logon, the Last Logon Timestamp property is replicated among domain controllers and the script just takes the value from the properties of each user account.
Leave a comment