简体   繁体   中英

How to insert or update properties in Active Directory Users and Groups

I am making a windows application that sync the source data to Active Directory.

This application works like this.

  1. Choose Source Data(Department, User)

  2. Mapping user or department attributes from source data

  3. When Application service is run, it create groups and users in Active Directory

  4. And also it sets the attributes to users and groups.

When I try to set group or user attributes(properties), it throws exception message like this.

in DirectoryEntry.CommitChanges(); block

The directory
 service cannot perform the requested operation on the RDN attribute of an object.

I tried to solve it, but it's really hard to me because I`m not good at Active directory...

Code is below, Please share your knowledge.

    //ppk: department key column, pk:user key column, row : Source DataTable's row
        void CreateADUser(string ppk,string pk,DataRow row)
        {
            //password
            string pass = GetPass(pk,row,LogSections.AD);
            //OU
            DirectoryEntry addept = adm.FindOU(ppk);
            //principal path
            string sOU = adm.GetPrincipalPath(addept);
            var aduser = adm.CreateNewUser(sOU, pk, pass, pk, null, null, adm.sDomain);
            SetAdUserProperties(pk, pass, row);    
            MoveUser(ppk,pk);
        }



        void SetAdUserProperties(string pk,string pass,DataRow row)
        {
            if (row == null) return;
            //list of mapped column(AD User attributes)
            List<ADMapping> MappingPatterns = GetAdMappings(Words.User,false);
            //Columns name of Source Data table's row
            var colnames = Tool.GetColNames(row);
            //get user proterties
            var aduser = adm.GetUser(pk);
            //directory entry of users
            var de=aduser.GetUnderlyingObject() as DirectoryEntry;
            //looping mapped column of user attributes
            foreach (var ADMap in MappingPatterns)
            {
                string val = ADMap.Mapping;
                //mapped columns value
                val=Util.ReplaceColPattern(val, row);
                SetProperty(de, ADMap.CN, val);
            }
            if (!string.IsNullOrWhiteSpace(pass))
            {
               var UserPkColumn = AppConfigHelper.GetAppString(Words.SourceUserPKColumn);
               UserPkColumn = Util.GetActualColName(UserPkColumn);
               aduser.SetPassword(pass);
               QueryHelper.Update(QueryHelper.ConnectionString, Words.ShadowUserTable
                            ,new SqlParameter[] { new SqlParameter("@passwd", pass) }
                            , new SqlParameter("@"+UserPkColumn,pk));
            }

             aduser.Save();
        }

        public void SetProperty(DirectoryEntry oDE, string sPropertyName, object sPropertyValue)
        {
            if (sPropertyValue != null && !string.IsNullOrWhiteSpace(sPropertyValue.ToString()))
            {
                if (oDE.Properties.Contains(sPropertyName))
                {
                    oDE.Properties[sPropertyName].Value = sPropertyValue;
                }
                else
                {
                    oDE.Properties[sPropertyName].Add(sPropertyValue);
                }
                try
                {
                    oDE.CommitChanges(); //exception here.
                    oDE.Close();
                 }
                catch (Exception)
                {   
                }
             }
        }

It's hard to see what's the cause of the issue here as we're not seeing what attributes you are trying to set.

That said, you can't just add an attribute if it doesn't exist on your AD object so this part of your code definitely has an issue :

if (oDE.Properties.Contains(sPropertyName))
{
    oDE.Properties[sPropertyName].Value = sPropertyValue;
}
else
{
    //The following line will never work in this context
    oDE.Properties[sPropertyName].Add(sPropertyValue);
}

If I had to make an educated guess, I'd say you're either trying to set an attribute that can't be set, or the User you're adding doesn't have all it's mandatory attributes set.

I also asked this question to other forums, and finally got it.

Before DirectoryEntry.CommitChanges(); set UserPropertyCache property to true

and call the RefreshCache method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM