Overview
When planning an AD migration, the first task is always understanding what you have. This script exports all user accounts from an Active Directory domain with the attributes most relevant to migration planning: display name, UPN, email, enabled status, last logon, group memberships, and home directory path.
The output is a clean CSV you can open in Excel or load into a migration planning tool.
The Script
# AD User Bulk Export
# Exports all AD users with key migration attributes to CSV
# Requires: ActiveDirectory module (RSAT)
#
# Usage: .\Export-ADUsers.ps1 -OutputPath "C:\Exports\users.csv"
param(
[Parameter(Mandatory)]
[string]$OutputPath,
[string]$SearchBase = "", # Leave empty for entire domain
[switch]$EnabledOnly # Only export enabled accounts
)
Import-Module ActiveDirectory -ErrorAction Stop
$filter = if ($EnabledOnly) { { Enabled -eq $true } } else { * }
$params = @{
Filter = $filter
Properties = @(
'DisplayName', 'UserPrincipalName', 'EmailAddress',
'Enabled', 'LastLogonDate', 'HomeDirectory',
'Department', 'Manager', 'MemberOf',
'PasswordLastSet', 'PasswordNeverExpires',
'DistinguishedName', 'SamAccountName'
)
}
if ($SearchBase) { $params.SearchBase = $SearchBase }
$users = Get-ADUser @params | ForEach-Object {
$groups = ($_.MemberOf | ForEach-Object {
(Get-ADGroup $_).Name
}) -join '; '
[PSCustomObject]@{
SamAccountName = $_.SamAccountName
DisplayName = $_.DisplayName
UPN = $_.UserPrincipalName
Email = $_.EmailAddress
Enabled = $_.Enabled
LastLogonDate = $_.LastLogonDate
PasswordLastSet = $_.PasswordLastSet
PasswordNeverExpires= $_.PasswordNeverExpires
HomeDirectory = $_.HomeDirectory
Department = $_.Department
Groups = $groups
DistinguishedName = $_.DistinguishedName
}
}
$users | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8
Write-Host "Exported $($users.Count) users to $OutputPath"
Usage
# Export all users in the domain
.\Export-ADUsers.ps1 -OutputPath "C:\Exports\all-users.csv"
# Export only enabled users from a specific OU
.\Export-ADUsers.ps1 -OutputPath "C:\Exports\enabled-users.csv" `
-SearchBase "OU=Users,DC=contoso,DC=com" `
-EnabledOnly
Notes
- The
LastLogonDateattribute is replicated every 9–14 days, so accounts that haven’t logged in recently might still show an older date. For precision, query each DC individually. - Group membership expansion (
MemberOf) can be slow on large domains. For domains with 10,000+ users, consider piping through a job or batching. - The script requires the RSAT Active Directory module. On Windows 10/11:
Add-WindowsCapability -Online -Name "Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0".