Добавление локального пользователя в локальную группу администраторов
Я пишу программу на C#, которую нужно вытолкнуть из лабораторий, в которых я работаю. Программа предназначена для создания учетной записи локального администратора (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;
}
}
}
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" в качестве имени.
Я чувствую, что это вопрос об обувной или стеклянной бутылке, поэтому я дам вам небольшой урок по использованию молотка.
Вы упоминаете, что эти машины находятся в домене, гораздо проще сделать это с помощью групповой политики.
Перейти к управлению групповой политикой (gpmc.msc
) и создать новую политику. После создания новой политики перейдите на Computer Configuration->Prefrences->Local Users and Groups
,
Оттуда щелкните правой кнопкой мыши и перейдите к New->Local User
, На новом экране установите действие Create
(Вы можете нажать кнопку справки, чтобы увидеть разницу между режимами) и ввести свою информацию для пользователя на этом экране.
Когда вы нажмете "ОК", пользователь появится на экране на странице локальных пользователей и групп. Оттуда щелкните правой кнопкой мыши и перейдите к New->Local Group
, На новой странице установите действие Update
, используйте раскрывающийся список, чтобы найти имя группы Administrators (built-in)
и выберите его. В нижней части нажмите Add...
и введите вручную то же имя, которое вы указали на предыдущем экране (itadmin
в твоем случае). В конце это должно выглядеть так
страница "Локальные пользователи и группы" будет выглядеть следующим образом
Важно отметить столбец "Порядок": обновление в группе администраторов должно иметь более высокий номер заказа, чем команда создания пользователя.
Когда у вас настроена групповая политика, примените политику к компьютерам, которые находятся в лаборатории (будь то с помощью нацеливания на OU или фильтрации безопасности или фильтрации WMI). При следующей перезагрузке локальный пользователь itadmin будет создан на каждой машине.
Также интересно отметить, что при выборе пользователя при выборе того, кого добавить в группу локальных администраторов, вы можете нажать ...
и выбрать пользователя в домене, это позволит кому-то использовать свой логин в качестве локального администратора на небольшом наборе компьютеров, не предоставляя им права быть администратором повсюду. Однако они должны будут иметь возможность войти в систему, используя домен, чтобы это работало, поэтому, если вы решаете проблему с сетевым подключением, ваш текущий подход может быть лучше.