Aubs
Aubs

Reputation: 340

Active Directory - Get LastLogonDate from all Domain Controllers for multiple users

The following script works perfectly, but I think it's way too complex and slow for what it needs to do.

Basically, for a list of users in a variable (manually or obtained from Get-ADUser, doesn't matter), I want to query all Domain Controllers and get the LastLogonDate for each user. I'll later use it for bad password etc.

Any suggestions on cleaning it up please that would improve my coding skills?

$UserList = "User1", "User2"

$DCs = (Get-ADDomainController -Filter *).Name

$Combined = foreach ($User in $UserList)
{
    $DCarray = [ordered] @{}
    foreach ($DC in $DCs)
    {
        $DCresponse = Get-ADUser $User -Properties DisplayName, LastLogonDate -Server $DC | Select-Object Name, DisplayName, LastLogonDate
        if( -not $DCarray.Contains("Name")) { $DCarray.Add("Name",$DCresponse.name) }
        if( -not $DCarray.Contains("DisplayName")) { $DCarray.Add("DisplayName",$DCresponse.DisplayName) }
        if( -not $DCarray.Contains($DC)) { $DCarray.Add($DC,$DCresponse.LastLogonDate) }
    }
    $Return = New-Object -TypeName psobject
        foreach ($Key in $DCarray.keys)
        {
            $Each = $DCarray[$Key]
            
            $Return | Add-Member -MemberType NoteProperty -Name $Key -Value $Each
        }
    $Return
}

$Combined | Format-Table -AutoSize

Upvotes: 1

Views: 2269

Answers (2)

gazza
gazza

Reputation: 11

I can't leave a comment, so posting as an Answer instead.

For a non-Powershell solution have a look at this tool which will retrieve the the last logon time from all DC in the forest\domain for a list of users, based on a list of samaccountnames.

https://nettools.net/last-logon-time/

Gary

Upvotes: 0

Santiago Squarzon
Santiago Squarzon

Reputation: 60045

I think the logic is mostly the same but this should be easier to understand and maintain. In addition, the use of the LDAPFilter should improve the runtime a bit.

$UserList = "User1", "User2", "User3"
$filter = "(|(name={0}))" -f ($UserList -join ')(name=')
# LDAP query string would look like: (|(name=User1)(name=User2)(name=User3))

$DCs = (Get-ADDomainController -Filter *).Name

$props = @{
    Properties = 'DisplayName', 'LastLogonDate'
    LDAPFitler = $filter
}

$result = foreach($dc in $DCs)
{
    $props.Server = $dc
    $users = Get-ADUser @props

    foreach($user in $users)
    {
        # If this User's LastLogonDate attribute is NOT null
        if($user.LastLogonDate)
        {
            [pscustomobject]@{
                DomainController = $dc
                UserName = $user.Name
                DisplayName = $user.DisplayName
                LastLogonDate = $user.LastLogonDate
            }
        }
    }
}

$result | Sort-Object UserName, LastLogonDate | Out-GridView

Upvotes: 1

Related Questions