我正在编写一个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;
}
}
}
答案 0 :(得分:0)
对于更新3(用于多语言支持)
请使用内置标识符 - > "众所周知的SID"用于构建帐户或组:
var sAdministrators = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid , null).Translate(typeof(NTAccount)).Value;
groupPrincipal = GroupPrincipal.FindByIdentity(systemContext, IdentityType.Name, sAdministrators.ToString());
而不是:..... FindByIdentity(systemContext,"管理员");
因为如果你想在世界范围内使用它"在engl之外。世界你会得到一个错误。示例:德国使用" VORDEFINIERT \ Administratoren"作为名字。
答案 1 :(得分:-5)
我觉得这有点Shoe or Glass bottle question,所以我会给你一些关于使用锤子的课程。
您提到这些计算机位于域中,使用组策略执行此操作要简单得多。
进入组策略管理(gpmc.msc
)并创建新策略。创建新策略后,请转到Computer Configuration->Prefrences->Local Users and Groups
。
从那里右键单击并转到New->Local User
。在新屏幕中将操作设置为Create
(您可以单击帮助按钮以查看模式之间的差异),然后在该屏幕中输入用户的信息。
单击“确定”,用户将在本地用户和组页面的屏幕上显示。从那里右键单击并转到New->Local Group
。在新页面上将操作设置为Update
,使用下拉列表查找组名Administrators (built-in)
并选择它。在底部单击Add...
,然后手动输入您在上一个屏幕中输入的相同名称(在您的案例中为itadmin
)。最后它应该看起来像这样
“本地用户和组”页面将如下所示
注意Order列非常重要,管理员组的更新必须具有比用户创建命令更高的订单号。
您已设置组策略的策略将策略应用于实验室中的计算机(通过OU定位或安全过滤或WMI过滤)。在下次重新启动时,将在每台计算机上创建本地itadmin用户。
另外一个有趣的说明是,当您选择添加到本地管理员组的用户时,您可以点击...
并在域中选择用户 这将允许某人使用他们的域名登录成为一小组计算机上的本地管理员,而无权让他们在任何地方成为管理员。但是,他们需要能够使用域名登录才能使用此功能,因此如果您要解决网络连接问题,那么您当前的方法可能会更好。