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

Я пишу программу на С#, которую нужно вывести из лабораторий, в которых я работаю. Программа состоит в том, чтобы создать локальную учетную запись администратора (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;
        }
    }
}

person nizram    schedule 11.10.2012    source источник
comment
Попробуйте получить конкретную ошибку с помощью E.ToString() вместо E.Message.ToString().   -  person TGlatzer    schedule 11.10.2012
comment
Кстати, есть (уже не новое) пространство имен под названием System.DirectoryServices.AccountManagement, которое облегчит вам жизнь.   -  person TGlatzer    schedule 11.10.2012
comment
@ 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 stack trace --- 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   -  person nizram    schedule 11.10.2012
comment
Что ж, возможно, вам следует взглянуть на пространство имен, о котором я упоминал выше, там вы можете создать пользователя и добавить его в группу за один шаг.   -  person TGlatzer    schedule 11.10.2012
comment
@nizram - Вы должны обновить вопрос с этой дополнительной информацией. Исключением является то, что вы пытаетесь удалить пользователя, который не существует или не является частью определенной группы.   -  person Security Hound    schedule 11.10.2012
comment
У вас нет групповой политики?   -  person David Heffernan    schedule 11.10.2012
comment
@DavidHeffernan Мы используем домен AD для пользователей, но это исключительно для локального администрирования, когда учащиеся работают над установкой программного обеспечения без предоставления им прав администратора домена.   -  person nizram    schedule 11.10.2012
comment
На какой ОС работает приложение? Запускается ли он от имени пользователя, который уже входит в группу администраторов, и если да, то от имени администратора?   -  person nateirvin    schedule 11.10.2012
comment
@nateirvin это было написано для / для Windows 7. Работающему пользователю нужны права администратора в рассматриваемой системе, и я смог использовать это, только создав код в Visual Studio и запустив полученный файл .exe от имени администратора из проводника Windows.   -  person nizram    schedule 11.10.2012


Ответы (2)


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

Пожалуйста, используйте встроенные идентификаторы --> "Известные SID" для встроенных учетных записей или групп:

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

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

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

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

person Nighty    schedule 23.06.2017

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

Перейдите к управлению групповыми политиками (gpmc.msc) и создайте новую политику. Создав новую политику, перейдите по ссылке Computer Configuration->Prefrences->Local Users and Groups.введите здесь описание изображения

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

введите здесь описание изображения

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

введите здесь описание изображения

страница «Локальные пользователи и группы» будет выглядеть так

введите здесь описание изображения

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

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


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

person Scott Chamberlain    schedule 11.10.2012
comment
Будет ли человек, который поставил этому -1, объяснить, почему? Этот процесс создает локального пользователя с правами локального администратора, почему этот ответ не был полезен? - person Scott Chamberlain; 23.10.2012
comment
Я проголосовал за это, потому что вы не ответили на вопрос. Вы дали альтернативу... но вопрос был в том, как это сделать программно. Я понимаю, что предлагаю программную альтернативу... но, на мой взгляд, это далеко не так. - person bsara; 24.10.2012
comment
@Brandon Пожалуйста, прочитайте этот meta.stackoverflow.com вопрос и ответы. Создание исполняемого файла для создания пользователя — неправильный способ создания таких пользователей в домене, он может работать, но это неправильный способ. - person Scott Chamberlain; 24.10.2012
comment
Спасибо за ссылку... тем не менее, я все еще чувствую то же самое. Вы не сказали, что это был неправильный путь... и если бы вы сказали, вы также должны объяснить, почему. Затем, если вы знаете, как сделать это неправильно, вы должны предоставить эту информацию, в противном случае может быть лучше предложить другой способ. Неправильный путь и правильный путь слишком относительны, чтобы предполагать, что то, что вы узнали или предположили, является неправильным/правильным путем. Честно говоря, я очень расстраиваюсь, когда получаю такие ответы, потому что иногда мне просто любопытно, как что-то работает или как что-то сделать, если меня когда-нибудь заставят это сделать. - person bsara; 25.10.2012
comment
Это не вопрос старой обуви или стеклянной бутылки. Создание программы для создания пользователей — вполне допустимый способ автоматизации такого рода задач. Я удивлен, что вы пытаетесь направить его к повторяющемуся вручную решению. Я предполагаю, что ОП уже знает, как mmc. - person Skrymsli; 08.04.2017