none
add user to AD group RRS feed

  • Question

  • I have below code and trying to add users to Ad group as part of a script task in SSIS.The script is inside a foreach loop container which will iterate over each row from query,pick the users and add them into the AD group iteratively.

    It does add some users to group but also throws some exceptions like:

    • the principal is already existing in store
    • No principal matching the specified parameters was found

    After I had made a change to my code to check if the user already existed in group,then do nothing,else add him to group,I dont see above but see another exception:Object reference not set to an instance of an object

    There are still a bunch of users pending addition into the AD group.

    using System;
    using System.DirectoryServices.AccountManagement;
    using System.Windows.Forms;

    namespace ST_a66e3c28bec84b718f6afa04448e0bec
    {

        [Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
        public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
        {
            enum ScriptResults
            {
                Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
                Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
            };
            public void Main()
            {
              
                try
                {

                    string userName = Dts.Variables["User::Uname"].Value.ToString();
                
                    string group = Dts.Variables["User::Group"].Value.ToString();
                    AddUserToGroup(userName, group);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                    Dts.TaskResult = (int)ScriptResults.Failure;
                }
                Dts.TaskResult = (int)ScriptResults.Success;
            }
            public void AddUserToGroup(string userId, string groupName)
            {
                try
                {
                    using (PrincipalContext pc = new
                    PrincipalContext(ContextType.Domain,
                    "abc.com"))
                    {
                        GroupPrincipal group = GroupPrincipal.FindByIdentity(pc, groupName);

                        UserPrincipal user = UserPrincipal.FindByIdentity(pc, userId);
                        if (user.IsMemberOf(group))
                        {
                            
                        }
                        else
                        {
                            group.Members.Add(pc, IdentityType.SamAccountName, userId);
                            group.Save();
                        }                
                    }
                }
                catch (Exception ex)
                {
                    //MessageBox.Show(ex.ToString());
                    var message = String.Format("{0} - {1}", ex.Message, Environment.NewLine);
                    System.IO.File.AppendAllText(@"C:\Users\tadam\Documents\ADError.txt", "Date :" + DateTime.Now.ToString() + "\t" + "Message:" + message);
                    //Dts.TaskResult = (int)ScriptResults.Failure;
                }
                Dts.TaskResult = (int)ScriptResults.Failure;
            }
        }
    }


    Tuesday, August 21, 2018 4:12 PM

Answers

  • Hi 

    Thank you for posting here.

    For your question. you could try the code below to check the user exists or not. Using if statement, if the checkUser() method return false, add the user into group.

    public static bool CheckUser(string name)
            {
                bool b = false;
                List<string> list = new List<string>();
                DirectoryEntry de = new DirectoryEntry("LDAP://DC=fareast,DC=corp,DC=microsoft,DC=com");
                DirectorySearcher searcher2 = new DirectorySearcher(de);
                searcher2.Filter = string.Format("(&(objectCategory=user)(objectClass=user)(memberOf={0}))", "CN=xxxxx,OU=xxxxx Lists,DC=xxxxx,DC=corp,DC=xxxxx,DC=xxxxx");
                SearchResultCollection results2 = searcher2.FindAll();
                foreach (SearchResult res2 in results2)
                {
                    ResultPropertyValueCollection col = res2.Properties["name"];
                    foreach (var o in col)
                    {
                        if (o.ToString().Contains(name))
                        {
                            b = true;
                        }
                    }
                }
                return b;
            }

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by msdnpublic1234 Thursday, August 23, 2018 10:22 PM
    Wednesday, August 22, 2018 6:13 AM
    Moderator
  • Wendy,

    Thanks for the directory search code.

    My above code did work,i just had to wait for various domain controllers to sync with eachother.If We perform mutliple operations on AD,the changes will not sync and we may enter into race condition.I gave ~1 hr for all users be deleted,then performed insert,waited for 30mins or so for all of them to be added back.


    Thursday, August 23, 2018 10:22 PM

All replies

  • Hi 

    Thank you for posting here.

    For your question. you could try the code below to check the user exists or not. Using if statement, if the checkUser() method return false, add the user into group.

    public static bool CheckUser(string name)
            {
                bool b = false;
                List<string> list = new List<string>();
                DirectoryEntry de = new DirectoryEntry("LDAP://DC=fareast,DC=corp,DC=microsoft,DC=com");
                DirectorySearcher searcher2 = new DirectorySearcher(de);
                searcher2.Filter = string.Format("(&(objectCategory=user)(objectClass=user)(memberOf={0}))", "CN=xxxxx,OU=xxxxx Lists,DC=xxxxx,DC=corp,DC=xxxxx,DC=xxxxx");
                SearchResultCollection results2 = searcher2.FindAll();
                foreach (SearchResult res2 in results2)
                {
                    ResultPropertyValueCollection col = res2.Properties["name"];
                    foreach (var o in col)
                    {
                        if (o.ToString().Contains(name))
                        {
                            b = true;
                        }
                    }
                }
                return b;
            }

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by msdnpublic1234 Thursday, August 23, 2018 10:22 PM
    Wednesday, August 22, 2018 6:13 AM
    Moderator
  • Wendy,

    Thanks for the above,but somehow i still see the following exception messages more than 100 and they did'nt already exist in the xyzOracle group:

    The principal already exists in the store. -

    Following is the code:

    using System;
    using System.Collections.Generic;
    using System.DirectoryServices;

    using System.DirectoryServices.AccountManagement;

    namespace ST_a66e3c28bec84b718f6afa04448e0bec
    {

        [Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
        public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
        {
            enum ScriptResults
            {
                Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
                Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
            };
            public void Main()
            {
                /* TODO: Add your code here
                PrincipalContext ouContex = new
                    PrincipalContext(ContextType.Domain
            , "abc.com", "CN=xyzOracle,OU=Groups-Distribution,OU=xyz,OU=USA,OU=North America,DC=abc,DC=com");
            */

                try
                {


                    string userName = Dts.Variables["User::Uname"].Value.ToString();
                    string group = Dts.Variables["User::Group"].Value.ToString();
                    bool CheckVal=CheckUser(userName);
                    if(CheckVal)
                    {
                        
                    }
                    else
                    {
                        AddUserToGroup(userName, group);
                    }
               
                }
                catch (Exception exp)
                {
                    //MessageBox.Show(ex.ToString());
                    var msg = String.Format("{0} - {1}", exp.Message, Environment.NewLine);
                    System.IO.File.AppendAllText(@"C:\Users\tadam\Documents\ADError_1.txt", "Date :" +
                        DateTime.Now.ToString() + "\t" + "Message:" + msg);
                    Dts.TaskResult = (int)ScriptResults.Failure;
                }
                Dts.TaskResult = (int)ScriptResults.Success;
            }
            public static bool CheckUser(string name)
            {
                bool b = false;
                List<string> list = new List<string>();
                DirectoryEntry de = new DirectoryEntry("LDAP://CN=xyzOracle,OU=Groups-Distribution,OU=xyz,OU=USA,OU=North America,DC=abc,DC=com");
                DirectorySearcher searcher2 = new DirectorySearcher(de);
                searcher2.Filter = string.Format("(&(objectCategory=person)(objectClass=user)(sAMAccountName=" + name + "))");
                SearchResultCollection results2 = searcher2.FindAll();
                foreach (SearchResult res2 in results2)
                {
                    ResultPropertyValueCollection col = res2.Properties["name"];
                    foreach (var o in col)
                    {
                        if (o.ToString().Contains(name))
                        {
                            b = true;
                        }
                    }
                }
                return b;
            }
            public void AddUserToGroup(string userId, string groupName)
            {
               
                    using (PrincipalContext pc = new
                    PrincipalContext(ContextType.Domain,
                    "abc.com"))
                    {
                        GroupPrincipal group = GroupPrincipal.FindByIdentity(pc, groupName);
                     

                        group.Members.Add(pc, IdentityType.SamAccountName, userId);
                        group.Save();
                    }
               
            }
        }
    }

    I dont know why i see those exceptions.Also,the first time I ran this ,i could see majority of members added to the AD.But next time,when i ran after removing all members from AD,I could see only 1/4th of them added.Its very weird that results are not consistent everytiime.Pls suggest the changes in the code.




    Wednesday, August 22, 2018 4:10 PM
  • Wendy,

    Thanks for the directory search code.

    My above code did work,i just had to wait for various domain controllers to sync with eachother.If We perform mutliple operations on AD,the changes will not sync and we may enter into race condition.I gave ~1 hr for all users be deleted,then performed insert,waited for 30mins or so for all of them to be added back.


    Thursday, August 23, 2018 10:22 PM