Here's some PowerShell code to do what you're looking for with domain accounts:
param (
[string]$oldPassword = $( Read-Host "Old password"),
[string]$newPassword = $( Read-Host "New password")
)
$ADSystemInfo = New-Object -ComObject ADSystemInfo
$type = $ADSystemInfo.GetType()
$user = [ADSI] "LDAP://$($type.InvokeMember('UserName', 'GetProperty', $null, $ADSystemInfo, $null))"
$user.ChangePassword( $oldPassword, $newPassword)
The ASDI provider also supports the syntax WinNT://computername/username
for the ChangePassword()
method. The ADSystemInfo
object, however, won't work for machine-local accounts, so just retrofitting the code above with WinNT://...
syntax isn't workable.
(Anybody want to suggest an edit w/ code to differentiate between local and domain accounts?)
On a completely different tack, the old NetUserChangePassword
API will work with local (and domain, provided you specify the domain name in NetBIOS syntax) accounts, too:
param (
[string]$oldPassword = $( Read-Host "Old password"),
[string]$newPassword = $( Read-Host "New password")
)
$MethodDefinition = @'
[DllImport("netapi32.dll", CharSet = CharSet.Unicode)]
public static extern bool NetUserChangePassword(string domainname, string username, string oldPassword, string newPassword);
'@
$NetAPI32 = Add-Type -MemberDefinition $MethodDefinition -Name 'NetAPI32' -Namespace 'Win32' -PassThru
$NetAPI32::NetUserChangePassword('.', $env:username, $oldPassword, $newPassword)
This code assumes you're changing a password on the local machine (".").