Export hexadecimal AD extended attribute collection

Someone Who loves giraffes 21 Reputation points
2022-11-19T00:37:15.75+00:00

Something I 've been trying to do for a short while and perhaps someone here can help out
AD extended attributes stored as a collection are in a binary format and can't be exported using export-csv and the like

[What I need]
I'm looking for a script and/or clues on how to go about exporting AD user extended attribute collection data in hexadecimal rather than converted decimal into an excel spreadsheet

[Example]
Get-ADUser -Properties x500uniqueidentifier -Filter * | Select sAMAccountName, x500uniqueidentifier |fl

1: Listing the data in powershell
the example does not provide the data in hexadecimal but rather the converted decimal data from within the collection data (try it and you'll see what I mean)

[Update the export is working but wrong data type - see update01 below]
2: Attempting to export the data to csv by appending | export-csv <some_path>
even if it could provide the data, an export wouldn't work and would instead show "Microsoft.ActiveDirectory.Management.ADPropertyValueCollection" even if the value wasn't present for the object, a non-null value/populated.

[Update01]: Changing the encoding fixes the export issue so now I'm focused on obtaining raw hex rather than converted decimal
get-aduser <someuser> -Properties *| select name, @{n='x500uniqueIdentifier';e={[system.text.encoding]::ascii.GetString([system.text.encoding]::unicode.GetBytes($($_.x500uniqueIdentifier)))}} | export-csv <somepath>

any ideas would be appreciated. Thank you

Windows for business Windows Client for IT Pros Directory services Active Directory
Windows for business Windows Server User experience PowerShell
Microsoft Security Microsoft Entra Microsoft Entra ID
0 comments No comments
{count} votes

Accepted answer
  1. Pradeep-0762 81 Reputation points
    2022-11-22T02:39:22.727+00:00

    Try this @Someone Who loves giraffes

    $hex = get-aduser <user>-Properties x500uniqueIdentifier| select @{n='Hex500uniqueIdentifier';e={$($.x500uniqueIdentifier)|%{[system.convert]::ToString($,16)}}}

    [string]$hex.Hex500uniqueIdentifier

    1 person found this answer helpful.
    0 comments No comments

4 additional answers

Sort by: Most helpful
  1. Rich Matheisen 47,901 Reputation points
    2022-11-19T20:55:12.597+00:00

    The LDAP type is defined as "bitstring", but I don't know how that's defined by PowerShell.

    Maybe having the object type would help:

    $b = Get-ADUser -Properties x500uniqueidentifier -Filter "some filter-value-for one user"  
    $b.gettype()  
    $b | Format-Hex  
    $b | format-hex -Encoding Unicode  
    

    Also, have a look at the .Net System.Convert class. Can the property be converted to a byte array?

    1 person found this answer helpful.
    0 comments No comments

  2. Rich Matheisen 47,901 Reputation points
    2022-11-20T16:34:58.977+00:00

    I still haven't found an example of the "bitstream" encoding, but I think it may correspond to the ADS Type "ADSTYPE_OCTET_STRING". If that's true, the encoding would be described in the LDAP BER (Basic Encoding Rules): Basic%20Encoding%20Rules.

    The value would begin with the hex value identifying the element type. In this case it would be a 0x04. Following that would be the length of the value (in octets/bytes). Following that would be the string value. That value will be the binary encoding of each octet/byte. However, the octets/bytes may, or may not, represent human-readable data.

    The property x500uniqueIdentifier is defined as a multi-valued property. So, within the bitstring, after ignoring the leading 0x04, the next octet/byte would define the length of the 1st bitstring. To get the next value (if there is one), skip ahead that many octets/bytes to find the byte signifying the length of the next bitstring. Continue that process until you reach the end of the string.

    1 person found this answer helpful.
    0 comments No comments

  3. Rich Matheisen 47,901 Reputation points
    2022-11-20T22:30:51.873+00:00

    Assuming(!) that you have a string with the bitstring in it, this should get you the hex value:

    $s = "X"  
    for ($i=0; $i -le $h.length; $i++){  
        $s += "{0:x2}" -f [System.Convert]::ToUInt16($h[$i])  
    }  
    $s  
    

    If the value of the data was "hello! (in ASCII), preceded by the type identifier (X04) and the string length (X06), the output would look like this:

    X040668656c6c6f21

    If you don't want the leading "X", set the value of $s to an empty string.

    1 person found this answer helpful.
    0 comments No comments

  4. Someone Who loves giraffes 21 Reputation points
    2022-11-23T21:40:06.967+00:00

    Pradeep's answer works, thank you!
    Thank you Rich M. for your assistance with coming up with a solution, great work! Have a safe and wonderful Thanksgiving

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.