トップ回答者
ローカルユーザの作成方法

質問
-
いつもお世話になっております。
非ドメイン環境下で、標準ユーザからローカルユーザの作成をしようと考えています。
以下の方法で試してみたのですが、標準ユーザから実行すると、UserPrincipal.Save()実行時にアクセスが拒否されましたと表示されてしまいます。
System.DirectoryServices.AccountManagement.PrincipalContext context = new System.DirectoryServices.AccountManagement.PrincipalContext(ContextType.Machine, null, null, ContextOptions.Negotiate, @"<ホスト名>\<管理者ユーザ名>", "<管理者パスワード>"); UserPrincipal localUser = new UserPrincipal(context); localUser.SamAccountName = "<新規ユーザ名>"; localUser.SetPassword("<新規パスワード>"); localUser.Save();
StackTrace:
場所 System.DirectoryServices.Interop.UnsafeNativeMethods.IAds.SetInfo()
場所 System.DirectoryServices.DirectoryEntry.CommitChanges()
場所 System.DirectoryServices.AccountManagement.SDSUtils.ApplyChangesToDirectory(Principal p, StoreCtx storeCtx, GroupMembershipUpdater updateGroupMembership, NetCred credentials, AuthenticationTypes authTypes)
場所 System.DirectoryServices.AccountManagement.SDSUtils.InsertPrincipal(Principal p, StoreCtx storeCtx, GroupMembershipUpdater updateGroupMembership, NetCred credentials, AuthenticationTypes authTypes, Boolean needToSetPassword)
場所 System.DirectoryServices.AccountManagement.SAMStoreCtx.Insert(Principal p)
場所 System.DirectoryServices.AccountManagement.Principal.Save()ご教授よろしくお願いいたします。
- 編集済み comm123 2017年3月8日 6:42
回答
-
どうしても実現したいのなら、アカウント作成権限のあるアカウントで Windows サービスを実行しておいて、そのサービスに通信してアカウントを作成させるという構造ですかね。
ただ、その Windows サービスは高い権限で実行されるので、相応に注意を払って設計・実装・検証しないと怖いですが…。なお、.NET のアプリは容易に逆コンパイルできるので、アカウントのパスワードをプログラムに埋めるのはやめておいた方が良いです。そのバイナリを入手した人が悪意を持てば、数分でパスワードを見れるので。
- 回答としてマーク comm123 2017年3月13日 14:46
すべての返信
-
下記のようなコードを管理者権限で起動させたところローカルユーザーを作成することができました。
using System; using System.DirectoryServices.AccountManagement; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { using (var context = new PrincipalContext(ContextType.Machine)) { using (var localUser = new UserPrincipal(context)) { localUser.SamAccountName = "<新規ユーザ名>"; localUser.SetPassword("<新規パスワード>"); localUser.Save(); using (var group = GroupPrincipal.FindByIdentity(context, "Users")) { group.Members.Add(localUser); group.Save(); } } } } } }
※System.DirectoryServices.AccountManagementの参照が必要。
参考になりますでしょうか?
- 編集済み kenjinoteMVP 2017年3月8日 8:29
-
どうしても実現したいのなら、アカウント作成権限のあるアカウントで Windows サービスを実行しておいて、そのサービスに通信してアカウントを作成させるという構造ですかね。
ただ、その Windows サービスは高い権限で実行されるので、相応に注意を払って設計・実装・検証しないと怖いですが…。なお、.NET のアプリは容易に逆コンパイルできるので、アカウントのパスワードをプログラムに埋めるのはやめておいた方が良いです。そのバイナリを入手した人が悪意を持てば、数分でパスワードを見れるので。
- 回答としてマーク comm123 2017年3月13日 14:46