The error Exception calling "ChangePassword" with "2" argument(s): "The specified network password is not correct.
is due to the symobls in your password. For example, if you have "$" in your password, PoweShell takes it as a variable.
In PowerShell, the dollar sign $ is used to reference variables. When you have a password with a dollar sign, PowerShell might interpret it as a variable and try to replace it with the value of the variable, leading to unexpected behavior.
To prevent PowerShell from interpreting the dollar sign as a variable, you can use single quotes (') instead of double quotes (") when defining the password in the script. Single quotes prevent variable expansion, and the dollar sign will be treated as a literal character.
In your case you need to read the password in a secure string and then convert it to plaintext to set the password like below:
$username = Read-Host -Prompt "Enter the AD user's username"
$domainController = "foo.example.local" #You can also provide IP of DC
$currentPassword = Read-Host -Prompt "Enter the current password" -AsSecureString
# Convert the secure string for current password to plain text
$plainCurrentPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($currentPassword))
$newPassword = Read-Host -Prompt "Enter the new password" -AsSecureString
# Convert the secure strings to plain text
$plainNewPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($newPassword))
[ADSI]$useraccount="WinNT://$domainController/$username"
$useraccount.ChangePassword($plainCurrentPassword, $plainNewPassword)
Or in a simple way to understand how it works with plain text see below (not recommended as it stores your password as text):
$user.ChangePassword('$abcd1234', '$qwerty1234')