public void ExecuteGroupSync(GroupSynch groupsyn, ConfigSettings settingsConfig, ToolSet tools, LogFile log) { StopWatch time = new StopWatch(); string groupapp = groupsyn.Group_Append; string groupOU = groupsyn.BaseGroupOU; string sAMAccountName = ""; string description = ""; int count = 0; string sqlgroupsTable = "#FHC_GROUPS_SQLgroupsTable"; string adGroupsTable = "#FHC_GROUPS_ADgroupsTable"; if (settingsConfig.TempTables == true) { sqlgroupsTable = "#FHC_GROUPS_SQLgroupsTable"; adGroupsTable = "#FHC_GROUPS_ADgroupsTable"; } else { sqlgroupsTable = "FHC_GROUPS_SQLgroupsTable" + groupsyn.Group_Append; adGroupsTable = "FHC_GROUPS_ADgroupsTable" + groupsyn.Group_Append; } string dc = groupOU.Substring(groupOU.IndexOf("DC")); string groupDN; string groupsTable; SqlDataReader add; SqlDataReader delete; SqlDataReader update; ArrayList adUpdateKeys = new ArrayList(); ArrayList sqlUpdateKeys = new ArrayList(); ArrayList fields = new ArrayList(); DataTable groupsDataTable = new DataTable(); Dictionary<string, string> groupObject = new Dictionary<string, string>(); SqlConnection sqlConn = new SqlConnection("Data Source=" + groupsyn.DataServer + ";Initial Catalog=" + groupsyn.DBCatalog + ";Integrated Security=SSPI;Connect Timeout=360"); sqlConn.Open(); // Setup the OU for the program log.addTrn("Setup OU for the groups", "Info"); tools.CreateOURecursive("OU=" + groupapp + "," + groupOU, log); // A little house cleaning to empty out tables if (settingsConfig.TempTables == false) { log.addTrn("Clear out tables for use", "Info"); tools.DropTable(adGroupsTable, sqlConn, log); tools.DropTable(sqlgroupsTable, sqlConn, log); } // grab list of groups from SQL insert into a temp table log.addTrn("Get groups from SQL", "Info"); SqlCommand sqlComm = new SqlCommand(); if (groupsyn.Group_where == "") { sqlComm = new SqlCommand("SELECT DISTINCT RTRIM(" + groupsyn.Group_sAMAccount + ") AS " + groupsyn.Group_sAMAccount + ", RTRIM(" + groupsyn.Group_CN + ") + '" + groupapp + "' AS " + groupsyn.Group_CN + " INTO " + sqlgroupsTable + " FROM " + groupsyn.Group_dbTable + " WHERE " + groupsyn.Group_sAMAccount + " IS NOT NULL ORDER BY " + groupsyn.Group_CN, sqlConn); } else { sqlComm = new SqlCommand("SELECT DISTINCT RTRIM(" + groupsyn.Group_sAMAccount + ") AS " + groupsyn.Group_sAMAccount + ", RTRIM(" + groupsyn.Group_CN + ") + '" + groupapp + "' AS " + groupsyn.Group_CN + " INTO " + sqlgroupsTable + " FROM " + groupsyn.Group_dbTable + " WHERE " + groupsyn.Group_sAMAccount + " IS NOT NULL AND " + groupsyn.Group_where + " ORDER BY " + groupsyn.Group_CN, sqlConn); } try { sqlComm.CommandTimeout = 360; sqlComm.ExecuteNonQuery(); log.addTrn(sqlComm.CommandText.ToString(), "Query"); } catch (Exception ex) { log.addTrn("Failed SQL command " + sqlComm.CommandText.ToString() + " error " + ex.Message.ToString() + "\n" + ex.StackTrace.ToString(), "Error"); throw; } // generate a list of fields to ask from AD adUpdateKeys.Add("description"); adUpdateKeys.Add("CN"); // grab groups from AD log.addTrn("Get groups from AD", "Info"); groupsDataTable = tools.EnumerateGroupsInOUDataTable("OU=" + groupapp + "," + groupOU, adUpdateKeys, adGroupsTable, log); // insert groups from AD into a temp table if (groupsDataTable.Rows.Count > 0) { groupsTable = tools.Create_Table(groupsDataTable, adGroupsTable, sqlConn, log); //Find groups that we need to create log.addTrn("Query to find groups that need to be created", "Info"); add = tools.QueryNotExistsAllFields(sqlgroupsTable, groupsTable, sqlConn, groupsyn.Group_CN, adUpdateKeys[1].ToString(), log); // Create groups log.addTrn("Creating groups", "Info"); while (add.Read()) { //i++; sAMAccountName = (string)add[1].ToString().Trim(); description = (string)add[0].ToString().Trim(); groupObject.Add("sAMAccountName", sAMAccountName); groupObject.Add("CN", sAMAccountName); groupObject.Add("description", description); tools.CreateGroup("OU=" + groupapp + "," + groupOU, groupObject, log); groupObject.Clear(); } add.Close(); //time.Start(); log.addTrn("Query to find groups to delete", "Info"); delete = tools.QueryNotExistsAllFields(groupsTable, sqlgroupsTable, sqlConn, adUpdateKeys[1].ToString(), groupsyn.Group_CN, log); // delete groups in AD // i = 0; log.addTrn("Deleting groups", "Info"); while (delete.Read()) { tools.DeleteGroup("OU=" + groupapp + "," + groupOU, (string)delete[adUpdateKeys[1].ToString()].ToString().Trim(), log); } delete.Close(); // Get columns from sqlgroupsTable temp table in database get columns deprcated in favor of manual building due to cannot figure out how to get the columns of a temporary table // SQLupdateKeys = tools.GetColumns(groupsyn.DataServer, groupsyn.DBCatalog, sqlgroupsTable); // make the list of fields for the sql to check when updating note these fields must be in the same order as the AD update keys sqlUpdateKeys.Add(groupsyn.Group_sAMAccount); sqlUpdateKeys.Add(groupsyn.Group_CN); // update assumes the both ADupdateKeys and SQLupdateKeys have the same fields, listed in the same order check call to EnumerateGroupsInOU if this is wrong should be sAMAccountName, CN matching the SQL order log.addTrn("Query to find groups which need to be updated", "Info"); update = tools.CheckUpdate(sqlgroupsTable, groupsTable, groupsyn.Group_CN, adUpdateKeys[1].ToString(), sqlUpdateKeys, adUpdateKeys, sqlConn, log); // update groups in ad // last record which matches the primary key is the one which gets inserted into the database log.addTrn("Updating groups", "Info"); while (update.Read()) { // any duplicate records will attempt to be updated if slow runtimes are a problem this might be an issue // i++; sAMAccountName = (string)update[1].ToString().Trim(); description = (string)update[0].ToString().Trim(); groupObject.Add("sAMAccountName", sAMAccountName); groupObject.Add("CN", sAMAccountName); groupObject.Add("description", description); if (tools.Exists("CN=" + groupObject["CN"] + ", OU=" + groupapp + "," + groupOU) == true) { // group exists in place just needs updating tools.UpdateGroup("OU=" + groupapp + "," + groupOU, groupObject, log); // log.addTrn("Group update ; " + sAMAccountName + ",OU=" + groupapp + "," + groupOU + ";" + description); } else { // find it its on the server somewhere we will log the exception groupDN = tools.GetObjectDistinguishedName(objectClass.group, returnType.distinguishedName, groupObject["CN"], dc, log); // what if user is disabled will user mapping handle it? // groups needs to be moved and updated // tools.MoveADObject(groupDN, "LDAP://OU=" + groupapp + ',' + groupOU); // tools.UpdateGroup("OU=" + groupapp + "," + groupOU, groupObject); log.addTrn("Group cannot be updated user probabally should be in ; " + "OU=" + groupapp + "," + groupOU + " ; but was found in ; " + groupDN, "Error"); } groupObject.Clear(); } update.Close(); } // we didn't find any records in AD so there is no need for the Update or delete logic to run else { log.addTrn("Query to get list of groups to add", "Info"); sqlComm = new SqlCommand("SELECT * FROM " + sqlgroupsTable, sqlConn); try { sqlComm.CommandTimeout = 360; add = sqlComm.ExecuteReader(); log.addTrn(sqlComm.CommandText.ToString(), "Query"); log.addTrn("Adding groups", "Info"); while (add.Read()) { //i++; groupObject.Add("sAMAccountName", (string)add[1]); groupObject.Add("CN", (string)add[1]); groupObject.Add("description", (string)add[0]); tools.CreateGroup("OU=" + groupapp + "," + groupOU, groupObject, log); groupObject.Clear(); } add.Close(); } catch (Exception ex) { log.addTrn("Failed SQL command " + sqlComm.CommandText.ToString() + " error " + ex.Message.ToString() + "\n" + ex.StackTrace.ToString(), "Error"); } } // users section string sqlgroupMembersTable = "#FHC_GROUPS_sqlusersTable"; string ADgroupMembersTable = "#FHC_GROUPS_ADusersTable"; if (settingsConfig.TempTables == true) { sqlgroupMembersTable = "#FCH_GROUPS_sqlusersTable"; ADgroupMembersTable = "#FHC_GROUPS_ADusersTable"; } else { sqlgroupMembersTable = "FHC_GROUPS_sqlusersTable"; ADgroupMembersTable = "FHC_GROUPS_ADusersTable"; } SqlDataReader sqlgroups; DataTable ADusers = new DataTable(); // A little house cleaning to empty out tables log.addTrn("Clear out tables for usage", "Info"); if (settingsConfig.TempTables == false) { tools.DropTable(sqlgroupMembersTable, sqlConn, log); tools.DropTable(ADgroupMembersTable, sqlConn, log); } // grab users data from sql log.addTrn("Get users from SQL", "Info"); if (groupsyn.User_where == "") { sqlComm = new SqlCommand("SELECT DISTINCT 'CN=' + RTRIM(" + groupsyn.User_sAMAccount + ") + '," + groupsyn.BaseUserOU + "' AS " + groupsyn.User_sAMAccount + ", RTRIM(" + groupsyn.User_Group_Reference + ") + '" + groupapp + "' AS " + groupsyn.User_Group_Reference + " INTO " + sqlgroupMembersTable + " FROM " + groupsyn.User_dbTable, sqlConn); } else { sqlComm = new SqlCommand("SELECT DISTINCT 'CN=' + RTRIM(" + groupsyn.User_sAMAccount + ") + '," + groupsyn.BaseUserOU + "' AS " + groupsyn.User_sAMAccount + ", RTRIM(" + groupsyn.User_Group_Reference + ") + '" + groupapp + "' AS " + groupsyn.User_Group_Reference + " INTO " + sqlgroupMembersTable + " FROM " + groupsyn.User_dbTable + " WHERE " + groupsyn.User_where, sqlConn); } try { sqlComm.CommandTimeout = 360; sqlComm.ExecuteNonQuery(); log.addTrn(sqlComm.CommandText.ToString(), "Query"); } catch (Exception ex) { log.addTrn("Failed SQL command " + sqlComm.CommandText.ToString() + " error " + ex.Message.ToString() + "\n" + ex.StackTrace.ToString(), "Error"); } // populate datatable with users from AD groups by looping thru the list of groups from SQL and loading the cross referenced AD group members log.addTrn("Get users from AD by looping through groups from SQL and appending results to a table", "Info"); sqlComm = new SqlCommand("SELECT " + groupsyn.Group_CN + " FROM " + sqlgroupsTable, sqlConn); try { ArrayList sqlgroupsStr = new ArrayList(); sqlComm.CommandTimeout = 360; sqlgroups = sqlComm.ExecuteReader(); log.addTrn(sqlComm.CommandText.ToString(), "Query"); DataTable currentOu = new DataTable(); while (sqlgroups.Read()) { sqlgroupsStr.Add((string)sqlgroups[0]); } sqlgroups.Close(); count = 0; foreach (string key in sqlgroupsStr) { ADusers = tools.EnumerateUsersInGroupDataTable(key, ",OU=" + groupapp + "," + groupOU, groupsyn.User_sAMAccount, groupsyn.User_Group_Reference, ADgroupMembersTable, log); if (count == 0) { // make the temp table for ou comparisons the datatable must have somethign in it to make it tools.Create_Table(ADusers, ADgroupMembersTable, sqlConn, log); } else { // table is already made now we need to only add to it tools.Append_to_Table(ADusers, ADgroupMembersTable, sqlConn, log); } count++; } // hopefully merge acts as an append // ADusers.Merge(tools.EnumerateUsersInGroupDataTable((string)sqlgroups[0], ",OU=" + groupapp + "," + groupOU, groupsyn.User_sAMAccount, groupsyn.User_Group_Reference, ADgroupMembersTable, log)); // currentOu = tools.EnumerateUsersInGroupDataTable( , ",OU=" + groupapp + "," + groupOU, groupsyn.User_sAMAccount, groupsyn.User_Group_Reference, ADgroupMembersTable, log); // tools.Append_to_Table(currentOu, ADgroupMembersTable, sqlConn, log); } catch (Exception ex) { log.addTrn("Failed SQL command " + sqlComm.CommandText.ToString() + " error " + ex.Message.ToString() + "\n" + ex.StackTrace.ToString(), "Error"); } // compare and add/remove log.addTrn("Query to find the users to add ", "Info"); add = tools.QueryNotExistsAllFields(sqlgroupMembersTable, ADgroupMembersTable, sqlConn, groupsyn.User_sAMAccount, ADusers.Columns[0].ColumnName, log); try { while (add.Read()) { tools.AddUserToGroup((string)add[0], "CN=" + (string)add[1] + ",OU=" + groupapp + "," + groupOU, false, dc, log); } } catch (Exception ex) { log.addTrn("Issue adding group datareader is null " + ex.Message.ToString() + "\n" + ex.StackTrace.ToString(), "Error"); } groupObject.Clear(); add.Close(); SqlCommand sqlComm2 = new SqlCommand(); string recordCount = ""; sqlComm2 = new SqlCommand("select count(" + groupsyn.Group_CN + ") FROM " + sqlgroupMembersTable, sqlConn); sqlComm2.CommandTimeout = 360; recordCount = sqlComm2.ExecuteScalar().ToString(); sqlComm2.Dispose(); if (recordCount != "0") { // setup update keys adUpdateKeys.Clear(); sqlUpdateKeys.Clear(); adUpdateKeys.Add(ADusers.Columns[1].ColumnName); adUpdateKeys.Add(ADusers.Columns[0].ColumnName); sqlUpdateKeys.Add(ADusers.Columns[1].ColumnName); sqlUpdateKeys.Add(ADusers.Columns[0].ColumnName); // get list of keys which have differed. We will delete them and then next time they will be readded as the correct key\ // users which need to be updated just get deleted and recreadted later where they need to be log.addTrn("Query to see which users need to be deleted", "Info"); delete = tools.CheckUpdate( ADgroupMembersTable, sqlgroupMembersTable, ADusers.Columns[0].ColumnName, groupsyn.User_sAMAccount, adUpdateKeys, sqlUpdateKeys, sqlConn, log); // delete = tools.QueryNotExistsAllFields(ADgroupMembersTable, sqlgroupMembersTable, sqlConn, ADusers.Columns[1].ColumnName, groupsyn.User_Group_Reference, log); // delete groups in AD log.addTrn("Deleteing users", "Info"); while (delete.Read()) { tools.RemoveUserFromGroup((string)delete[1], "CN=" + (string)delete[0] + ",OU=" + groupapp + "," + groupOU, log); } delete.Close(); } sqlConn.Close(); }