How to Pull Active Directory Reports: PowerShell, Excel Export & Free Tools

Posted by AlbusBit on October 25, 2025 · 23 min read

Every Active Directory environment needs regular reporting — for security audits, compliance reviews, user cleanup, or just answering management questions like "how many inactive accounts do we have?" This guide covers three approaches to pulling AD reports: PowerShell (the manual way), built-in Windows tools, and dedicated reporting software. Each section includes practical examples you can use immediately.

Table of Contents

Pulling AD Reports with PowerShell

PowerShell with the Active Directory module is the most common way to pull AD reports. It's free, built into Windows Server, and extremely flexible. The downside is that every report requires writing and testing a script, and some data (like accurate last logon times) requires querying multiple domain controllers.

Before running any of the commands below, make sure the AD module is available:

Import-Module ActiveDirectory

If the module isn't installed, you'll need the Remote Server Administration Tools (RSAT) on your workstation, or run the commands directly on a domain controller.

User Reports: All Users, Inactive Accounts, Password Status

User reports are by far the most requested AD reports. Here are the PowerShell commands for the most common ones:

All users with key attributes

Get-ADUser -Filter * -Properties DisplayName, Department, Title, `
    EmailAddress, LastLogonDate, Enabled |
  Select-Object Name, SamAccountName, DisplayName, Department, `
    Title, EmailAddress, LastLogonDate, Enabled |
  Export-Csv -Path "AllUsers.csv" -NoTypeInformation

Inactive users (no logon in 90 days)

$CutoffDate = (Get-Date).AddDays(-90)
Get-ADUser -Filter {LastLogonDate -lt $CutoffDate -and Enabled -eq $true} `
    -Properties LastLogonDate, Department |
  Select-Object Name, SamAccountName, LastLogonDate, Department |
  Export-Csv -Path "InactiveUsers.csv" -NoTypeInformation

Users with password expiring in the next 14 days

$Today = Get-Date
$MaxAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge.Days
Get-ADUser -Filter {Enabled -eq $true -and PasswordNeverExpires -eq $false} `
    -Properties PasswordLastSet |
  Where-Object {
    ($_.PasswordLastSet.AddDays($MaxAge) - $Today).Days -le 14 -and
    ($_.PasswordLastSet.AddDays($MaxAge) - $Today).Days -ge 0
  } |
  Select-Object Name, SamAccountName, PasswordLastSet, `
    @{N='ExpiresOn';E={$_.PasswordLastSet.AddDays($MaxAge)}} |
  Export-Csv -Path "PasswordExpiring.csv" -NoTypeInformation

Disabled accounts

Get-ADUser -Filter {Enabled -eq $false} -Properties WhenChanged |
  Select-Object Name, SamAccountName, WhenChanged |
  Export-Csv -Path "DisabledUsers.csv" -NoTypeInformation

These scripts work well for one-off reports, but they have limitations. Each new report type means writing a new script. Complex attributes like UserAccountControl require manual decoding — the raw value 0x0202 means "normal user account, disabled," but PowerShell won't tell you that. And getting clean, formatted Excel output (not just CSV) requires additional libraries or manual conversion.

Easier alternative: AD FastReporter includes built-in report forms for all of the above — all users, inactive users, password expiring, disabled accounts, and 240+ more. Select a report, choose your fields, click Generate. No scripting needed, and it automatically decodes attributes like UserAccountControl into readable values.

Computer Reports: OS Versions, Inactive Machines

Computer account reports are essential for tracking your hardware inventory, identifying machines running outdated operating systems, and cleaning up stale computer accounts.

All computers with OS details

Get-ADComputer -Filter * -Properties OperatingSystem, `
    OperatingSystemVersion, LastLogonDate, IPv4Address |
  Select-Object Name, OperatingSystem, OperatingSystemVersion, `
    LastLogonDate, IPv4Address |
  Export-Csv -Path "AllComputers.csv" -NoTypeInformation

Computers running outdated operating systems

Get-ADComputer -Filter {OperatingSystem -notlike "*Windows 11*" `
    -and OperatingSystem -notlike "*Windows 10*" `
    -and OperatingSystem -notlike "*Server 2022*" `
    -and OperatingSystem -notlike "*Server 2025*"} `
    -Properties OperatingSystem, LastLogonDate |
  Select-Object Name, OperatingSystem, LastLogonDate |
  Sort-Object OperatingSystem |
  Export-Csv -Path "OutdatedOS.csv" -NoTypeInformation

Inactive computers (no logon in 90 days)

$CutoffDate = (Get-Date).AddDays(-90)
Get-ADComputer -Filter {LastLogonDate -lt $CutoffDate} `
    -Properties LastLogonDate, OperatingSystem |
  Select-Object Name, OperatingSystem, LastLogonDate |
  Export-Csv -Path "InactiveComputers.csv" -NoTypeInformation

These commands use LastLogonDate (the replicated lastLogonTimestamp attribute), which can be up to 14 days behind the actual last logon. For most cleanup purposes this is acceptable, but if you need precise data, see the last logon report section below.

Easier alternative: AD FastReporter's Computer category includes built-in reports for all computers by OS, inactive computers, servers vs workstations, and more. The tool also supports IPv4 and IPv6 address fields and BitLocker recovery key reporting (if you have the required AD permissions).

Last Logon Report: Getting Accurate Data

Generating an accurate "last logon" report is one of the most common — and most misunderstood — AD reporting tasks. The problem comes down to two different AD attributes:

  • lastLogonTimestamp (PowerShell: LastLogonDate) — Replicated across domain controllers, but only updated at intervals of 9–14 days. Easy to query but up to two weeks behind.
  • lastLogon — Updated on every logon, but not replicated between DCs. Each domain controller only records logons it handled directly. To get the true last logon time, you must query every DC and take the most recent value.

For an approximate report (good enough for identifying accounts inactive for 90+ days), LastLogonDate works fine — see the inactive user scripts above. But for a precise last logon report, here's the PowerShell approach:

Accurate last logon from all domain controllers

# Query all DCs for precise lastLogon values
$DCs = Get-ADDomainController -Filter *
$Users = @{}

foreach ($DC in $DCs) {
    Write-Host "Querying $($DC.HostName)..."
    Get-ADUser -Filter * -Properties lastLogon -Server $DC.HostName |
      ForEach-Object {
        $Logon = [DateTime]::FromFileTime($_.lastLogon)
        if (-not $Users.ContainsKey($_.SamAccountName) -or
            $Users[$_.SamAccountName].LastLogon -lt $Logon) {
            $Users[$_.SamAccountName] = [PSCustomObject]@{
                Name = $_.Name
                SamAccountName = $_.SamAccountName
                LastLogon = $Logon
                LastLogonDC = $DC.HostName
            }
        }
    }
}

$Users.Values | Sort-Object LastLogon |
  Export-Csv -Path "AccurateLastLogon.csv" -NoTypeInformation

This script works, but it has significant drawbacks in practice:

  • Speed: It queries every user from every DC sequentially. In an environment with 10,000 users and 5 DCs, that's 50,000+ LDAP queries.
  • Unreachable DCs: If a domain controller is offline or unreachable, the script may fail or produce incomplete results without warning.
  • No export formatting: You get a raw CSV, not a formatted Excel report.

AD FastReporter solves this automatically. When you include the "Last Logon Time" field in any user or computer report, it queries every accessible domain controller in your environment and returns the most recent logon time per account. If a DC is unreachable, it completes the report and warns you which DCs were missed — rather than failing silently.

Download free version — works on any domain-joined workstation, no server installation needed.

Group Reports: Membership, Empty Groups, Nested Groups

Group reports answer questions like "who is in this group?", "which groups have no members?", and "what groups does this user belong to (including nested memberships)?" If you also need to delegate day-to-day group membership changes to department managers, see AD Group Manager Web — a self-service portal that works alongside reporting tools.

All groups with member counts

Get-ADGroup -Filter * -Properties Members, ManagedBy, GroupScope, `
    GroupCategory, Description |
  Select-Object Name, GroupScope, GroupCategory, Description, `
    @{N='MemberCount';E={$_.Members.Count}},
    @{N='ManagedBy';E={
        if ($_.ManagedBy) {(Get-ADUser $_.ManagedBy).Name} else {""}
    }} |
  Sort-Object MemberCount -Descending |
  Export-Csv -Path "AllGroups.csv" -NoTypeInformation

Empty groups (cleanup candidates)

Get-ADGroup -Filter * -Properties Members |
  Where-Object { $_.Members.Count -eq 0 } |
  Select-Object Name, GroupScope, GroupCategory |
  Export-Csv -Path "EmptyGroups.csv" -NoTypeInformation

All groups a specific user belongs to (including nested)

# Direct memberships only
Get-ADPrincipalGroupMembership -Identity "jsmith" |
  Select-Object Name, GroupScope, GroupCategory

# Including nested (recursive) memberships
$User = Get-ADUser "jsmith" -Properties MemberOf
$AllGroups = @()
$Queue = [System.Collections.Queue]::new()
$User.MemberOf | ForEach-Object { $Queue.Enqueue($_) }
$Visited = @{}

while ($Queue.Count -gt 0) {
    $GroupDN = $Queue.Dequeue()
    if ($Visited.ContainsKey($GroupDN)) { continue }
    $Visited[$GroupDN] = $true
    $Group = Get-ADGroup $GroupDN -Properties MemberOf
    $AllGroups += $Group
    $Group.MemberOf | ForEach-Object { $Queue.Enqueue($_) }
}

$AllGroups | Select-Object Name, GroupScope, GroupCategory

Nested group membership resolution is where PowerShell gets complicated quickly. The recursive script above works but is slow for users in many groups, and doesn't easily scale to reporting on all users at once.

AD FastReporter handles this natively — it resolves inherited (nested) group memberships for any user, with separate fields for direct membership, inherited membership, membership by group type (security vs distribution), and membership by scope (domain local, global, universal). It also calculates both direct and total member counts for group reports.

How to Export Active Directory Data to Excel

The most common request from management: "I need this in Excel." Here are your options:

Option 1: PowerShell to CSV, then open in Excel

All the PowerShell examples above use Export-Csv, which produces a CSV file. You can open this directly in Excel, but it has limitations: no formatting, no auto-sized columns, date values may display incorrectly, and Unicode characters can cause encoding issues.

Option 2: PowerShell with ImportExcel module

The ImportExcel PowerShell module can export directly to XLSX format:

# Install once
Install-Module ImportExcel -Force

# Export users directly to formatted Excel
Get-ADUser -Filter * -Properties DisplayName, Department, LastLogonDate |
  Select-Object Name, SamAccountName, Department, LastLogonDate |
  Export-Excel -Path "ADUsers.xlsx" -AutoSize -FreezeTopRow -BoldTopRow

This is the best PowerShell-based option for Excel output, but requires installing a third-party module, which may not be allowed in locked-down environments.

Option 3: Dedicated reporting tool with built-in export

AD FastReporter Pro exports directly to 8 formats: Excel (XLSX), CSV, CSV (append), HTML, PDF, XML, ODS, and JSON. The Excel export includes formatted columns, auto-sizing, and proper date handling. The CSV (append) mode is useful for building cumulative data files — each scheduled run adds rows to the same file instead of overwriting.

Active Directory users exported to Excel spreadsheet

AD FastReporter Excel export — formatted and ready to share

Download sample exports to see the output quality:

Using a Dedicated AD Reporting Tool (Free)

If you need reports regularly, or if you're not comfortable writing PowerShell scripts, a dedicated tool saves significant time. Here's what to look for and how AD FastReporter compares.

What a good AD reporting tool should do

  • No server installation: Run from your workstation, not on domain controllers
  • Read-only: Query AD via LDAP without modifying your directory or schema
  • Pre-built reports: Cover the common cases without custom configuration
  • Accurate last logon: Query all DCs for the lastLogon attribute, not just lastLogonTimestamp
  • Export options: At minimum Excel and CSV; ideally PDF and HTML too
  • Custom reports: Build your own reports when the built-in ones aren't enough

AD FastReporter overview

AD FastReporter is a Windows desktop application that reads Active Directory data using standard LDAP queries. It includes over 250 built-in report forms organized across 8 categories:

Category What it reports on Example reports
Users User accounts — status, logon history, passwords, organization All users, inactive users (30/60/90 days), password expiring, disabled, locked out, never logged on
Computers Computer accounts — OS details, logon status, IP addresses All computers, by OS version, inactive computers, servers vs workstations
Groups Security and distribution groups — members, counts, scope All groups, empty groups, groups by scope, security groups with member counts
Exchange Mail-enabled objects — mailbox settings, protocols Exchange users, mail-enabled contacts, protocol status (OWA, POP3, IMAP4, MAPI)
Contacts AD contact objects — names, email, organization All contacts, contacts by company
Printers Published printers — names, locations, servers All published printers
GPOs Group Policy Objects — links, status All GPOs with links to OUs/sites/domains, GPO status
OUs Organizational Units — structure, child object counts All OUs with user/computer/group counts
AD FastReporter reporting tool interface with report categories

AD FastReporter report catalog — 250+ built-in reports across 8 categories

How to generate a report:

  1. Select a report form from the catalog (e.g., Users → Logon Status → "Users not logged on in 90 days")
  2. Choose which AD fields to include as columns — pick from names, organization, account status, password status, membership, and more
  3. Click Generate — results appear in a sortable, searchable table
  4. Export to your preferred format (Pro version)
Selecting Active Directory attributes for report columns

Select from 100+ AD attributes per report — add any field you need

System requirements: Windows 10 or later (including Windows Server 2016+), .NET 10 Desktop Runtime, domain-joined workstation with read access to AD. Standard domain user permissions are sufficient for most reports. Install on your workstation — no server installation, no agents, no schema changes.

Download AD FastReporter Free — all 250+ reports, no time limit.

Automating Reports on a Schedule

One-off reports are useful, but regular automated reporting catches problems before they become incidents. Here are recommended reporting schedules:

Frequency Report Why
Daily Locked-out accounts Identify potential brute-force attacks or user issues
Weekly New users created in the last 7 days Verify all new accounts are authorized
Weekly Users with passwords expiring in 14 days Proactive notification before passwords expire
Monthly Inactive users (90+ days no logon) Clean up abandoned accounts
Monthly Inactive computers (90+ days) Identify hardware for decommissioning
Monthly Empty groups Remove unnecessary group objects
Quarterly Domain admin group membership Audit privileged access

Scheduling with PowerShell

Save your PowerShell scripts as .ps1 files and schedule them with Windows Task Scheduler:

# Create a scheduled task to run a report script weekly
$Action = New-ScheduledTaskAction -Execute "PowerShell.exe" `
    -Argument "-ExecutionPolicy Bypass -File C:\Scripts\WeeklyADReport.ps1"
$Trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Monday -At 7am
Register-ScheduledTask -TaskName "Weekly AD Report" `
    -Action $Action -Trigger $Trigger -RunLevel Highest

Scheduling with AD FastReporter

AD FastReporter Pro includes built-in scheduling that integrates with Windows Task Scheduler. For each scheduled task, you configure:

  • Which report to run (any built-in or custom report form)
  • Which fields to include
  • Export format and destination path
  • Email recipients (sends the report as an attachment via SMTP)
  • Schedule (daily interval with start date)

Tasks run automatically using the command-line tool ADFastReporterCmd.exe — no GUI needed. The tool logs results and can notify you of errors.

Setting up automated Active Directory report schedule

Configure scheduled reports with export and email delivery

Free vs Pro: Which Version Do You Need?

Feature Free Pro
250+ built-in reports across 8 categories
Multiple domain/forest connections
Accurate lastLogon from all DCs
Export (XLSX, CSV, PDF, HTML, XML, ODS, JSON)
Custom report forms with filters
Scheduled automated reporting + email
Charts and visualizations
Custom LDAP fields
NIS2 compliance dashboard
Report history and storage
Recommendation: Start with the free version — you get all 250+ reports with no time limit. If you find yourself needing exports, custom reports, or scheduled automation, upgrade to Pro. Your connections and settings carry over.

Summary

Pulling Active Directory reports doesn't have to mean hours of PowerShell scripting. For simple, one-off queries, the PowerShell commands in this guide will get you what you need. For regular reporting — especially across multiple report types with Excel export and scheduling — a dedicated tool like AD FastReporter handles the complexity for you, including tricky tasks like querying all domain controllers for accurate last logon data and resolving nested group memberships.

Whatever approach you choose, the important thing is to report regularly. A monthly review of inactive accounts, password status, and privileged group membership catches security issues before they become incidents.

Questions? Contact us at support@albusbit.com for help with Active Directory reporting.



Use of this site constitutes acceptance of our Privacy Policy and EULA. Copyright © Albus Bit SIA