重命名计算机并在 C# 中一次重启即可加入域

Posted

技术标签:

【中文标题】重命名计算机并在 C# 中一次重启即可加入域【英文标题】:Rename computer and join domain with one reboot in C# 【发布时间】:2012-05-10 03:05:41 【问题描述】:

我正在尝试制作一个程序,使我们能够更轻松地在域上部署新计算机。我想要它做的就是简单地重命名计算机,并将其加入我们的域(它会做很多其他的事情,但在我完成这项工作之前不会出现)。

此处代码:http://pastebin.com/ayREYH0C

从http://www.experts-exchange.com/Programming/Languages/.NET/Q_26262588.html 窃取,然后根据我的需要进行更改

我的问题是域加入不尊重计算机的重命名。我在重命名和连接之间放置了一个 Thread.Sleep,所以我有时间检查重命名是否发生了,它确实发生了!当域加入发生时,它会恢复为旧名称,这是在域中创建的计算机名称,而不是新名称。

我已经四处搜索,但没有找到这样的问题,也没有找到满足这种特殊需求的解决方案。

【问题讨论】:

你见过吗:***.com/questions/6217799/…和social.technet.microsoft.com/Forums/en-US/ITCG/thread/… 这也可能有用:***.com/questions/4183759/… 所以答案是:加入域,然后更改PC的名称。这带来了一些问题,因为非管理员没有更改计算机名称的权限,但我会解决这个问题,非常感谢您的帮助:) 没问题..我只是做了一些谷歌搜索..我实际上是在寻找一些你可以调用的powershell脚本,但我发现了它。如果你弄清楚了发布并回答并接受它..如果它有任何代码,我会支持它;-) 【参考方案1】:

这是一个将工作站连接到域的 c# 函数...您可能会发现将其用作避免 WMI 并改用 ManagementObject 的替代方法:

(我意识到执行凭据仍然需要重命名权限)

public static bool Join(string dom,string usr, string pass)
    
        // Define constants used in the method.
        int JOIN_DOMAIN = 1;
        int ACCT_CREATE = 2;
        int ACCT_DELETE = 4;
        int WIN9X_UPGRADE = 16;
        int DOMAIN_JOIN_IF_JOINED = 32;
        int JOIN_UNSECURE = 64;
        int MACHINE_PASSWORD_PASSED = 128;
        int DEFERRED_SPN_SET = 256;
        int INSTALL_INVOCATION = 262144;

        // Define parameters that we will use later when we invoke the method.
        // Remember, the username must have permission to join the object in the AD.
        //string domain = "domain";
        //string password = "password";
        //string username = "username";
        //string destinationOU = "destinationOU";

        // Here we will set the parameters that we like using the logical OR operator.
        // If you want to create the account if it doesn't exist you should add " | ACCT_CREATE "
        // For more information see: http://msdn.microsoft.com/en-us/library/aa392154%28VS.85%29.aspx
        int parameters = JOIN_DOMAIN | DOMAIN_JOIN_IF_JOINED;

        // The arguments are passed as an array of string objects in a specific order
        object[] methodArgs =  dom, pass, usr + "@" + dom, null, parameters ;

        // Here we construct the ManagementObject and set Options
        ManagementObject computerSystem = new ManagementObject("Win32_ComputerSystem.Name='" + Environment.MachineName + "'");
        computerSystem.Scope.Options.Authentication = System.Management.AuthenticationLevel.PacketPrivacy;
        computerSystem.Scope.Options.Impersonation = ImpersonationLevel.Impersonate;
        computerSystem.Scope.Options.EnablePrivileges = true;

        // Here we invoke the method JoinDomainOrWorkgroup passing the parameters as the second parameter
        object Oresult = computerSystem.InvokeMethod("JoinDomainOrWorkgroup", methodArgs);

        // The result is returned as an object of type int, so we need to cast.
        int result = (int)Convert.ToInt32(Oresult);

        // If the result is 0 then the computer is joined.
        if (result == 0)
        
            MessageBox.Show("Joined Successfully!");
            return true;
        
        else
        
            // Here are the list of possible errors
            string strErrorDescription = " ";
            switch (result)
            
                case 5: strErrorDescription = "Access is denied";
                    break;
                case 87: strErrorDescription = "The parameter is incorrect";
                    break;
                case 110: strErrorDescription = "The system cannot open the specified object";
                    break;
                case 1323: strErrorDescription = "Unable to update the password";
                    break;
                case 1326: strErrorDescription = "Logon failure: unknown username or bad password";
                    break;
                case 1355: strErrorDescription = "The specified domain either does not exist or could not be contacted";
                    break;
                case 2224: strErrorDescription = "The account already exists";
                    break;
                case 2691: strErrorDescription = "The machine is already joined to the domain";
                    break;
                case 2692: strErrorDescription = "The machine is not currently joined to a domain";
                    break;
            
            MessageBox.Show(strErrorDescription.ToString());
            return false;
        

    

【讨论】:

以上是关于重命名计算机并在 C# 中一次重启即可加入域的主要内容,如果未能解决你的问题,请参考以下文章

通过添加当前电脑名称来批量重命名电脑

将数据导出到 csv 并在计算机配置文件名称后重命名

C# ActiveDirectory - 如何将本地用户帐户从加入域的计算机远程添加到非域计算机

重新建立域计算机账户与域控制器的联系

Windows Server 2016-重命名域控制器

计算机加入域时,提示说 加入域失败,指定的用户已存在 ,是啥原因??