標準のWindowsユーザーがコマンドラインからパスワードを変更するにはどうすればよいですか?


18

Windows Server 2008 R2には、PowerShell Remotingを介してのみサーバーにアクセスできる標準(管理者ではない)ローカルユーザー(サーバーはドメイン内にありますが、Active Directoryアカウントではありません)があります。ユーザーは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://...は機能しないため、上記のコードに構文を追加するだけでは機能しません。

(ローカルアカウントとドメインアカウントを区別するためのコード付き編集を提案したい人はいますか?)

完全に異なる方法で、古い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 14年

1
あなたは間違いなくコードゴルフ賞を受賞しています。私はただフォーマルで適切なだけです...実際、それは主に、カットアンドペーストタイプである可能性のある他の人にとってスクリプトをもう少し使いやすくします。
エヴァンアンダーソン14年

1
@ charleswj81-エヴァンの答えはもっと完全です。これは、PS1パラメーター付きまたはパラメーターなしで呼び出すことができるスタンドアロンスクリプトです。読みやすくなっています。コードとは、コンピューターではなく、人間が他の誰かが書いたことを理解することです。どちらのソリューションも他のソリューションよりも高速ではありません。
マークヘンダーソン

1
これは有望に見えますが、アカウントがシステムに対してローカルであることを明確にする必要があります。私は次のことを試みました: ([ADSI]'WinNT://localhost/USERNAME').ChangePassword("OLDPASS", "NEWPASS") しかし、それは「パスワードはパスワードポリシー要件を満たしていません...」を返しました。ただし、新しいパスワードはこれらの要件を満たします。
エリヤバック

1
実際、ユーザーを「リモートデスクトップユーザー」に追加し、その方法でパスワードを変更しようとすると、同じエラーが発生します。:私は、ローカルアカウントを変更するための正しい方法であると信じている ([ADSI]'WinNT://localhost/USERNAME').ChangePassword("OLDPASS", "NEWPASS")
elijahbuckは

9

PowerShellでは、これは実際には非常に簡単です。

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

3

ドメインに参加していないローカル管理者のパスワードを変更するために、上記の両方の回答を無効にしました。コメントを掘り下げると、必要なものが得られました。

現在受け入れられている回答の2番目の部分についてはlongbool戻り値の代わりに使用する署名を更新する必要があります。これらは、次の場所でトラブルシューティングできます。はシステムエラーコードdocs。したがって、次のようになります。

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では、ローカル管理者パスワードの単純な変更が非常に複雑であることは絶対にばかげています。システムにセキュアストリングを保存する場合、古いパスワードを指定してパスワードを更新する必要があります。そうしないと、これらのセキュアストリングを適切に復号化する能力を失う危険があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.