none
ローカルユーザの作成方法 RRS feed

  • 質問

  • いつもお世話になっております。

    非ドメイン環境下で、標準ユーザからローカルユーザの作成をしようと考えています。

    以下の方法で試してみたのですが、標準ユーザから実行すると、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
    2017年3月8日 6:41

回答

  • 残念ながら標準ユーザーのままでは、新規ユーザーの作成はできないようです。
    UAC などで Administrator 権限に昇格するか、実行時のユーザーが Administrators グループのメンバーである必要があるようです。

    https://technet.microsoft.com/ja-jp/library/cc770642(v=ws.11).aspx

    • 回答としてマーク comm123 2017年3月8日 9:03
    2017年3月8日 8:50
  • どうしても実現したいのなら、アカウント作成権限のあるアカウントで Windows サービスを実行しておいて、そのサービスに通信してアカウントを作成させるという構造ですかね。
    ただ、その Windows サービスは高い権限で実行されるので、相応に注意を払って設計・実装・検証しないと怖いですが…。

    なお、.NET のアプリは容易に逆コンパイルできるので、アカウントのパスワードをプログラムに埋めるのはやめておいた方が良いです。そのバイナリを入手した人が悪意を持てば、数分でパスワードを見れるので。

    • 回答としてマーク comm123 2017年3月13日 14:46
    2017年3月8日 12:57
    モデレータ

すべての返信

  • 下記のようなコードを管理者権限で起動させたところローカルユーザーを作成することができました。

    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の参照が必要。

    参考になりますでしょうか?

    2017年3月8日 8:14
  • kenjinoteさん返信ありがとうございます。

    説明不足で申し訳ないです。標準ユーザの権限上で実行したかったです。

    管理者用のユーザ名とパスワードを記載しているので、標準ユーザから作成できるのかと思ったのですが、やはり、管理者権限が別途必要になってしまうのでしょうか?大変お手数ですが、他の方法で作成できるかご存知でしたらご教授いただきたいです。

    よろしくお願いいたします。



    • 編集済み comm123 2017年3月8日 8:35
    2017年3月8日 8:33
  • 残念ながら標準ユーザーのままでは、新規ユーザーの作成はできないようです。
    UAC などで Administrator 権限に昇格するか、実行時のユーザーが Administrators グループのメンバーである必要があるようです。

    https://technet.microsoft.com/ja-jp/library/cc770642(v=ws.11).aspx

    • 回答としてマーク comm123 2017年3月8日 9:03
    2017年3月8日 8:50
  • どうしても実現したいのなら、アカウント作成権限のあるアカウントで Windows サービスを実行しておいて、そのサービスに通信してアカウントを作成させるという構造ですかね。
    ただ、その Windows サービスは高い権限で実行されるので、相応に注意を払って設計・実装・検証しないと怖いですが…。

    なお、.NET のアプリは容易に逆コンパイルできるので、アカウントのパスワードをプログラムに埋めるのはやめておいた方が良いです。そのバイナリを入手した人が悪意を持てば、数分でパスワードを見れるので。

    • 回答としてマーク comm123 2017年3月13日 14:46
    2017年3月8日 12:57
    モデレータ