Improving performance of System.DirectoryServices.AccountManagement

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-01 08:02:52
Scott Chamberlain

I found a soulution

private void AddUsers(UserInfo userInfo, InfinityInfo infinityInfo, int subUserStart)
{
    var userSerach = new UserPrincipal(context);
    userSerach.SamAccountName = userInfo.Username + '*';
    var ps = new PrincipalSearcher(userSerach);
    var pr = ps.FindAll().ToList().Where(a =>
                Regex.IsMatch(a.SamAccountName, String.Format(@"{0}\D", userInfo.Username))).ToDictionary(a => a.SamAccountName); // removes results like conversons12 from the search conversions1*
    pr.Add(userInfo.Username, Principal.FindByIdentity(context, IdentityType.SamAccountName, userInfo.Username));
    using (GroupPrincipal r = GroupPrincipal.FindByIdentity(context, "Remote Desktop Users"))
    using (GroupPrincipal u = GroupPrincipal.FindByIdentity(context, "Users"))
    for(int i = subUserStart; i < userInfo.SubUsers; ++i)
    {
        string username = userInfo.Username;
        if (i >= 0)
        {
            username += (char)('a' + i);
        }
        UserPrincipal user = null;
        try
        {
            if (userInfo.NewPassword == null)
                throw new ArgumentNullException("userInfo.NewPassword", "userInfo.NewPassword was null");
            if (userInfo.NewPassword == "")
                throw new ArgumentOutOfRangeException("userInfo.NewPassword", "userInfo.NewPassword was empty");
            if (pr.ContainsKey(username))
            {
                user = (UserPrincipal)pr[username];
                user.Enabled = true;
                user.SetPassword(userInfo.NewPassword);
            }
            else
            {
                user = new UserPrincipal(context, username, userInfo.NewPassword, true);
                user.UserCannotChangePassword = true;
                user.PasswordNeverExpires = true;
                user.Save();
                r.Members.Add(user);
                u.Members.Add(user);
                r.Save();
                u.Save();
            }
            IADsTSUserEx iad = (IADsTSUserEx)((DirectoryEntry)user.GetUnderlyingObject()).NativeObject;
            iad.TerminalServicesInitialProgram = GenerateProgramString(infinityInfo);
            iad.TerminalServicesWorkDirectory = Service.Properties.Settings.Default.StartInPath;
            iad.ConnectClientDrivesAtLogon = 0;
            user.Save();
            OperationContext.Current.GetCallbackChannel<IRemoteUserManagerCallback>().FinishedChangingUser(username);

        }
        finally
        {
            if (user != null)
            {
                user.Dispose();
            }
        }
    }
}

It adds a few more seconds on the first user but now its about .5 seconds per user after that. The odd calling of the ps.FindAll().ToList().Where(a =>Regex.IsMatch(...))).ToDictionary(a => a.SamAccountName); is because a principle searcher does not cache results. See my question from a few days ago.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!