I need to update some AD querying code and want to use the new .NET 3.5 System.DirectoryServices.AccountManagement objects to query AD in a managed way as opposed to our current method of using LDAP.
I encountered an odd problem when reading the UserPrincipal.Guid value. It turns out that it is similar to but different from the Guids we have been using via LDAP.
At first they looked completely different, but on a second take, I saw that the last half are identical and the first half are simply transposed ie:
New (.NET 3.5) Method GUID: 01234567-89ab-cdef-0123-456789abcdef
Prev (LDAP) Method GUID: 67452301-ab89-efcd-0123-456789abcdef
I checked the LDAP code and saw that we were using the SearchResult.GetDirectoryEntry().NativeGuid field to get the Old Guid.
It has a different property called SearchResult.GetDirectoryEntry().Guid which is identical to the GUID I retrieve using the new .Net 3.5 classes.
My question is, why are they (sort of) different and which should I use?
When a new domain user or group account is created, AD assigns the new object a globally unique identifier (GUID), which is a 128-bit value that is unique not only in the enterprise but also across the world. GUIDs are assigned to every object created by Active Directory, not just User and Group objects.
ObjectGUID is an Attribute-Names which represents a Universally Unique Identifier as used in Microsoft Active Directory.
As you've guessed they are both representations of the exact same value. The difference is in the formatting; DirectoryEntry.NativeGUID
is displayed in little-endian order (without dashes) which is how it's stored "natively" in the directory service and UserPricipal.GUID/DirectoryEntry.GUID
is displayed in big-endian order (with dashes). See the Wikipedia article on Endianess for details.
So when you print out the value for NativeGUID (a string) it should not show any dashes (like your example does) unless you create a new GUID using the string as input (Guid ng = new Guid(de.NativeGuid);
). That will create some confusion...
The important thing is not to mix the two when storing the GUIDs in an external data source or storing a NativeGUID as a big-endian GUID.
So I'd go for the UserPricipal.GUID/DirectoryEntry.GUID because that's how the objectGUID attribute is displayed using most Windows management tools (such as Active Directory Users and Computers and ADSI Edit) and how it's stored and displayed in SQL Server when you use the uniqueidentifier
data type. Also; you'll need to go "below" UserPrincipal (GetUnderlyingObject()
) to get the NativeGUID-value (or convert the UserPrincipal.GUID property to little-endian).
So I guess you'll have to decide whether to migrate your existing "external" data to the GUID-format or to continue using the NativeGUID-format. Right now I'm guessing you're somewhere in between.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With