1

I would like to query all AD users and get the following attributes from each user:

SamAccountName, UserPrincipalName, LastLogonDate, Enabled, LockedOut, PasswordNeverExpires, CannotChangePassword, whenCreated

As the domain has more than one domain controller I also want to make sure I get all the data. Any thoughts?

Many thanks

Here my code:

$domainControllers = Get-ADDomainController -Filter * | Select-Object -ExpandProperty Name
Write-Host "Create AD user report accross the following domaincontroller: $domaincontrollers"

# Create an empty array to store the results
$results = @()
$searchbase= "DC=XXX,DC=XX"

# Iterate through each domain controller and retrieve users
foreach ($dc in $domainControllers) {
     $users = Get-ADUser -Filter * -SearchBase $Searchbase -Properties SamAccountName, UserPrincipalName, LastLogonDate, Enabled, LockedOut, PasswordNeverExpires, CannotChangePassword, whenCreated |
         Select-Object SamAccountName, UserPrincipalName, @{Name="LastLogin"; Expression={$_.LastLogonDate}}, Enabled, LockedOut, PasswordNeverExpires, CannotChangePassword , whenCreated
    $results += $users
# Export the results to a CSV file
}

$resultfinal = $results | Select-Object * -Unique
$resultfinal| Export-Csv -Path c:\logging\data\AD_User_Report.csv -NoTypeInformation

However often I simply get nothing back and I'm not sure why exactly. Probably it's related the "unique" sorting option?

Based on the domain spot checks (attribut editor) every user object would have the lastlogonDate so the domain schema should be up-to-date.

Rambo2000
  • 13
  • 2
  • Does this answer your question? https://stackoverflow.com/questions/75337565/exporting-last-logon-date-for-inactive-users-via-powershell/75339028#75339028 – Santiago Squarzon Aug 25 '23 at 12:43
  • This might also be helpful https://social.technet.microsoft.com/wiki/contents/articles/22461.understanding-the-ad-account-attributes-lastlogon-lastlogontimestamp-and-lastlogondate.aspx – David Trevor Aug 25 '23 at 13:24

2 Answers2

0

In a big environment this will not be very performant. Querying all domain controllers to get the "complete" data can be misleading, because what happens when you delete a user in one domain controller, but it has not replicated yet? That user would be added to the list in your script.

I recommend query only one domain controller (force a replication via script beforehand if necessary). Skip the "Select-Object -Unique" altogether.

David Trevor
  • 794
  • 1
  • 7
  • 22
  • Thanks - the replication didn't help so far. There are clearly lastlogonDate timestamps on all user (visible in AD browser) however not available if queried by powershell. – Rambo2000 Aug 25 '23 at 11:54
0

Here is a snippet of the code I used. It queries each domain controller and records the most recent logon time found between all the controllers. My domain only has three controllers so the code finished quickly.

#gets a list of domain controllers
$dcs = Get-ADDomainController -Filter {Name -like "*"}
#list of users including specied properties
$users = Get-ADUsers -Properties name, description, enabled , Department,   CanonicalName, userPrincipalName
  
  
  $result =@()
  #loops through each user and then each domain controller
  foreach($user in $users)
  {
    $time = 0
    $License = "No Email"

    foreach($dc in $dcs)
    { 
      # queries the dc for the user last reprted logon time
      $currentUser = Get-ADUser $user | Get-ADObject -Server $dc.HostName -Properties lastlogon
       
      #checks if the logon time from the dc is more recent than the logon time from previous dc.  If it is then $time is set to the current dc logon time for the user.
      #A user will return 0 on a controller if they have never logged in using the dc.
      if($currentUser.LastLogon -gt $time) 
      {
        $time = $currentUser.LastLogon
           # Converts the last logon time returned from the dc to a human readable format. The code will return a very old date if $time = 0
           if($time -ne "0")
            {
            $dt = [DateTime]::FromFileTime($time)
            $currentdc = $dc.Hostname
            }
      }
      
    }

Finally I put all the data in a pscustomobect and exported that to excel

Warlord213
  • 74
  • 4