Come può un utente standard di Windows cambiare la propria password dalla riga di comando?


18

Su Windows Server 2008 R2, ho un utente locale standard (non amministratore) (non un account Active Directory, sebbene il server si trovi in ​​un dominio) che abbia accesso al server solo tramite PowerShell Remoting. L'utente non può accedere tramite RDP.

Vorrei che questo utente fosse in grado di cambiare la propria password. Il comando 'net user' richiede i diritti di amministratore, anche se l'utente sta cercando di cambiare la propria password.

Come può un utente standard cambiare la propria password dalla riga di comando?

Risposte:


18

Ecco un po 'di codice PowerShell per fare ciò che stai cercando con gli account di dominio:

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)

Il provider ASDI supporta anche la sintassi WinNT://computername/usernameper il ChangePassword()metodo. L' ADSystemInfooggetto, tuttavia, non funzionerà per gli account macchina-locali, quindi non è possibile modificare semplicemente il codice sopra con la WinNT://...sintassi.

(Qualcuno vuole suggerire una modifica con codice per distinguere tra account locali e di dominio?)

Su una virata completamente diversa, la vecchia NetUserChangePasswordAPI funzionerà anche con account locali (e di dominio, purché tu specifichi il nome di dominio nella sintassi NetBIOS):

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)

Questo codice presuppone che tu stia modificando una password sul computer locale (".").


1
Mi hai battuto, ma vinco per la conservazione dei personaggi;) Qualche motivo per cui sai che le parti extra che hai usato sono necessarie? O solo per essere più formale e corretto?
charleswj81,

1
Ottieni sicuramente il premio per il golf del codice. Sono solo formale e corretto ... In realtà, rende principalmente la sceneggiatura un po 'più utilizzabile per gli altri che potrebbero essere tipi taglia e incolla.
Evan Anderson,

1
@ charleswj81 - La risposta di Evan è molto più completa. È uno PS1script autonomo che può essere chiamato con o senza parametri. È anche molto più leggibile. Il codice riguarda gli umani che comprendono ciò che qualcun altro ha scritto, non il computer. Nessuna soluzione sarà più rapida dell'altra.
Mark Henderson

1
Sembra promettente, ma dovrei chiarire che l'account è locale per il sistema. Ho tentato quanto segue: ([ADSI]'WinNT://localhost/USERNAME').ChangePassword("OLDPASS", "NEWPASS") Ma quello ha restituito "La password non soddisfa i requisiti della politica della password ...". Tuttavia, la nuova password soddisfa tali requisiti.
elijahbuck,

1
In realtà, dopo aver aggiunto l'utente a "Utenti desktop remoto" e aver tentato di cambiare la password in questo modo, ottengo lo stesso errore. Credo che il modo corretto di cambiare un account locale sia: ([ADSI]'WinNT://localhost/USERNAME').ChangePassword("OLDPASS", "NEWPASS")
elijahbuck,

9

Questo è in realtà abbastanza semplice in PowerShell:

([ADSI]'LDAP://CN=User,CN=Users,DC=domain').ChangePassword('currentpassword','newpassword')

3

Ho provato entrambe le risposte sopra senza alcun risultato, per aver modificato la password di un amministratore locale che non è stato aggiunto al dominio. Scavare tra i commenti ha prodotto ciò di cui avevo bisogno.

Per la seconda parte della risposta attualmente accettata, si desidera aggiornare la firma da utilizzare longanziché il boolvalore restituito, e questi possono essere risolti nei documenti sui codici di errore di sistema . Quindi finisci con:

param (
    [string]$oldPassword = $( Read-Host "Old password"),
    [string]$newPassword = $( Read-Host "New password")
)

$MethodDefinition = @'
[DllImport("netapi32.dll", CharSet = CharSet.Unicode)]
public static extern **long** 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)

Tuttavia, ciò non ha funzionato per me. I codici di errore si sono alternati tra 86 e 2221, a seconda di come ho impostato i parametri. Stava per arrendersi e scavare di più nei commenti, e alla fine trovò successo nel fare:

([ADSI]'WinNT://./USERNAME').ChangePassword("OLDPASS‌​", "NEWPASS")

Assolutamente ridicolo che il semplice CAMBIAMENTO di una password dell'amministratore locale sia così complicato in Powershell. Se memorizzi tutti i sistemi di sicurezza sul tuo sistema, l'aggiornamento della password deve essere effettuato fornendo la vecchia password o rischi di perdere la capacità di decodificare correttamente quelle stringhe sicure!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.