Добавление локального пользователя в локальную группу администратора

Я пишу программу С#, которая будет вытеснена из лабораторий, в которых я работаю. Программа предназначена для создания локальной учетной записи администратора (itadmin), установки пароля, установки пароля, который никогда не истекает, и добавления учетной записи к локальной Группа администраторов. Программа создает новую учетную запись пользователя и устанавливает все правильно, но когда она пытается добавить ее в группу администратора, я получаю исключение, исключающее исключение. В первую очередь, правильно ли добавлена ​​группа? Что мне не хватает?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.DirectoryServices;

namespace CreateITAdmin
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                string userName = "itadmin";
                string userPassword = "password";

                Console.WriteLine("Building System Information");
                DirectoryEntry localMachine = new DirectoryEntry("WinNT://.,computer");
                DirectoryEntry newUser = localMachine.Children.Add(userName, "user");
                DirectoryEntry admGroup = new DirectoryEntry("WinNT://./Administrators,group");

                Console.WriteLine("Building User Information");
                newUser.Properties["FullName"].Value = "IT Administrative User";
                newUser.Invoke("Put", new object[] { "UserFlags", 0x10000 });

                Console.WriteLine("Setting User Password");
                newUser.Invoke("SetPassword", new object[] { userPassword });

                newUser.CommitChanges();

                Console.WriteLine("Adding itadmin to Administrators Group");
                admGroup.Invoke("Add", "WinNT://./" + newUser);

                Console.WriteLine("Cleaning Up");
                localMachine.Close();
                newUser.Close();
                admGroup.Close();
            }
            catch (System.DirectoryServices.DirectoryServicesCOMException E)
            {
                Console.WriteLine(E.Message.ToString());
                Console.ReadLine();
            }
            catch (System.Runtime.InteropServices.COMException E)
            {
                Console.WriteLine(E.Message.ToString());
                Console.ReadLine();
            }
            catch (System.Reflection.TargetInvocationException E)
            {
                Console.WriteLine(E.Message.ToString());
                Console.ReadLine();
            }
            catch (Exception E)
            {
                Console.WriteLine(E.Message.ToString());
                Console.ReadLine();
            }

            Console.WriteLine();
            Console.WriteLine("Press Any Key to Continue");
            Console.ReadLine();
            return;
        }
    }
}

Вывод кода ниже:

Building System Information
Building User Information
Setting User Password
Adding itadmin to Administrators Group
Exception has been thrown by the target of an invocation.

Любое понимание было бы значительно оценено.

ОБНОВЛЕНИЕ 1: С помощью @Grumbler85 исключение указано ниже:

System.Reflection.TargetInvocationException: Exception has been thrown by the target 
of an invocation. ---> System.Runtime.InteropServices.COMException: A member could not
be added to or removed from the local group because the member does not exist. --- End
of inner exception stacktrace --- at System.DirectoryServices.DirectoryEntry.Invoke
(String methodName,Object[]args) at CreateITAdmin.Program.Main(String[]args)in 
H:\code\CS\CreateITAdmin\CreateITAdmin\Program.cs:line 37

Также с помощью @Grumbler85 я работал над обновлением использования библиотеки в System.DirectoryServices.AccountManagement. Кажется, это намного проще и намного более прямолинейно в использовании. Дополнительные обновления/детали появятся по мере продвижения.

Обновление 2: Я знаю, что это быстрое продолжение, но я смог завершить обновление до нового пространства имен. После небольшой икоты с определением машины я смог успешно создать пользователя, установить пароль, обновить пароль, который не истекает, и добавить пользователя в группу администраторов. Спасибо @Grumbler85 за обновление для нового пространства имен. Новый код ниже:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;

namespace CreateITAdmin
{
    class Program
    {
        static void Main(string[] args)
        {
            string userName = "itadmin";
            string userPassword = "IT-Engineering1";
            PrincipalContext systemContext = null;

            try
            {
                Console.WriteLine("Building System Information");
                systemContext = new PrincipalContext(ContextType.Machine, null);
            }
            catch (Exception E)
            {
                Console.WriteLine("Failed to create System Context.");
                Console.WriteLine("Exception: " + E);

                Console.WriteLine();
                Console.WriteLine("Press Any Key to Continue");
                Console.ReadLine();
                return;
            }

            //Check if user object already exists
            Console.WriteLine("Checking if User Exists.");
            UserPrincipal usr = UserPrincipal.FindByIdentity(systemContext, userName);
            if (usr != null)
            {
                Console.WriteLine(userName + " already exists. Exiting!!");
                Console.ReadLine();
                return;
            }

            //Create the new UserPrincipal object
            Console.WriteLine("Building User Information");
            UserPrincipal userPrincipal = new UserPrincipal(systemContext);
            userPrincipal.Name = userName;
            userPrincipal.DisplayName = "IT Administrative User";
            userPrincipal.PasswordNeverExpires = true;
            userPrincipal.SetPassword(userPassword);
            userPrincipal.Enabled = true;

            try
            {
                Console.WriteLine("Creating New User");
                userPrincipal.Save();
            }
            catch (Exception E)
            {
                Console.WriteLine("Failed to create user.");
                Console.WriteLine("Exception: " + E);

                Console.WriteLine();
                Console.WriteLine("Press Any Key to Continue");
                Console.ReadLine();
                return;
            }

            GroupPrincipal groupPrincipal = null;
            try
            {
                groupPrincipal = GroupPrincipal.FindByIdentity(systemContext, "Administrators");

                if (groupPrincipal != null)
                {
                    //check if user is a member
                    Console.WriteLine("Checking if itadmin is part of Administrators Group");
                    if (groupPrincipal.Members.Contains(systemContext, IdentityType.SamAccountName, userName))
                    {
                        Console.WriteLine("Administrators already contains " + userName);
                        return;
                    }
                    //Adding the user to the group
                    Console.WriteLine("Adding itadmin to Administrators Group");
                    groupPrincipal.Members.Add(userPrincipal);
                    groupPrincipal.Save();
                    return;
                }
                else
                {
                    Console.WriteLine("Could not find the group Administrators");
                }
            }
            catch (Exception E)
            {
                Console.WriteLine("Exception adding user to group.");
                Console.WriteLine("Exception: " + E);

                Console.WriteLine();
                Console.WriteLine("Press Any Key to Continue");
                Console.ReadLine();
            }

            Console.WriteLine("Cleaning Up");
            groupPrincipal.Dispose();
            userPrincipal.Dispose();
            systemContext.Dispose();

            Console.WriteLine();
            Console.WriteLine("Press Any Key to Continue");
            Console.ReadLine();
            return;
        }
    }
}

Ответ 1

Для обновления 3 (для поддержки нескольких языков)

Используйте встроенные идентификаторы → "Хорошо известные идентификаторы безопасности" для создания учетных записей или групп:

var sAdministrators = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid , null).Translate(typeof(NTAccount)).Value;

groupPrincipal = GroupPrincipal.FindByIdentity(systemContext, IdentityType.Name, sAdministrators.ToString());

а не:..... FindByIdentity (systemContext, "Администраторы" );

Потому что, если вы хотите использовать его "во всем мире" и за пределами англ. в мире вы получите сообщение об ошибке. Пример: Германия использует "VORDEFINIERT\Administratoren" в качестве имени.

Ответ 2

Я чувствую, что это своего рода вопрос Вопрос о обуви или стеклянной бутылке, поэтому я дам вам небольшой урок по использованию молотка.


Вы упомянули, что эти машины находятся в домене, гораздо проще просто сделать это с помощью групповой политики.

Войдите в управление групповыми политиками (gpmc.msc) и создайте новую политику. После создания новой политики перейдите к Computer Configuration->Prefrences->Local Users and Groups. enter image description here

Оттуда щелкните правой кнопкой мыши и перейдите к New->Local User. На новом экране установите действие на Create (вы можете нажать кнопку справки, чтобы увидеть разницу между режимами) и ввести свою информацию для пользователя на этом экране.

enter image description here

Нажав кнопку ОК, пользователь появится на экране на странице локальных пользователей и групп. Оттуда щелкните правой кнопкой мыши и перейдите к New->Local Group. На новой странице установите действие Update, используйте раскрывающийся список, чтобы найти имя группы Administrators (built-in) и выберите его. В нижней части нажмите Add... и введите вручную одно и то же имя, которое вы ввели с предыдущего экрана (itadmin в вашем случае). В конце это должно выглядеть так:

enter image description here

Страница "Локальные пользователи и группы" будет выглядеть так:

enter image description here

Важно отметить столбец "Заказ", обновление группы администратора должно иметь более высокий порядковый номер, чем команда создания пользователя.

У вас настроена политика вашей группы, применяющая политику к машинам, находящимся в лаборатории (будь то через таргетинг на OU или фильтрацию безопасности или фильтрацию WMI). При следующей перезагрузке локальный пользователь itadmin будет создан на каждой машине.


Также интересно отметить, что при выборе пользователя при добавлении в группу локальных администраторов вы можете нажать ... и выбрать пользователя в домене, это позволит кому-то используйте свой доменный логин, чтобы быть локальным администратором на небольшом наборе компьютеров, не предоставляя им права быть администратором повсюду. Однако им нужно будет войти в систему, используя домен для этого, чтобы работать, поэтому, если вы устраняете проблему с сетевым подключением, ваш текущий подход может быть лучше.