rename computer during Windows Autopilot deployment using C#

182 views Asked by At

I'm trying to create a C# application to perform workstation deployment tasks during Windows Autopilot. The first thing i want to do is rename the computer. I've tried numerous ways to accomplish this, i started by using a powershell script with the Rename-Computer command uploaded into Intune. After many hours of searching for a solution to the numerous errors received, I finally gave up and decided to switch to a C# console app. I've had the most success with this approach but it's still not correct.

static void Main()
{
    try
    {
        // Specify the LDAP path to the computer object in Active Directory
        string ldapPath = "LDAP://" + GetPathToMachine(Environment.MachineName);

        // build the new computer name
        string computerNamePrefix = "CompPFix-";
        string newComputerName = computerNamePrefix + GetPCAssetTag();

        if (!ldapPath.Contains(newComputerName))
        {
            using (DirectoryEntry computerEntry = new DirectoryEntry(ldapPath, @"domain\admin", @"adminpassword"))
            {
                // Get the parent container (OU) of the computer to construct the new ADName
                DirectoryEntry parentContainer = computerEntry.Parent;
                string newADName = $"CN={newComputerName}";

                // If needed, update the DNS host name attribute
                computerEntry.Rename(newADName);
                computerEntry.CommitChanges();
                computerEntry.Properties["cn"].Value = newComputerName;
                computerEntry.Properties["name"].Value = newComputerName;
                computerEntry.Properties["dNSHostName"].Value = $"{newComputerName}.corp.contoso.com"; 
                computerEntry.Properties["displayName"].Value = newComputerName + "$$";
                computerEntry.Properties["sAMAccountName"].Value = newComputerName + "$$";
                computerEntry.CommitChanges();

                if (GetPathToMachine(newComputerName).Length > 1) 
                {
                    WriteLog($"Computer object name successfully changed to {newComputerName} in Active Directory.");
                }
                else
                {
                    WriteLog($"error trying to change computer object to {newComputerName} in Active Directory.");
                }
                if (Environment.MachineName == newComputerName)
                {
                    WriteLog($"local computer name successfully changed to {newComputerName}.");
                }
                else
                {
                    WriteLog($"error trying to change local computer name to {newComputerName}.");
                }
            }
        }
        else
        {
            WriteLog($"AD Computer Object is already set correctly {newComputerName}.");
        }
    }
    catch (Exception ex)
    {
        WriteLog($"An error occurred: {ex.GetType().FullName} - {ex.Message}\n{ex.StackTrace}");
    }
}

With this approach I've been able to change the AD computer object but not the local computer name. I've tried many different variations to try and get both the AD object and local name in sync but nothing seems to work. Most of the time the AD object isn't quite right. It will have the correct name but many of the attributes that contain name related data are not changed correctly. In the code above I've tried to manually change some of those attributes without success. There's been far too many different errors to recall but generally they look like this one.

An error occurred: System.DirectoryServices.DirectoryServicesCOMException - A device attached to the system is not functioning.

   at System.DirectoryServices.DirectoryEntry.CommitChanges()
   at WindowsAutopilotDeployment.Program.Main()

Many times I'll get a message saying that the security identifier does not exist for the machine name. I'm at my wits end with this. Has anyone been successful, with any technique, at renaming a computer, during a Windows Autopilot deployment, in a Hybrid domain joined environment?

1

There are 1 answers

0
Konrad Psiuk On

If You want to change the computer's name, You can try to do it in Windows settings and check regedit what values changed. Then, when You know what changed in the register, you can reverse-eng that and You can change the registry from C#, like below (this is what I found in my system, I think ComputerName needs to be in capital letters but this is TBC), Make sure You run this code as Administrator, changes apply after reboot:

namespace ConsoleApp
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string name = "newname";
            
            RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName", true);
            key.SetValue("ComputerName", name.ToUpper());
            
            key = Registry.LocalMachine.OpenSubKey(@"SYSTEM\ControlSet001\Services\Tcpip\Parameters", true);
            key.SetValue("NV HostName", name);
        }
    }
}