Further to the series of posts on importing data from Active Directory, I’ve run into a new issue. For this client I built the exact same solution as described here Getting Around Active Directory Paging on SSIS Import, but got this lovely error message: “Index was out of range. Must be non-negative and less than the size of the collection.” It turns out there were empty values in some of the single-value fields. I hadn’t run into this previously, but I found a neat solution.
In the original solution I outlined how to create a simple SSIS script task in C# to import single value fields from Active Directory. I’ve added to this code to create a solution to import empty single-value fields.
A For Each statement for single-value fields has been added to the script to check if the field is empty before setting the variable value. Even though there is only one possible value for a single value field, the For Each statement still works nicely to check if it’s empty. Here is the code snippet of the For Each statement:
//If the property is null, set the variable to blank, else set it to the value in the property string Mail = ""; ResultPropertyValueCollection valueCollectionMail = results.Properties["Mail"]; foreach (String sField in valueCollectionMail) { //Replace any single quotes with two single quotes for SQL Statement
Mail = sField.Replace("'", "''"); }
Here is the complete code. for more details on how to create the SSIS package and set up the references for the script task, please see Getting Around Active Directory Paging on SSIS Import.
public void Main() { //Set up the AD connection; using (DirectorySearcher ds = new DirectorySearcher()) { //Edit the filter for your purposes; ds.Filter = "(&(objectClass=user))"; ds.SearchScope = SearchScope.Subtree; ds.PageSize = 1000; //This will page through the records 1000 at a time; //Set up SQL Connection string sSqlConn = Dts.Variables["SqlConn"].Value.ToString(); SqlConnection sqlConnection1 = new SqlConnection(sSqlConn); SqlCommand cmd = new SqlCommand(); SqlDataReader reader; cmd.CommandType = CommandType.Text; cmd.Connection = sqlConnection1; //Read all records in AD that meet the search criteria into a Collection using (SearchResultCollection src = ds.FindAll()) { //For each record object in the Collection, insert a record into the SQL table foreach (SearchResult results in src) { string sAMAccountName = results.Properties["sAMAccountName"][0].ToString(); string objectClass = results.Properties["objectClass"][0].ToString(); //If the property is null, set the variable to blank, otherweise set it to the value in the property string Mail = ""; ResultPropertyValueCollection valueCollectionMail = results.Properties["Mail"]; foreach (String sField in valueCollectionMail) { Mail = sField.Replace("'", "''"); //Replace any single quotes with two single quotes for SQL Statement } //If the property is null, set the variable to blank, otherweise set it to the value in the property string displayName = ""; ResultPropertyValueCollection valueCollectiondisplayName = results.Properties["displayName"]; foreach (String sField in valueCollectiondisplayName) { displayName = sField.Replace("'", "''"); //Replace any single quotes with two single quotes for SQL Statement } sqlConnection1.Open(); cmd.CommandText = "INSERT INTO AD_Users (sAMAccountName, objectClass, Mail, displayName) VALUES ('" + sAMAccountName + "','" + objectClass + "','" + Mail + "','" + displayName +"')"; reader = cmd.ExecuteReader(); sqlConnection1.Close(); } } } }
Here are links to the other posts in the Active Directory series:
Importing Data from Active Directory using SSIS Data Flows
How to Query Multi-Value Fields in Active Directory using SSIS