I am writing some automation to handle Active Directory objects, mostly managing ServiceConnectionPoints (SCP) and regular Group objects.
If you want to retrieve multiple LDAP Attributes having the same name (like the keywords collection of an SCP), you will have a bad time when using ActiveDirectory.getEntry(), because it has no public Method documented to retrieve a collection of a given Attribute (like for example if you have multiple keywords as an array). You can retrieve the first one, that’s it!
After some search I figured out that there is a lower-level LdapClient, which can be used to retrieve an LdapEntry, that has the magic getAttributes(), that can help you. So that’s good, we like lower level classes if we need to do advanced stuff.
However, when you want to get the objectGUID
or the objectGUID
, those are binary values…

Microsoft Active Directory stores their SID Structures and UUID/GUID in binary hexadecimal byte arrays, instead of string values.
When using VMware vRealize Orchestrator to interface via the Active Directory Plugin, and want to get the string representation, you are mostly stuck with JavaScript and the difficult task to convert the binary value to string. I was definitely stuck. Google resulted in some examples and results, but not all were really usable.
A strange thing I have noticed is that the original code found on those pages was generating very bad SID-s. While debugging I found out that using LdapAttribute.getValueByteArray()
will return signed integers, none above 256… For example, these are the last 6 bytes of my SID when using getValueByteArray():
[ ... -27, -20, -44, 21, 9, 0]
And this is what I get when getting the binary representation as hex in a different editor:
[ ... 0xe5, 0xec, 0xd4, 0x15, 0x09, 0x00]
We see from the back, that 0 and 9 are OK, 0x15 is also 21 in decimal, so that’s OK. The issues start with all the negative numbers, those are not good. However, after some math, when you “add” them to 256, the resulting numbers converted to hex now make sense:
256 + (-44) = 212 = 0xd4
256 + (-20) = 236 = 0xec
256 + (-27) = 229 = 0xe5
So, at the end, I managed to get them working, and the patched versions appear to produce the same values as seen in other tools (I am using Apache Directory Studio).
Disclaimer: The code below are modified version of the referenced sources, so I am not taking any claims that I wrote them, nor do I provide any support or responsibility if you use them.
function sidBufferToString(buf) {
// original> https://gist.github.com/Krizzzn/0ae47f280cca9749c67759a9adedc015
var asc, end;
var i;
if (buf == null) { return null; }
var version = buf[0];
var subAuthorityCount = buf[1];
var result = [];
for (i = 2; i <= 7; i++) {
result.push(buf[i].toString(16));
}
var identifierAuthority = parseInt(result.join(''), 16);
var sidString = 'S-' + version + '-' + identifierAuthority;
function _n(s) {
if (s < 0) {
// Some weird f'up where vRO gets the byte array, as some
// weird signed int, so we correct negatives into positives
s = 256 + s;
}
s = s.toString(16);
if (s.length < 2) {
s = "0" + s;
}
return s;
};
for (i = 0, end = subAuthorityCount-1, asc = 0 <= end; asc ? i <= end : i >= end; asc ? i++ : i--) {
var subAuthOffset = i * 4;
var sidpart = parseInt(
// the SID Part is little-endian, so we build the number from the "right" side
_n(buf[11 + subAuthOffset]) + _n(buf[10 + subAuthOffset]) + _n(buf[9 + subAuthOffset]) + _n(buf[8 + subAuthOffset])
, 16
);
sidString += "-" + sidpart
}
return sidString;
};
function guidBufferToString(guidValueArr) {
// original> https://stackoverflow.com/a/59019552
guidValueArr = attr.getValueByteArray();
var guid = "", i;
function _padLeft( obj, len, str ) {
var s = obj;
if ( str.length > 0 ) {
while ( s.length < len ) {
s = ( str + s );
};
}
return s;
}
for ( i = 0; i < guidValueArr.length; i ++ ) {
// Some weird f'up where vRO gets the byte array as some
// weird signed int, so we correct negatives into positives
guid += _padLeft((guidValueArr[i] < 0 ? 256+guidValueArr[i] : guidValueArr[i]).toString(16), 2,"0");
}
return guid.replace(/(.{2})(.{2})(.{2})(.{2})(.{2})(.{2})(.{2})(.{2})(.{4})(.{12})/, "$4$3$2$1-$6$5-$8$7-$9-$10");
}
Have fun, I hope I saved some hours of your life.