Wie kann ein Windows-Standardbenutzer sein Kennwort über die Befehlszeile ändern?

18

Unter Windows Server 2008 R2 habe ich einen lokalen Standardbenutzer (kein Administrator) (kein Active Directory-Konto, obwohl sich der Server in einer Domäne befindet), der nur über PowerShell Remoting auf den Server zugreifen kann. Der Benutzer kann sich nicht über RDP anmelden.

Ich möchte, dass dieser Benutzer sein Passwort ändern kann. Der Befehl 'net user' erfordert Administratorrechte, auch wenn der Benutzer versucht, sein eigenes Passwort zu ändern.

Wie kann ein Standardbenutzer sein Kennwort über die Befehlszeile ändern?

Elijahbuck
quelle

Antworten:

18

Im Folgenden finden Sie einen PowerShell-Code, mit dem Sie das tun können, wonach Sie suchen:

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)

Der ASDI-Provider unterstützt auch die Syntax WinNT://computername/usernamefür die ChangePassword()Methode. Das ADSystemInfoObjekt funktioniert jedoch nicht für maschinenlokale Konten. Daher kann der obige Code nicht mit der WinNT://...Syntax nachgerüstet werden .

(Möchte jemand eine Bearbeitung mit Code vorschlagen, um zwischen lokalen und Domain-Konten zu unterscheiden?)

Bei einem völlig anderen Ansatz NetUserChangePasswordfunktioniert die alte API auch mit lokalen (und Domänen-) Konten, sofern Sie den Domänennamen in der NetBIOS-Syntax angeben:

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)

Dieser Code setzt voraus, dass Sie ein Kennwort auf dem lokalen Computer ändern (".").

Evan Anderson
quelle
1
Du hast mich geschlagen, aber ich gewinne für die Erhaltung der Charaktere;) Weißt du aus irgendeinem Grund, dass die zusätzlichen Teile, die du benutzt hast, notwendig sind? Oder nur, um formeller und angemessener zu sein?
Charleswj81
1
Sie erhalten definitiv den Code Golf Award. Ich bin einfach nur formell und ordentlich ... Eigentlich ist es hauptsächlich so, dass das Skript für andere, die vielleicht vom Typ "Ausschneiden und Einfügen" sind, ein wenig benutzerfreundlicher wird.
Evan Anderson
1
@ charleswj81 - Evans Antwort ist viel vollständiger. Es ist ein eigenständiges PS1Skript, das mit oder ohne Parameter aufgerufen werden kann. Es ist auch viel besser lesbar. Bei Code geht es darum, dass Menschen verstehen, was jemand anderes geschrieben hat, nicht den Computer. Keine Lösung ist schneller als die andere.
Mark Henderson
1
Das sieht vielversprechend aus, aber ich sollte klarstellen, dass das Konto für das System lokal ist. Ich habe Folgendes versucht: ([ADSI]'WinNT://localhost/USERNAME').ChangePassword("OLDPASS", "NEWPASS") Es wurde jedoch "Das Kennwort entspricht nicht den Anforderungen der Kennwortrichtlinie ..." zurückgegeben. Das neue Passwort erfüllt jedoch diese Anforderungen.
Elijahbuck
1
Nach dem Hinzufügen des Benutzers zu "Remotedesktopbenutzern" und dem Versuch, das Kennwort auf diese Weise zu ändern, wird derselbe Fehler angezeigt. Ich glaube, der richtige Weg, um ein lokales Konto zu ändern, ist: ([ADSI]'WinNT://localhost/USERNAME').ChangePassword("OLDPASS", "NEWPASS")
Elijahbuck
9

In PowerShell ist das eigentlich ganz einfach:

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

Ich habe beide oben genannten Antworten ohne Erfolg versucht, um das Kennwort eines lokalen Administrators zu ändern, der nicht der Domäne angehört. Das Durchsuchen der Kommentare ergab jedoch das, was ich brauchte.

Für den zweiten Teil der aktuell akzeptierten Antwort möchten Sie die Signatur so aktualisieren, dass sie longanstelle des boolRückgabewerts verwendet wird, und diese können in den Dokumenten mit den Systemfehlercodes behoben werden . So endest du mit:

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)

Das hat aber bei mir nicht geklappt. Die Fehlercodes wechselten zwischen 86 und 2221, je nachdem, wie ich die Parameter einrichte. Ich wollte aufgeben und mich mehr mit den Kommentaren befassen und fand schließlich Erfolg darin, Folgendes zu tun:

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

Absolut lächerlich, dass das einfache ÄNDERN eines lokalen Administratorkennworts in Powershell so kompliziert ist. Wenn Sie auf Ihrem System Sicherheitszeichenfolgen speichern, muss das Kennwort mit dem alten Kennwort aktualisiert werden. Andernfalls besteht die Gefahr, dass Sie die Möglichkeit verlieren, diese Sicherheitszeichenfolgen ordnungsgemäß zu entschlüsseln.

gnalck
quelle