🔁 Reset AD Passwords in Bulk from CSV with Force-Change-at-Logon
The Problem: Bulk Reset Is Different from Bulk Creation
Creating new AD users with generated passwords is one workflow. Resetting existing users — especially after a security incident, a forgotten-password wave, or an offboarding sweep — is a completely different challenge:
- You're working with existing accounts, not new ones.
Set-ADAccountPasswordreplacesNew-ADUser. - You must force a password change at next logon — otherwise users keep the temporary credential indefinitely.
- You may need to target specific OUs, groups, or user subsets (active accounts only, accounts flagged for reset, etc.).
- The reset affects live users. Mistakes interrupt work.
This guide covers the complete end-to-end workflow: generate unique secure passwords → build the reset CSV → run the PowerShell reset script → verify every account.
What You'll Need
- A domain-joined machine with the Active Directory module for PowerShell (RSAT)
- Domain admin credentials or delegated reset-password permissions on the target OUs
- The Instant Password Generator browser tab — no installation needed
Step 1: Generate Unique Passwords
Open the Instant Password Generator and configure:
- Count: Match the number of users whose passwords you're resetting
- Length: 20+ characters to exceed all domain password policies and NIST SP 800-63B minimums
- Character classes: All four — uppercase, lowercase, numbers, symbols
- Format: CSV export — the tool outputs
index,"password"
Step 2: Build the Reset CSV
Create a reset.csv with this structure. The sam column is the sAMAccountName — the pre-Windows 2000 logon name:
sam,password,ou jsmith,P@$$w0rd123!,OU=Users,DC=contoso,DC=com agarcia,Kj9#mB2$xL7!,OU=Users,DC=contoso,DC=com bnguyen,Zp4&qR8*vF2!,OU=Sales,DC=contoso,DC=com mwilliams,Xm3@zK1!qL8,OU=Users,DC=contoso,DC=com
To merge your generated passwords with existing user data:
# Merge generated passwords with user SAM list
$passwords = Import-Csv "passwords.csv" | Select-Object -ExpandProperty password
$users = @("jsmith", "agarcia", "bnguyen")
$output = for ($i = 0; $i -lt $users.Count; $i++) {
[PSCustomObject]@{
sam = $users[$i]
password = $passwords[$i]
ou = "OU=Users,DC=contoso,DC=com"
}
}
$output | Export-Csv "reset.csv" -NoTypeInformation
Step 3: Bulk Reset Passwords
This is the core script. It reads the CSV, resets each user's password, and forces a change at next logon:
Import-Module ActiveDirectory
$users = Import-Csv "reset.csv"
foreach ($user in $users) {
$securePwd = ConvertTo-SecureString $user.password -AsPlainText -Force
try {
Set-ADAccountPassword -Identity $user.sam `
-NewPassword $securePwd `
-Reset `
-ErrorAction Stop
Set-ADUser -Identity $user.sam `
-ChangePasswordAtLogon $true
Write-Host "✓ Reset password for $($user.sam) with force-change-at-logon" -ForegroundColor Green
}
catch {
Write-Host "✗ Failed for $($user.sam): $_" -ForegroundColor Red
}
}
Key Parameters Explained
| Parameter | Purpose |
|---|---|
-Reset | Forces a password reset even if the user doesn't know their current password. Critical for lockout/compromise scenarios. |
-NewPassword | The generated password as a secure string. Must be complex enough to meet domain policy. |
-ChangePasswordAtLogon $true | Ensures the generated password is one-time use. The user creates their own password on first login. |
-Identity | Accepts sAMAccountName, UPN, or Distinguished Name. We use sAMAccountName from the CSV. |
Step 4: OU-Specific Scenarios
Reset All Users in a Specific OU
# Reset every user in the Sales OU
$ou = "OU=Sales,DC=contoso,DC=com"
Get-ADUser -Filter * -SearchBase $ou | ForEach-Object {
$securePwd = ConvertTo-SecureString "NewTempP@ss123!" -AsPlainText -Force
Set-ADAccountPassword -Identity $_.SamAccountName -NewPassword $securePwd -Reset
Set-ADUser -Identity $_.SamAccountName -ChangePasswordAtLogon $true
Write-Host "Reset $($_.SamAccountName)" -ForegroundColor Green
}
Reset Only Disabled or Locked-Out Accounts
# Find and reset locked-out users
$locked = Search-ADAccount -LockedOut
foreach ($user in $locked) {
$securePwd = ConvertTo-SecureString "Unl0ck@2026!" -AsPlainText -Force
Set-ADAccountPassword -Identity $user.SamAccountName -NewPassword $securePwd -Reset
Set-ADUser -Identity $user.SamAccountName -ChangePasswordAtLogon $true
Unlock-ADAccount -Identity $user.SamAccountName
Write-Host "Unlocked and reset $($user.SamAccountName)" -ForegroundColor Yellow
}
Bulk Reset from a Text File (One User Per Line)
# Single-column user list
$users = Get-Content "users.txt"
$passwords = (Import-Csv "passwords.csv").password
for ($i = 0; $i -lt $users.Count; $i++) {
$securePwd = ConvertTo-SecureString $passwords[$i] -AsPlainText -Force
Set-ADAccountPassword -Identity $users[$i] -NewPassword $securePwd -Reset
Set-ADUser -Identity $users[$i] -ChangePasswordAtLogon $true
Write-Host "Reset $($users[$i])" -ForegroundColor Green
}
Step 5: Verification
After running the bulk reset, verify every account:
# Check users who still don't require password change
Get-ADUser -Filter {PasswordNeverExpires -eq $false -and Enabled -eq $true} `
-Properties pwdLastSet | Where-Object { $_.pwdLastSet -eq 0 } | `
Select-Object Name, SamAccountName
# Confirm specific user was reset
Get-ADUser jsmith -Properties PasswordLastSet, pwdLastSet, LastLogonDate
# Count recently reset users
$since = (Get-Date).AddHours(-1)
Get-ADUser -Filter {PasswordLastSet -ge $since} -Properties PasswordLastSet | `
Measure-Object | Select-Object -ExpandProperty Count
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
| "Access denied" | Insufficient AD permissions | Run as domain admin or delegate reset-password for the target OU |
| "Cannot find an object with identity" | sAMAccountName doesn't exist or is misspelled | Verify user exists: Get-ADUser user. Check CSV for typos. |
| "The password does not meet policy requirements" | Password violates domain password policy | Generate with all 4 character classes at 20+ characters |
| "The user account is disabled" | Account is inactive | Use -Enabled $true or enable via Enable-ADAccount |
Next Article in This Series
This is part of the Active Directory password management series:
- 📋 New-ADUser Bulk Creation with Generated Passwords — create new users with unique passwords
- 🔁 Reset AD Passwords in Bulk from CSV — you're here
- 🗂️ Bulk Password Generation for Windows AD — overview of the complete workflow
- 📊 CSV Password Pipelines: From Bulk Generation to IAM Import — Okta, Entra ID, and more
For teams managing passwords across multiple users, a shared credential vault simplifies the whole lifecycle. NordPass Business integrates directly with AD and provides secure password sharing, access groups, and breach monitoring.
Disclosure: If you purchase through the NordPass link above, we may earn a commission at no extra cost to you. All affiliate links are marked with "sponsored" per FTC and ASA guidelines.