Created
November 21, 2025 17:03
-
-
Save Cyr-Az/6a519812c867a39bcbbc75eac32b3f51 to your computer and use it in GitHub Desktop.
Changes the password of any local user account using its current password for verification without requiring administrator permissions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Function Set-LocalUserPassword | |
| { | |
| <# | |
| .SYNOPSIS | |
| Changes the password of any local user account using its current password for verification. | |
| .DESCRIPTION | |
| This function utilizes the System.DirectoryServices.AccountManagement .NET namespace to change a local user's password. | |
| Unlike the standard 'Set-LocalUser' cmdlet or 'net user' command, this function utilizes the 'ChangePassword' method. | |
| This allows standard (non-administrator) users to change the password of any local account provided they know its current password, similar to what can be achieved with Set-ADAccountPassword for Active Directory accounts. | |
| .PARAMETER Identity | |
| The SAMAccountName of the local user to modify. | |
| If omitted, the function will prompt for the username. | |
| If this prompt is left empty, it defaults to the currently logged-in user ($env:USERNAME). | |
| .PARAMETER OldPassword | |
| The current valid password for the account, passed as a SecureString. | |
| If omitted, the function will prompt the user to enter it securely via the host UI. | |
| .PARAMETER NewPassword | |
| The desired new password for the account, passed as a SecureString. | |
| If omitted, the function will prompt the user to enter it securely via the host UI. | |
| .EXAMPLE | |
| Set-LocalUserPassword -Identity "Bob" | |
| Description | |
| ----------- | |
| Attempts to change the password for local user "Bob". The function will interactively prompt for the Old and New passwords. | |
| .EXAMPLE | |
| Set-LocalUserPassword | |
| Description | |
| ----------- | |
| Prompts for the target username. If the user presses Enter without typing a name, it targets the current user. | |
| Then prompts for the Old and New passwords. | |
| .INPUTS | |
| System.String | |
| .OUTPUTS | |
| None | |
| .NOTES | |
| Requirements: .NET Framework 3.5 or later (System.DirectoryServices.AccountManagement) | |
| #> | |
| [CmdletBinding()] | |
| Param ( | |
| [Parameter(Mandatory = $false, Position = 0)] | |
| [String]$Identity, | |
| [Parameter(Mandatory = $false)] | |
| [securestring]$OldPassword, | |
| [Parameter(Mandatory = $false)] | |
| [securestring]$NewPassword | |
| ) | |
| #Load Assembly (requires .NET 3.5) | |
| Add-Type -AssemblyName System.DirectoryServices.AccountManagement | |
| try | |
| { | |
| #Handle Missing Identity Input | |
| if ([string]::IsNullOrWhiteSpace($Identity)) | |
| { | |
| $Identity = Read-Host -Prompt "Enter local username (Leave empty for current user)" | |
| if ([string]::IsNullOrWhiteSpace($Identity)) | |
| { | |
| $Identity = $env:USERNAME | |
| } | |
| } | |
| Write-Verbose "Connecting to Local Machine Context..." | |
| $PrincipalContext = [System.DirectoryServices.AccountManagement.PrincipalContext]::new("Machine") | |
| Write-Verbose "Looking up user: $Identity" | |
| $User = [System.DirectoryServices.AccountManagement.UserPrincipal]::FindByIdentity($PrincipalContext, $Identity) | |
| if ($null -eq $User) | |
| { | |
| throw "User '$Identity' could not be found on this computer." | |
| } | |
| if (-not $OldPassword) | |
| { | |
| $OldPassword = Read-Host -Prompt "Enter OLD password for $Identity" -AsSecureString | |
| } | |
| if (-not $NewPassword) | |
| { | |
| $NewPassword = Read-Host -Prompt "Enter NEW password for $Identity" -AsSecureString | |
| } | |
| # Convert SecureString to PlainText as this is what ChangePassword() method requires | |
| $OldPassPlain = [System.Net.NetworkCredential]::new("", $OldPassword).Password | |
| $NewPassPlain = [System.Net.NetworkCredential]::new("", $NewPassword).Password | |
| $User.ChangePassword($OldPassPlain, $NewPassPlain) | |
| Write-Host "Password successfully changed for user: $Identity" -ForegroundColor Green | |
| } | |
| catch | |
| { | |
| Write-Error $_.Exception.Message | |
| throw | |
| } | |
| finally | |
| { | |
| # Clean up unmanaged COM resources and plain text secret variables | |
| if ($null -ne $User) { $User.Dispose() } | |
| if ($null -ne $PrincipalContext) { $PrincipalContext.Dispose() } | |
| $OldPassPlain = $null | |
| $NewPassPlain = $null | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment