Як звичайний користувач Windows може змінити свій пароль з командного рядка?


18

У Windows Server 2008 R2 у мене є стандартний локальний користувач (не адміністратор) (не обліковий запис Active Directory, хоча сервер знаходиться в домені), який має доступ до сервера лише за допомогою PowerShell Remoting. Користувач не може увійти через RDP.

Я хотів би, щоб цей користувач міг змінити свій пароль. Команда 'net user' вимагає прав адміністратора, навіть якщо користувач намагається змінити свій власний пароль.

Як звичайний користувач може змінити свій пароль з командного рядка?

Відповіді:


18

Ось код PowerShell для того, щоб робити те, що ви шукаєте, з обліковими записами домену:

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)

Провайдер ASDI також підтримує синтаксис WinNT://computername/usernameдля ChangePassword()методу. ADSystemInfoОб'єкт, однак, не буде працювати для машин локальних рахунків, так що просто дооснащення коду вище WinNT://...синтаксис не працездатний.

(Хтось хоче запропонувати змінити w / код для розмежування між локальними та доменними обліковими записами?)

У зовсім іншому варіанті старий NetUserChangePasswordAPI також буде працювати з локальними (і доменними, за умови, що ви вкажете ім'я домену в синтаксисі 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)

Цей код передбачає, що ви змінюєте пароль на локальній машині (".").


1
Ти мене перемагаєш, але я перемагаю за збереження персонажів;) Будь-яка причина, що ти знаєш про те, що потрібні додаткові частини, які ти використовував? Або просто бути більш формальним і правильним?
charleswj81

1
Ви точно отримаєте нагороду з кодом за гольф. Я просто офіційний і належний ... Насправді, це в основному робить сценарій трохи більш корисним для інших, які можуть бути типовими для вирізання та вставки.
Еван Андерсон

1
@ charleswj81 - відповідь Евана набагато повніше. Це окремий PS1сценарій, який можна викликати з параметрами або без них. Це також набагато читабельніше. Код - це те, щоб люди розуміли, що хтось ще написав, а не комп’ютер. Жодне рішення не буде швидшим, ніж інше.
Марк Хендерсон

1
Це виглядає перспективно, але я повинен уточнити, що обліковий запис є локальним для системи. Я спробував наступне: ([ADSI]'WinNT://localhost/USERNAME').ChangePassword("OLDPASS", "NEWPASS") Але це повернуло "Пароль не відповідає вимогам політики щодо паролів ...". Новий пароль все ж відповідає цим вимогам.
elijahbuck

1
Насправді, додавши користувача до «Користувачів віддаленого робочого столу» та намагаючись змінити пароль таким чином, я отримую ту ж помилку. Я вважаю, що правильний спосіб змінити локальний рахунок: ([ADSI]'WinNT://localhost/USERNAME').ChangePassword("OLDPASS", "NEWPASS")
elijahbuck,

9

Це насправді досить просто в PowerShell:

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

3

Я намагався обидві відповіді вище, безрезультатно, для зміни пароля місцевого адміністратора, який не приєднався до домену. Копати коментарі дало те, що мені було потрібно.

У другій частині прийнятої на даний момент відповіді потрібно оновити підпис, щоб використовувати longзамість boolзворотного значення, і це може бути усунено неполадки в документах із системними кодами помилок . Отже, ви закінчуєте:

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)

Однак це не спрацювало для мене. Коди помилок чергувались між 86 і 2221, залежно від того, як я встановив параметри. Збирався відмовитись і більше заглиблювався в коментарі, і нарешті знайшов успіх у цьому:

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

Абсолютно смішно, що проста зміна локального пароля адміністратора настільки складна в Powershell. Якщо ви взагалі зберігаєте захисні рядки у вашій системі, то оновлення пароля потрібно проводити, надаючи старий пароль, або ризикуєте втратити здатність правильно розшифрувати ці безпечні рядки!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.