web-dev-qa-db-ja.com

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

Windows Server 2008 R2では、PowerShell Remoting経由でのみサーバーにアクセスできる標準の(管理者以外の)ローカルユーザー(サーバーはドメイン内にありますが、Active Directoryアカウントではありません)を持っています。ユーザーはRDP経由でログインできません。

このユーザーが自分のパスワードを変更できるようにしたいと考えています。 'Net User'コマンドには、ユーザーが自分のパスワードを変更しようとしている場合でも、管理者権限が必要です。

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

18
elijahbuck

ドメインアカウントで探していることを実行するための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プロバイダーは、ChangePassword()メソッドの構文_WinNT://computername/username_もサポートしています。ただし、ADSystemInfoオブジェクトはマシンローカルアカウントでは機能しないため、上記のコードを_WinNT://..._構文で改造するだけでは機能しません。

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

まったく異なる方法で、古いNetUserChangePassword AP​​Iはローカル(およびドメイン、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)
_

このコードは、ローカルマシン( "。")のパスワードを変更していることを前提としています。

18
Evan Anderson

これは、実際にはPowerShellではかなり単純です。

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

ドメインに参加していないローカル管理者のパスワードを変更するため、上記の両方の回答を試してみましたが、役に立ちませんでした。コメントを掘り下げてみると、私は必要なものを見つけました。

現在受け入れられている回答の2番目の部分では、longの戻り値ではなくboolを使用するように署名を更新する必要があります。これらは システムエラーコードでトラブルシューティングできます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では、ローカル管理者パスワードの単純な変更が非常に複雑であることは絶対にばかげています。システムにセキュアストリングを保管する場合、パスワードの更新は古いパスワードを指定して行う必要があります。そうしないと、これらのセキュアストリングを適切に復号化できなくなる可能性があります。

3
gnalck