# UserLastLogonAndCount.ps1
# For a specified user this PowerShell script retrieves the values of
# logonCount and lastLogon on every domain controller in the domain. The
# values on each DC are displayed, but the script also outputs the latest
# lastLogon value and the total logonCount for the user over all DCs.
#
# Copyright (c) 2018 Richard L. Mueller
# Version 1.0 - December 20, 2018
#
# ----------------------------------------------------------------------
# You have a royalty-free right to use, modify, reproduce, and
# distribute this script file in any way you find useful, provided that
# you agree that the copyright owner above has no warranty, obligations,
# or liability for such use.

# Retrieve information for the current domain.
$D = [system.directoryservices.activedirectory.Domain]::GetCurrentDomain()
$Domain = [ADSI]"LDAP://$D"

# Setup the DirectorySearcher object.
$Searcher = New-Object System.DirectoryServices.DirectorySearcher
$Searcher.PageSize = 200
$Searcher.SearchScope = "subtree"

# Specify the user by sAMAccountName.
$UserNTName = Read-Host "Enter the sAMAccountName of a user"
# Filter on the user.
$Searcher.Filter = "(sAMAccountName=$UserNTName)"

# Specify attribute values to retrieve.
$Searcher.PropertiesToLoad.Add("logonCount") > $Null
$Searcher.PropertiesToLoad.Add("lastLogon") > $Null

# Retain the latest lastLogon value for the user.
$LLDate = [DateTime]0
$UserLast = $LLDate.AddYears(1600).ToLocalTime()

# Retain the cumulative total logonCount for the user
$TotalCount = 0

# Output a header line, comma delimited.
"Domain Controller,Last Logon,Logon Count"

# Query every domain controller in the domain.
ForEach ($DC In $D.DomainControllers)
{
    # Ping each domain controller.
    If (ping $DC -n 1 -w 1000 | find "Reply from")
    {
        # DC responded.
        # Trap any error, but do not halt the script. The error message
        # will not be redirected, but will display at the prompt.
        Trap{Write-Host "DC $Server - $_" `
            -foregroundcolor red -backgroundcolor black; Continue;}
        $Server = $DC.Name
        $Result = $Null
        # Specify the DC and the domain in the Base of the query.
        $Base = "LDAP://$Server/" + $Domain.distinguishedName
        $Searcher.SearchRoot = $Base
        $Result = $Searcher.FindOne()
        If($Result)
        {
            # Retrieve the values for the user on this DC.
            $LogonCount = $Result.Properties.Item("logonCount")[0]
            If (-Not $LogonCount) {$LogonCount = 0}
            $LL = $Result.Properties.Item("lastLogon")[0]
            If (-Not $LL) {$LL = 0}
            $Last = ([DateTime]$LL).AddYears(1600).ToLocalTime()
            # Retain the latest lastLogon value.
            If ($Last -gt $UserLast) {$UserLast = $Last}
            # Check if logonCount greater than 0.
            If ($LogonCount -gt 0)
            {
                # Add logonCount to the total.
                $TotalCount = $TotalCount + $LogonCount
            }
            # Output values for the user on this DC.
            "$Server,$Last,$LogonCount"
        }
    }
    Else
    {
        Write-Host "DC $DC is not available -foregroundcolor red -backgroundcolor black"
    }
}

If ($UserLast -lt ([DateTime]0).AddYears(1602).ToLocalTime()) {$UserLast = "Never"}
# Output for all DCs, comma delimited.
"All Domain Controllers,$UserLast,$TotalCount"