📋 Set-ADAccountPassword Cheat Sheet: Syntax, Examples, Bulk Operations
The Set-ADAccountPassword cmdlet is the primary PowerShell tool for managing Active Directory user passwords. Unlike New-ADUser -AccountPassword, which only works during user creation, Set-ADAccountPassword operates on existing accounts — making it essential for password resets, offboarding, and incident response.
This cheat sheet covers every parameter, every common scenario, and the edge cases that trip up even experienced IT admins.
Basic Syntax
Set-ADAccountPassword [-Identity] <ADUser> [-NewPassword] <SecureString> [-Reset] [-PassThru] [-Server] [-Credential] [-WhatIf] [-Confirm] [<CommonParameters>]
Quick Reference
Reset password (admin)
Set-ADAccountPassword -Identity "jsmith" -NewPassword $secPwd -Reset
Forces a password reset without knowing the current password. Requires reset-password privilege.
Change password (user knows old)
Set-ADAccountPassword -Identity "jsmith" -OldPassword $oldSec -NewPassword $newSec
Changes password using the current password for verification. No special privilege needed.
Bulk reset from CSV
Import-Csv "reset.csv" | ForEach-Object { $sec=ConvertTo-SecureString $_.password -AsPlainText -Force; Set-ADAccountPassword -Identity $_.sam -NewPassword $sec -Reset }
Resets multiple users using a CSV with columns: sam, password.
Reset + force change at logon
Set-ADAccountPassword -Identity "jsmith" -NewPassword $secPwd -Reset
Set-ADUser -Identity "jsmith" -ChangePasswordAtLogon $true
The -Reset parameter doesn't set ChangePasswordAtLogon. Always call Set-ADUser separately.
Parameter Reference
| Parameter | Type | Required | Description |
|---|---|---|---|
-Identity | ADUser | Yes | Specifies the user. Accepts sAMAccountName, Distinguished Name, GUID, or SID. Most common: sAMAccountName. |
-NewPassword | SecureString | Yes | The new password as a secure string. Must be created with ConvertTo-SecureString. |
-Reset | Switch | Conditional | Resets the password without requiring the old password. Requires "Reset password" permission. Required for admin-initiated resets. |
-OldPassword | SecureString | Conditional | The current password. Required when -Reset is NOT used (user-initiated change). |
-PassThru | Switch | No | Returns the modified user object for further processing or verification. |
-Server | String | No | Target domain controller. Defaults to any available DC. Use for cross-domain or site-specific operations. |
-Credential | PSCredential | No | Alternative credentials for running the cmdlet. Use when your current session lacks sufficient privileges. |
-WhatIf | Switch | No | Shows what would happen without executing. Always test with -WhatIf in production. |
-Confirm | Switch | No | Prompts for confirmation before executing each change. Use for small batches. |
Secure String Conversion
The trickiest part of using Set-ADAccountPassword is creating the SecureString. These three methods all work but have different use cases:
| Scenario | Syntax | When to Use |
|---|---|---|
| From a plaintext variable (scripting) | $secPwd = ConvertTo-SecureString "P@$$w0rd" -AsPlainText -Force | Most common for automation scripts. The -Force flag confirms you know the string is in plaintext. |
| From user input (interactive) | $secPwd = Read-Host "Enter password" -AsSecureString | When you want the password to stay encrypted in memory and never appear on screen. |
| From a file (batch processing) | $passwords = Import-Csv "passwords.csv" | When importing generated passwords from the Instant Password Generator CSV export. The generator's CSV output maps directly to this workflow. |
Set-ADAccountPassword -Identity "jsmith" -NewPassword "P@$$w0rd" fails because -NewPassword requires a SecureString, not a plaintext string. Always wrap in ConvertTo-SecureString.
Bulk Operations
Reset All Users in an OU
Import-Module ActiveDirectory
$ou = "OU=Sales,DC=contoso,DC=com"
$generated = Import-Csv "passwords.csv"
$users = Get-ADUser -Filter * -SearchBase $ou
$i = 0
$users | ForEach-Object {
$secPwd = ConvertTo-SecureString $generated[$i].password -AsPlainText -Force
Set-ADAccountPassword -Identity $_.SamAccountName -NewPassword $secPwd -Reset
Set-ADUser -Identity $_.SamAccountName -ChangePasswordAtLogon $true
$i++
}
Reset with Different Passwords Per User (From Generator CSV)
# CSV from generator: index,password
# Merge with user list
$passwords = Import-Csv "generated_passwords.csv"
$userList = @("jsmith", "agarcia", "bnguyen", "mwilliams")
for ($i = 0; $i -lt $userList.Count; $i++) {
$secPwd = ConvertTo-SecureString $passwords[$i].password -AsPlainText -Force
Set-ADAccountPassword -Identity $userList[$i] -NewPassword $secPwd -Reset
Set-ADUser -Identity $userList[$i] -ChangePasswordAtLogon $true
}
Reset with Verification
$users = Import-Csv "reset.csv"
$results = @()
foreach ($user in $users) {
$secPwd = ConvertTo-SecureString $user.password -AsPlainText -Force
try {
Set-ADAccountPassword -Identity $user.sam -NewPassword $secPwd -Reset -ErrorAction Stop
Set-ADUser -Identity $user.sam -ChangePasswordAtLogon $true
$results += [PSCustomObject]@{User=$user.sam; Status="Success"; Time=Get-Date}
}
catch {
$results += [PSCustomObject]@{User=$user.sam; Status="Failed: $($_.Exception.Message)"; Time=Get-Date}
}
}
$results | Export-Csv "reset_results.csv" -NoTypeInformation
$results | Group-Object Status | Select-Object Name, Count
Common Errors and Fixes
| Error | Root Cause | Fix |
|---|---|---|
| "Cannot bind parameter 'NewPassword'. Cannot convert value to type System.Security.SecureString" | Passing a plaintext string instead of a SecureString | Use ConvertTo-SecureString "pwd" -AsPlainText -Force |
| "Access denied" | Missing reset-password permission | Delegate "Reset password" on the target OU, or run as domain admin |
| "The password does not meet the password policy requirements" | Generated password violates domain complexity/length rules | Use 20+ characters with all 4 character classes via the generator |
| "Cannot find an object with identity" | sAMAccountName doesn't exist | Verify with Get-ADUser "name". Check for typos or different naming convention |
| Password reset works but user can't log on | Account is disabled or ChangePasswordAtLogon wasn't set | Check Get-ADUser user -Properties Enabled, pwdLastSet. If pwdLastSet is 0, the force-change flag is on. If account is disabled, run Enable-ADAccount |
Pipeline Best Practices
- Generate first, reset second. Use the Instant Password Generator to create all passwords in one batch. Download the CSV, merge with your user list, then run Set-ADAccountPassword.
- Always use -WhatIf on the first run. Pipe your user list through
Set-ADAccountPassword -WhatIfto verify the cmdlet resolves every identity correctly before committing changes. - Log every reset. At minimum, capture which users were reset, at what time, and whether it succeeded. Use the verification script above.
- Delete the CSV after. The generated passwords are plaintext in your CSV. Once the reset completes successfully, delete the file or store it encrypted.
- Set a post-reset expiry. The template uses -ChangePasswordAtLogon $true, which effectively expires the generated password immediately. For service accounts, use a scheduled rotation instead — see the enterprise automation guide.
AD Password Management Series
- 📋 New-ADUser Bulk Creation with Generated Passwords — create users from scratch with unique passwords
- 🔁 Reset AD Passwords in Bulk from CSV with Force-Change-at-Logon — the companion guide for existing users
- 📋 Set-ADAccountPassword Cheat Sheet — you're here
- 🗂️ Bulk Password Generation for Windows AD — overview of the complete workflow
For teams managing passwords at scale, a shared credential manager keeps everything auditable and secure. NordPass Business integrates with Active Directory and provides access groups, activity logs, and breach monitoring across the organisation.
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.