Script Repository


Last logon time of all users

February 06, 2017
1451

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.

Parameters:

  • $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
PowerShell
Import-Module Adaxes

$to = "recipient@domain.com" # 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">
    <tr>
        <th>Full name</th>
        <th>Username</th>
        <th>Last logon time</th>
    </tr>
"@ # 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 http://www.adaxes.com/help/?HowDoI.ManageService.RegisterWebInterface.html", "Warning")
}

try
{
    $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))
        }
        else
        {
            $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
        }
        else
        {
            $users.Add($domainName, $reportRecord)
        }
    }
}
finally
{
    $searcherResult.Dispose()
}

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 )
avatar
Ramon
September 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

avatar
Support
September 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