Rename Windows Local Account with c#

Viewed 444

I try to rename some windows local account, and I used 3 method: (all of them runs in elevated administrator account) The first one works, but it takes 7-9 seconds to do it. Here is my first question:
Why is it so slow?

public bool RenameWinUser(winUser winUser, string newname) {
  log.writeToLog(null, "[renameWinUser]");
  DirectoryEntry localDirectory = new DirectoryEntry("WinNT://" + Environment.MachineName.ToString());
  DirectoryEntries localUsers = localDirectory.Children;
    try {
      DirectoryEntry toRename = localUsers.Find(winUser.getName());
      try {
        log.writeToLog(null, String.Format("[renameWinUser] {0} is found, try to rename", winUser.getName()));
        try {
          toRename.Rename(newname);
          log.writeToLog(null, String.Format("[renameWinUser] {0} is renamed", winUser.getName()));
          return true;
        }
        catch (Exception e) {
         log.writeToLog(null, String.Format("[renameWinUser] Rename user exception: ", e.ToString()));
        }
      }
      catch (Exception e) {
        log.writeToLog(null, String.Format("[renameWinUser] Rename user exception: ", e.ToString()));
        return false;
      }
    }
    catch (Exception e) {
      log.writeToLog(null, String.Format("[removeWinUser] Remove user exception while searching: ", e.ToString()));
      return false;
    }
  return false;
}

The second one is fast, but it won't save the username/SamAccountName/UserPrincipalName, just the FullName.
So, here is my second question: What did i do wrong?

public bool RenameWinUser(winUser winUser, string newname) {
  log.writeToLog(null, "[renameWinUser]");
  PrincipalContext context = new PrincipalContext(ContextType.Machine, Environment.MachineName);
  UserPrincipal user = new UserPrincipal(context);
  PrincipalSearcher usrSearch = new PrincipalSearcher(user);
  foreach (UserPrincipal usrResult in usrSearch.FindAll()) {
    if (usrResult.SamAccountName.ToLower() == winUser.getName().ToLower()) {
      log.writeToLog(null, String.Format("[renameWinUser] {0} is found, try to rename", winUser.getName()));
      try {
        usrResult.SamAccountName = newname;
        usrResult.Name = newname;
        usrResult.DisplayName = newname;
        //usrResult.UserPrincipalName = newname + "@" + Domain.GetCurrentDomain();
        //this throws:Current security context is not associated with an Active Directory domain or forest
        //usrResult.UserPrincipalName = newname + "@" + Environment.MachineName;
        //this throws:This property is invalid for this storage type
      }
      catch (Exception e) {
        log.writeToLog(null, String.Format("[renameWinUser] Failed to set properties: {0}", e.Message.ToString()));
        return false;
        }
      try {
        usrResult.Save();
        log.writeToLog(null, String.Format("[renameWinUser] Rename was success", winUser.getName()));
        return true;
      }
      catch (Exception e) {
        log.writeToLog(null, String.Format("[renameWinUser] Failed to save: {0}", e.Message.ToString()));
        return false;
      }
    }
  }
  return false;
}

My 3rd option was UserPrincipal.FindByIdentity(), but it takes 7-9 seconds to save only the fullname, not the username/SamAccountName/UserPrincipalName. My last questions:
why UserPrincipal.FindByIdentity() takes so long
What did I do wrong again?

public bool RenameWinUser(winUser winUser, string newname) {
  log.writeToLog(null, "[renameWinUser]");
  PrincipalContext context = new PrincipalContext(ContextType.Machine, Environment.MachineName);
  UserPrincipal user = UserPrincipal.FindByIdentity(context, winUser.getName());
  log.writeToLog(null, String.Format("[renameWinUser] {0} is found, try to rename", winUser.getName()));
  try {
    user.SamAccountName = newname;
    user.Name = newname;
    user.DisplayName = newname;
    //user.UserPrincipalName = newname + "@" + Domain.GetCurrentDomain();
  }
  catch (Exception e) {
    log.writeToLog(null, String.Format("[renameWinUser] Failed to set properties: {0}", e.Message.ToString()));
    return false;
  }
  try {
    user.Save();
    log.writeToLog(null, String.Format("[renameWinUser] Rename was success", winUser.getName()));
    return true;
  }
  catch (Exception e) {
    log.writeToLog(null, String.Format("[renameWinUser] Failed to save: {0}", e.Message.ToString()));
    return false;
  }
}

I dont wan't use cmd/wmic/System.Management.SelectQuery, but I know, that wmic

wmic useraccount where name='apple' rename grape

takes only 0.1-2 sec.

I really need your help, guys...

0 Answers
Related