How to convert PropertyValueCollection to a C # list? (ResultPropertyCollection, SearchResult, LDAP)

I sent a request to read some materials from Active Directory. But the result has a kind of "ResultPropertyCollection" as a property. Does any authority know how I can convert it to a list (like a general list)?

DirectoryEntry de = new DirectoryEntry("LDAP://" + this.rootLDAP); DirectorySearcher ds = new DirectorySearcher(de, "(& (objectcategory=Group))"); ds.PropertiesToLoad.Add("samaccountname"); ds.PropertiesToLoad.Add("memberof"); ds.PropertiesToLoad.Add("samaccounttype"); ds.PropertiesToLoad.Add("grouptype"); ds.PropertiesToLoad.Add("member"); ds.PropertiesToLoad.Add("objectcategory"); var r = ( from SearchResult sr in ds.FindAll() select sr ) .ToArray(); 

Thanks Farzad

+4
source share
4 answers

You cannot - at least not very easily.

If you just want to have a list of SearchResult types, you can use:

 var r = ds.FindAll(); List<SearchResult> results = new List<SearchResult>(); foreach (SearchResult sr in r) { results.Add(sr); } 

But if you want to get the actual values ​​from the search results, you need to do more work.

Basically, this collection contains all the properties you defined for your search β€” at least as long as they contain a value!

So what you need to do is create a class to hold these values. These two elements: memberOf and member can themselves contain several values ​​(they are "multi-valued" attributes in AD) - for this you need a list of lines:

 public class YourType { public string SamAccountName { get; set; } public int SamAccountType { get; set; } public int GroupType { get; set; } public string ObjectCategory { get; set; } public List<string> MemberOf { get; set; } public List<string> Member { get; set; } } 

Then, as soon as you have the search result, you need to iterate over the results and create new instances of YourType for each search result and insert them into the List<YourType> :

 foreach(SearchResult sr in ds.FindAll()) { YourType newRecord = ConvertToYourType(sr); } 

and in this method you need to check the .Properties collection for each value and extract it:

 public YourType ConvertToYourType(SearchResult result) { YourType returnValue = new YourType(); returnValue.MemberOf = new List<string>(); returnValue.Member = new List<string>(); if(result.Properties["samAccountName"] != null && result.Properties["samAccountName"].Count > 0) { returnValue.SamAccountName = result.Properties["samAccountName"][0].ToString(); } // ..... and so on for each of your values you need to extracxt return returnValue; } 
+7
source

This may not be the complete solution or the correct answer. Below is the only solution to convert SearchResultCollection to List

 SearchResultCollection rc = ds.FindAll(); List<SearchResult> resultList = rc.Cast<SearchResult>().ToList(); // Now loop through the list foreach(SearchResult sr in resultList) { //.. get properties here } 
0
source

Can't we use something like this? (Since I'm currently using it)

 ds.FindAll().Cast<SearchResult>().Select(result => new Address(result.GetDirectoryEntry())).ToList(); public class Address { internal Address(DirectoryEntry entry) { // // You can get one or more of the following properties: // // // objectClass // cn // description // givenName // distinguishedName // instanceType // whenCreated // whenChanged // displayName // uSNCreated // memberOf // uSNChanged // homeMTA // proxyAddresses // homeMDB // mDBUseDefaults // mailNickname // protocolSettings // name // objectGUID // userAccountControl // badPwdCount // codePage // countryCode // badPasswordTime // lastLogon // pwdLastSet // primaryGroupID // objectSid // accountExpires // logonCount // sAMAccountName // sAMAccountType // showInAddressBook // legacyExchangeDN // userPrincipalName // lockoutTime // objectCategory // dSCorePropagationData // lastLogonTimestamp // textEncodedORAddress // mail // msExchPoliciesExcluded // msExchMailboxTemplateLink // msExchRecipientDisplayType // msExchUserCulture // msExchVersion // msExchRecipientTypeDetails // msExchHomeServerName // msExchALObjectVersion // msExchMailboxSecurityDescriptor // msExchUserAccountControl // msExchMailboxGuid // nTSecurityDescriptor // As an example we get only two properties this.DisplayName = (string)entry.Properties["displayName"].Value; this.Mail = (string)entry.Properties["mail"].Value; Manager = (string)entry.Properties["manager"].Value; } public string DisplayName { get; private set; } public string Manager { get; private set; } public string Mail { get; private set; } } 
0
source

At first I was also embarrassed, but the thing is to get the type of the property collection element. As soon as I found out that the type of the property item is System.Collections.DictionaryEntry and that this value is a collection made from ResultPropertyValueCollection elements, simple iterations are possible.

Here is what I ended up with:

  bool attemptResult = false; string ldap = "LDAP:<Your AD specific connection string>"; DirectoryEntry entry = new DirectoryEntry(ldap, username, password, AuthenticationTypes.Secure); try { DirectorySearcher searcher = new DirectorySearcher(entry); searcher.Filter = "(&(objectClass=User)(sAMAccountName=" + username + "))"; SearchResult one = searcher.FindOne(); attemptResult = true; string properties = ""; string userData = JsonConvert.SerializeObject(one.Properties); foreach (System.Collections.DictionaryEntry de in one.Properties) { properties += (properties.Length > 0 ? ",\n" : ""); properties += "\"" + de.Key + "\": ["; ResultPropertyValueCollection vc = ((ResultPropertyValueCollection)de.Value); foreach (var val in vc) { properties += "{\"type\": \"" + val.GetType().Name + "\", \"value\"; \"" + val.ToString() + "\"}"; } properties += "]"; } properties = properties.Replace("}{", "},{"); string displayName = one.Properties["displayname"][0].ToString(); string givenName = one.Properties["givenname"][0].ToString(); string lastname = one.Properties["sn"][0].ToString(); } catch (Exception e) { //log the error; } return attemptResult; 

Check out the quick and easy conversion to string using JsonConvert.SerializeObject. This is a one-step conversion.

I also performed a personalized conversion to string using foreach iterations. It was more of a self-learning exercise, from which I get that after getting a value for a named property, I can find out if the property has zero, one or more values ​​and acts accordingly, even checking the type of the object, if necessary.

Here is the value obtained from both the string variables, properties, and userData (some elements are removed for privacy).

 /* Value of userData Obtained with Json serializator*/ {"givenname":["First Name"],"samaccountname":["User.Name"],"cn":["First Name Last Name"],"pwdlastset":[131641282827115142],"whencreated":["2017-10-12T22:16:43"],"badpwdcount":[0],"displayname":["First Name Last Name"],"lastlogon":[131648243091569908],"samaccounttype":[805306368],"countrycode":[0],"objectguid":["SOMETHINGBASE64LIKE=="],"usnchanged":[52144153],"manager":["CN=The Name Of A Person,OU=Department Name,OU=City,OU=GroupName ,DC=Domain,DC=com"],"whenchanged":["2018-03-02T23:21:54"],"name":["First Name Last Name"],"objectsid":["SOMETHINGBASE64LIKE=="],"lastlogoff":[0],"lockouttime":[0],"badpasswordtime":[131647632246625185],"instancetype":[4],"primarygroupid":[513],"objectcategory":["CN=Person,CN=Schema,CN=Configuration,DC=Domain,DC=com"],"logoncount":[1073],"useraccountcontrol":[512],"description":["Some text"],"dscorepropagationdata":["1601-01-01T00:00:00"],"distinguishedname":["CN=First Name Last Name,OU=Department Name,OU=City,OU=GroupName ,DC=Domain,DC=com"],"objectclass":["top","person","organizationalPerson","user"],"adspath":["LDAP://Server/CN=First Name Last Name,OU=Department Name,OU=City,OU=GroupName ,DC=Domain,DC=com"],"usncreated":[39705915],"lastlogontimestamp":[131643676396776065],"userprincipalname":[" User.Name@Domain.com "],"employeeid":["99999"],"accountexpires":[9223372036854775807],"department":["DepartmentName"],"codepage":[0],"sn":["Last Name"]} /* value of properties, the string I concatenated */ "givenname": [{"type": "String", "value"; "First Name"}], "samaccountname": [{"type": "String", "value"; "User.Name"}], "cn": [{"type": "String", "value"; "First Name Last name"}], "pwdlastset": [{"type": "Int64", "value"; "131641282827115142"}], "whencreated": [{"type": "DateTime", "value"; "12/10/2017 10:16:43 pm"}], "badpwdcount": [{"type": "Int32", "value"; "0"}], "displayname": [{"type": "String", "value"; "First Name Last name"}], "lastlogon": [{"type": "Int64", "value"; "131648243091569908"}], "samaccounttype": [{"type": "Int32", "value"; "805306368"}], "countrycode": [{"type": "Int32", "value"; "0"}], "objectguid": [{"type": "Byte[]", "value"; "System.Byte[]"}], "usnchanged": [{"type": "Int64", "value"; "52144153"}], "manager": [{"type": "String", "value"; "CN=Some Person Name,OU=Department name,OU=City,OU=Group Name,DC=Domain,DC=com"}], "whenchanged": [{"type": "DateTime", "value"; "2/3/2018 11:21:54 pm"}], "name": [{"type": "String", "value"; "First Name Last name"}], "objectsid": [{"type": "Byte[]", "value"; "System.Byte[]"}], "lastlogoff": [{"type": "Int64", "value"; "0"}], "lockouttime": [{"type": "Int64", "value"; "0"}], "badpasswordtime": [{"type": "Int64", "value"; "131647632246625185"}], "instancetype": [{"type": "Int32", "value"; "4"}], "primarygroupid": [{"type": "Int32", "value"; "513"}], "objectcategory": [{"type": "String", "value"; "CN=Person,CN=Schema,CN=Configuration,DC=Domain,DC=com"}], "logoncount": [{"type": "Int32", "value"; "1073"}], "useraccountcontrol": [{"type": "Int32", "value"; "512"}], "description": [{"type": "String", "value"; "13065, PROGRAMADOR SENIOR"}], "dscorepropagationdata": [{"type": "DateTime", "value"; "1/1/1601 12:00:00 am"}], "distinguishedname": [{"type": "String", "value"; "CN=First Name Last name,OU=Department name,OU=City,OU=Group Name,DC=Domain,DC=com"}], "objectclass": [{"type": "String", "value"; "top"},{"type": "String", "value"; "person"},{"type": "String", "value"; "organizationalPerson"},{"type": "String", "value"; "user"}], "adspath": [{"type": "String", "value"; "LDAP://SERVERNAME/CN=First Name Last name,OU=Department name,OU=City,OU=Group Name,DC=Domain,DC=com"}], "usncreated": [{"type": "Int64", "value"; "39705915"}], "lastlogontimestamp": [{"type": "Int64", "value"; "131643676396776065"}], "userprincipalname": [{"type": "String", "value"; " User.Name@Domain.com "}], "employeeid": [{"type": "String", "value"; "13065"}], "accountexpires": [{"type": "Int64", "value"; "9223372036854775807"}], "department": [{"type": "String", "value"; "IT"}], "codepage": [{"type": "Int32", "value"; "0"}], "sn": [{"type": "String", "value"; "Last name"}] 

As you can see, some properties have more than one value. So, to get a simple general list of properties, you will need to decide what to do with the multi-valued properties. Most likely, you would like to have all the values ​​as strings, so multiple values ​​can simply be combined using a suitable separator.

0
source

Source: https://habr.com/ru/post/1381112/


All Articles