bdkdavid
bdkdavid

Reputation: 223

Active Directory Search displaying properties GUID and SID returns system.Byte[] instead of Actual Values

This code produces the following output:

my email address,
System.Byte[], this should be SID
System.Byte[], this should be GUID
my name,
First Name,
last Name,
Middle Initial

Code:

Console.WriteLine(((byte)de.Properties["objectSid"].Value.ToString());

I attempted to cast the above line. I get an error

Cannot convert type string to byte

string ObjGuid = BitConverter.ToString(de.Properties["objectguid"].Value);

I attempted the above line of code same response

((byte)de.Properties["ObjectGUID"]).Value.ToString();

Cannot convert type SystemDirectoryServices.PropertyValueCollection to byte

byte one = Encoding.UTF8.GetString(de.Properties["ObjectGUID"]));

Cannot convert type SystemDirectoryServices.PropertyValueCollection to byte

These are the items that I have attempted. Console.WriteLine requires a string.

The problem that I see is that I am getting a list of items.

From this list, I am getting the underlying properties.

I am only collecting a few items of the collection of properties.

I am searching inside the underlying collection and I am attempting to convert that item to a string

I think this is a basic conversion from byte to string. I might have an issue with searching and manipulating an object hierarchy.

Can someone help me with this concept?

using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Principal;
using System.Threading;
using System.DirectoryServices.AccountManagement;
using System.DirectoryServices;
using System.IO;
using System.Data;
using System.Management.Automation;
using System.Collections.ObjectModel;

//using System.DirectoryServices;
namespace TestRole
{
  class Program
  {
    static void Main(string[] args)
    {
        //Requires Add References to using System.DirectoryServices.AccountManagement;
        // and using System.DirectoryServices;


        PrincipalContext ctx = new 
               PrincipalContext(ContextType.Domain,Environment.UserDomainName);
        UserPrincipal user = new UserPrincipal(ctx);

        user.EmailAddress = "MyEmail@com";

        PrincipalSearcher ps = new PrincipalSearcher();
        ps.QueryFilter = user;
        PrincipalSearchResult<Principal> results = ps.FindAll();
        Principal pc = results.ToList()[0];
        DirectoryEntry de = (DirectoryEntry)pc.GetUnderlyingObject();

        Console.WriteLine(de.Properties["mail"].Value.ToString());

      //old code
        ////Console.WriteLine(de.Properties["Sid"].Value.ToString());
        //Console.WriteLine(de.Properties["objectSid"].Value.ToString());
        //Console.WriteLine(de.Properties["objectGUID"].Value.ToString());
        //This code does the job
            var sid = new 
             SecurityIdentifier((byte[])de.Properties["objectSid"].Value, 0);
               Console.WriteLine(sid);
            var guid = new Guid((Byte[])de.Properties["objectGUID"].Value);
               Console.WriteLine(guid.ToString());


        Console.WriteLine(de.Properties["Name"].Value.ToString());
        Console.WriteLine(de.Properties["givenname"].Value.ToString());
        Console.WriteLine(de.Properties["sn"].Value.ToString());
        Console.WriteLine(de.Properties["initials"].Value.ToString());


        Console.WriteLine(Environment.UserDomainName);


        //Console.WriteLine(de.Properties["StructuralObjectClass"].Value.ToString());

       }
    }
}

Upvotes: 1

Views: 1870

Answers (1)

You need to check the type of the returned values before using or converting them. The return type of de.Properties["anyPropHere"].Value is object, because it will return different types, depending on the queried property.

If you want to get the objectSid as string you have to convert the returned bytes using the SecurityIdentifier, as described in this post

byte[] sid = (byte[])de.Properties["objectSid"].Value;
string sidStr = (new SecurityIdentifier((byte[])sid, 0)).ToString();

Upvotes: 1

Related Questions