How to Change Local User Password via Command Line Without Admin Rights on Windows Server 2008 R2


2 views

When managing Windows Server 2008 R2 environments, standard users often need to change their local passwords remotely without administrative privileges. The traditional net user command fails in this scenario due to permission restrictions, particularly when using PowerShell Remoting as the sole access method.

The Windows Management Instrumentation Command-line (WMIC) utility provides a way for standard users to change their own passwords without elevation:


wmic useraccount where name='username' call setpassword 'newpassword'

However, this method has limitations on domain-joined machines and may not work consistently across all Windows Server 2008 R2 installations.

A more reliable approach uses PowerShell's System.DirectoryServices.AccountManagement namespace:


Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$context = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::Machine)
$user = [System.DirectoryServices.AccountManagement.UserPrincipal]::FindByIdentity($context, $env:USERNAME)
$user.ChangePassword("oldpassword", "newpassword")
$user.Save()
  • Password policies still apply (complexity requirements, minimum age)
  • The PowerShell method requires .NET Framework 3.5 or later
  • For domain accounts, modify the ContextType parameter to Domain
  • These methods work over PowerShell Remoting (WinRM)

Here's a robust PowerShell script with proper error handling:


try {
    Add-Type -AssemblyName System.DirectoryServices.AccountManagement -ErrorAction Stop
    $context = New-Object System.DirectoryServices.AccountManagement.PrincipalContext(
        [System.DirectoryServices.AccountManagement.ContextType]::Machine)
    
    $user = [System.DirectoryServices.AccountManagement.UserPrincipal]::FindByIdentity(
        $context, $env:USERNAME)
    
    if($user.ChangePassword($oldPass, $newPass)) {
        $user.Save()
        Write-Output "Password changed successfully"
    } else {
        Write-Error "Password change failed"
    }
}
catch {
    Write-Error ("Password change error: {0}" -f $_.Exception.Message)
}

When working with Windows Server 2008 R2 in domain environments, we often encounter scenarios where standard users need to change their local passwords through PowerShell Remoting without administrative privileges. The traditional net user approach fails because:

  • Requires local admin rights even for self-service password changes
  • Blocked by UAC elevation prompts in remote sessions
  • Lacks granular permission controls

The Windows Management Instrumentation Command-line (WMIC) provides a workaround that respects standard user permissions:

wmic useraccount where "name='USERNAME'" call setpassword "OLDPASSWORD","NEWPASSWORD"

Implementation example:

$cred = Get-Credential
wmic useraccount where "name='$($cred.UserName)'" call setpassword "$($cred.GetNetworkCredential().Password)","NewP@ssw0rd123"

When executing via PowerShell Remoting (WinRM), these adjustments are necessary:

Invoke-Command -ComputerName Server01 -ScriptBlock {
    param($user,$oldPass,$newPass)
    wmic useraccount where "name='$user'" call setpassword "$oldPass","$newPass"
} -ArgumentList $username,$currentPassword,$newPassword

Important security notes when implementing this solution:

  • Password transmission should occur over encrypted WinRM sessions
  • Consider implementing Just Enough Administration (JEA) constraints
  • Audit password change events in Security logs (Event ID 4723)

For environments where WMIC is restricted:

1. Scheduled Task Workaround:

# Requires one-time admin setup
$action = New-ScheduledTaskAction -Execute 'net.exe' -Argument "user $env:USERNAME NewP@ssword123"
Register-ScheduledTask -TaskName "UserPasswordReset" -Action $action -User $env:USERNAME

2. ADSI Method (for local accounts):

$user = [ADSI]"WinNT://localhost/$env:USERNAME"
$user.ChangePassword("oldPass", "newPass")