Shore Up
A single locked mailbox on a wall of pigeonholes being opened with a fresh key, the old key set aside.
WindowsSecurity

Reset an Active Directory User Password with PowerShell

Ketan Aagja8 min read

Before you run this

This guide resets the password on one Active Directory user account, and optionally unlocks the account and forces the user to change the password at next logon. That is the entire scope: a targeted, single-user reset — the kind of thing you do a dozen times a week at a help desk.

Privileges. This needs the ActiveDirectory PowerShell module (part of RSAT on a workstation, or already present on a Domain Controller) and an account with delegated permission to reset passwords in the target OU. A standard help-desk delegation is enough; you do not need Domain Admin for a routine reset. Run PowerShell as a user who holds that delegation — if your everyday account is not delegated, start the session with runas under one that is.

Test first. Read the commands before you paste them. Do this against a test account in a lab or non-production OU the first time so you can watch each step behave, before you ever run it on a real person's account. Create a throwaway user, reset that, confirm it, and only then use the procedure for real.

What it changes, and what you can't undo. Resetting a password overwrites the old one — AD does not store the previous plaintext, so there is no "restore the old password." If you reset the wrong account, the only fix is to set a new known password on it again and tell that user. Unlocking an account and setting the change-at-logon flag are both trivially reversible; the password overwrite is not. Treat the -Identity value with the same care you'd treat a Remove- command.

Assumptions

I'm assuming:

  • Windows 10/11 or Windows Server with RSAT / the ActiveDirectory module installed, or you're running this on a Domain Controller.
  • Windows PowerShell 5.1 (the shell that ships with Windows). The commands here also work in PowerShell 7 as long as the ActiveDirectory module is available.
  • A domain like example.com. Replace every placeholder — the username jdoe, the domain, the OU — with your real values.

Check the module is loaded:

# Confirms the ActiveDirectory cmdlets are available in this session
Get-Module -ListAvailable ActiveDirectory
Import-Module ActiveDirectory

If Get-Module -ListAvailable returns nothing, RSAT isn't installed. On Windows 10/11 that's Settings → Optional features → RSAT: Active Directory Domain Services and Lightweight Directory Services Tools, or via Add-WindowsCapability. On a DC the module is already there.

Find the account first

Before you change anything, confirm you're pointing at the right person. Never reset a password from memory of a samAccountName — look it up and eyeball the result.

# Confirm you have the correct account before touching it
Get-ADUser -Identity "jdoe" -Properties DisplayName, Enabled, LockedOut, PasswordLastSet |
    Format-List Name, SamAccountName, DisplayName, Enabled, LockedOut, PasswordLastSet

If you only know the person's name, search instead:

# Find candidates by display name when you don't know the logon name
Get-ADUser -Filter "Name -like '*Doe*'" -Properties DisplayName |
    Select-Object Name, SamAccountName, DisplayName

Note the exact SamAccountName from the output. That's what you'll pass to -Identity in the next step.

Reset the password

The cmdlet is Set-ADAccountPassword with -Reset. -Reset is what an administrator uses to set a new password without knowing the old one (as opposed to a user changing their own, which needs -OldPassword).

The password has to be a SecureString. I'll prompt for it interactively with Read-Host -AsSecureString so the new password is never sitting in your command history or in a script file:

# Prompt for the new password without echoing it or storing it in history
$NewPassword = Read-Host "Enter new password" -AsSecureString

# Reset the password on the target account
Set-ADAccountPassword -Identity "jdoe" -Reset -NewPassword $NewPassword

If the new password doesn't meet the domain's complexity, length, or history policy, Set-ADAccountPassword will throw an error and make no change — read the error, pick a compliant password, and run it again.

Force a change at next logon (recommended)

For a help-desk reset you almost always want the user to set their own password the first time they log in, so you don't know their password going forward:

# User must set a new password at their next sign-in
Set-ADUser -Identity "jdoe" -ChangePasswordAtLogon $true

If instead you need the password to persist as-is (a service account you're setting deliberately, say), leave that flag alone or set it to $false.

Unlock the account if it's locked

A password reset does not by itself clear a lockout from too many bad attempts. If the earlier Get-ADUser showed LockedOut : True, unlock it:

# Clears an account lockout; harmless to run if it wasn't locked
Unlock-ADAccount -Identity "jdoe"

Unlock-ADAccount is safe to run against an account that isn't locked — it simply does nothing.

A small safe-by-default wrapper

If you do this often, wrap the three steps so you always confirm the target first. This shows you who you're about to reset and makes you type yes before it proceeds:

function Reset-UserPassword {
    param(
        [Parameter(Mandatory)]
        [string]$SamAccountName
    )

    # Show the account so you can confirm it's the right one
    $user = Get-ADUser -Identity $SamAccountName -Properties DisplayName, LockedOut
    Write-Host "About to reset:" $user.DisplayName "(" $user.SamAccountName ")" -ForegroundColor Yellow

    if ((Read-Host "Type 'yes' to continue") -ne 'yes') {
        Write-Host "Cancelled." ; return
    }

    $pw = Read-Host "New password" -AsSecureString
    Set-ADAccountPassword -Identity $SamAccountName -Reset -NewPassword $pw
    Set-ADUser         -Identity $SamAccountName -ChangePasswordAtLogon $true
    Unlock-ADAccount   -Identity $SamAccountName   # no-op if not locked

    Write-Host "Done." -ForegroundColor Green
}

# Usage:
# Reset-UserPassword -SamAccountName "jdoe"

This is deliberately plain: no bulk loops, no reading names from a CSV. Password resets are one of those jobs where operating on a single, confirmed target is the whole point.

Verify it worked

Check that PasswordLastSet is now current and the account is unlocked:

# PasswordLastSet should show the current date/time; LockedOut should be False
Get-ADUser -Identity "jdoe" -Properties PasswordLastSet, LockedOut, Enabled |
    Format-List Name, PasswordLastSet, LockedOut, Enabled

A PasswordLastSet timestamp from the last minute confirms the reset landed. If you set the change-at-logon flag, the user will be prompted at their next sign-in; you can confirm the flag through Get-ADUser by requesting the pwdLastSet attribute (a value of 0 there indicates "must change at next logon").

One caveat in multi-DC environments: your change was written to whichever DC you're talking to and needs to replicate to the others. If the user logs in against a different DC seconds later and sees the old password, give replication a moment. You can force it for a site with repadmin /syncall, but normal replication catches up on its own.

Undoing it

There's no rollback for the password value itself — AD keeps only the current hash. If you reset the wrong account, the remedy is to set a fresh known password on it again (same commands) and notify the user.

The two side effects are reversible:

# Undo the change-at-logon requirement
Set-ADUser -Identity "jdoe" -ChangePasswordAtLogon $false

There's no "re-lock" command, and you wouldn't want one — an unlocked account isn't a problem to reverse.

For exact parameter details, see Microsoft Learn for Set-ADAccountPassword, Set-ADUser, and Unlock-ADAccount. Those pages are the authoritative reference if your environment does anything unusual with fine-grained password policies.

Reset an Active Directory User Password with PowerShell