13

我正在编写一个 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;
        }
    }
}
4

2 回答 2

2

对于更新 3(用于多语言支持)

请使用内置标识符 --> “众所周知的 SID” 来构建帐户或组:

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

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

而不是:..... FindByIdentity(systemContext, "Administrators");

因为如果您想在“世界范围内”和英语之外使用它。世界你会得到一个错误。示例:德国使用“VORDEFINIERT\Administratoren”作为名称。

于 2017-06-23T14:57:43.427 回答
-8

您提到这些机器位于域上,使用组策略执行此操作要简单得多。

进入组策略管理 ( 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 用户。


还有一个有趣的注意事项,当您在选择要添加到本地管理员组的人员时选择用户时,您可以单击...并选择域上的用户,这将允许某人使用他们的域登录成为一小部分的本地管理员计算机而不赋予他们在任何地方成为管理员的权利。但是,他们需要能够使用域登录才能使其工作,因此,如果您正在解决网络连接问题,您当前的方法可能是更好的选择。

于 2012-10-11T20:09:35.450 回答