= Change Expired AD Password =
**Summary**: How to change your own expired password when you can’t login to RDP. \\
**Date**: Around 2022 \\
**Refactor**: 21 February 2025: Checked links and formatting. \\
{{tag>ad powershell desktop}}
I often have multiple accounts to keep track of, with various password policies. Sometimes a password just expires and I don't want to bother support staff to reset it to a temporary password which I have to reset then again. It's a lot of hassle. To prevent that, I became a big fan of the PowerShell function below. All credits go to [[https://evotec.xyz/how-to-change-your-own-expired-password-when-you-cant-login-to-rdp/ |Evotec]], but I've used it a lot. If you're on a personal system, you could just simply do:
Install-Module PSSharedGoods -Force
Set-PasswordRemotely
But if you're on a server system without internet access or do not want to install form unknown sources you could simply paste the function into your powershell session and then run the function:
function Set-PasswordRemotely {
[CmdletBinding(DefaultParameterSetName = 'Secure')]
param(
[Parameter(ParameterSetName = 'Secure', Mandatory)][string] $UserName,
[Parameter(ParameterSetName = 'Secure', Mandatory)][securestring] $OldPassword,
[Parameter(ParameterSetName = 'Secure', Mandatory)][securestring] $NewPassword,
[Parameter(ParameterSetName = 'Secure')][alias('DC', 'Server', 'ComputerName')][string] $DomainController
)
Begin {
$DllImport = @'
[DllImport("netapi32.dll", CharSet = CharSet.Unicode)]
public static extern bool NetUserChangePassword(string domain, string username, string oldpassword, string newpassword);
'@
$NetApi32 = Add-Type -MemberDefinition $DllImport -Name 'NetApi32' -Namespace 'Win32' -PassThru
if (-not $DomainController) {
if ($env:computername -eq $env:userdomain) {
# not joined to domain, lets prompt for DC
$DomainController = Read-Host -Prompt 'Domain Controller DNS name or IP Address'
} else {
$Domain = $Env:USERDNSDOMAIN
$Context = [System.DirectoryServices.ActiveDirectory.DirectoryContext]::new([System.DirectoryServices.ActiveDirectory.DirectoryContextType]::Domain, $Domain)
$DomainController = ([System.DirectoryServices.ActiveDirectory.DomainController]::FindOne($Context)).Name
}
}
}
Process {
if ($DomainController -and $OldPassword -and $NewPassword -and $UserName) {
$OldPasswordPlain = [System.Net.NetworkCredential]::new([string]::Empty, $OldPassword).Password
$NewPasswordPlain = [System.Net.NetworkCredential]::new([string]::Empty, $NewPassword).Password
$result = $NetApi32::NetUserChangePassword($DomainController, $UserName, $OldPasswordPlain, $NewPasswordPlain)
if ($result) {
Write-Host -Object "Set-PasswordRemotely - Password change for account $UserName failed on $DomainController. Please try again." -ForegroundColor Red
} else {
Write-Host -Object "Set-PasswordRemotely - Password change for account $UserName succeeded on $DomainController." -ForegroundColor Cyan
}
} else {
Write-Warning "Set-PasswordRemotely - Password change for account failed. All parameters are required. "
}
}
}
Set-PasswordRemotely