Working with Binary Data (GUIDs) in VBScript

Originally published March 9, 2005

 

Recently, I've spent a great deal of time learning to deal with GUIDs and other somewhat arbitrary binary data within VBScript. While it isn't easy to figure out how, and the conventional wisdom says “don't do it”, after establishing some basic rules and tools, it's actually pretty easy.

Don't expect that the performance will be superb...here are the fruits of my investigations and labors.

This program does a couple of silly things, just for testing:

1) Get a GUID from a user object (note that this is returned to VBScript as a Byte() array - which VBScript doesn't handle easily, natively).

2) Convert the GUID to a string array so that it can be easily handled in VBScript.

3) Escape the string array so that it can be used in an LDAP query for that GUID.

4) Do an LDAP search

5) Convert the string array GUID back to a byte array and compare them.

That's all, folks!

 Option Explicit

 Dim Com, Conn, Rs  ' for ADO
 Dim objUser, s, strQuery, objRootDSE, strNamingContext
 Dim newArr, strGUID

 Set objRootDSE = GetObject ("LDAP://RootDSE")
 strNamingContext = objRootDSE.Get ("defaultNamingContext")
 Set objRootDSE = Nothing

 Set objUser = Getobject ("LDAP://CN=Michael B. Smith,CN=Users," & strNamingContext)

 s = myADsEncodeBinaryData (objUser.msExchMailboxGUID)
 strGUID = OctetToHexStr (objUser.msExchMailboxGUID)
 wscript.echo "objUser.msExchMailboxGUID Type = " & Typename (objUser.msExchMailboxGUID)
 wscript.echo "objUser.msExchMailboxGUID Size = " & LenB (objUser.msExchMailboxGUID)

 Call InitializeADSI

 strQuery = "<LDAP://" & strNamingContext & ">;" & _
  "(msExchMailboxGuid=" & s & ");" & _
  "name,distinguishedName;" & _
  "subtree"

 wscript.echo strquery

 Call DoLDAPQuery (strQuery, Rs)

 wscript.echo "recordcount = " & rs.recordcount

 While not rs.eof
  wscript.echo "name = " & rs.fields ("name")
  wscript.echo "dn = " & rs.fields ("distinguishedname")

  rs.MoveNext
 Wend

 Call ConvertHexStringToByteArray (strGUID, newArr)
 wscript.echo "newArr Type = " & Typename (newArr)
 wscript.echo "newArr Size = " & LenB (newArr)

 If strGUID = OctetToHexStr (newArr) Then
  wscript.echo "Same!"
 Else
  wscript.echo "Different!"
 End If

 Set objUser = Nothing

 Call FinishLDAPQuery (rs)

 Call DoneWithADSI

Function myADsEncodeBinaryData (arrByte)
 Dim str, s, i

 str = OctetToHexStr (arrByte)

 WScript.Echo "Length = " & len(str) & " '" & str & "'"

 s = ""
 For i = 1 to Len (str) Step 2
  s = s & "\" & Mid (str, i, 2)
 Next

 WScript.Echo s

 myADsEncodeBinaryData = s
End Function

Function OctetToHexStr (arrbytOctet)
 ' Function to convert OctetString (byte array) to Hex string.

 ' Code from Richard Mueller, a MS MVP in Scripting and ADSI

 Dim k

 OctetToHexStr = ""

 For k = 1 To Lenb (arrbytOctet)
  OctetToHexStr = OctetToHexStr _
        & Right("0" & Hex(Ascb(Midb(arrbytOctet, k, 1))), 2)
 Next
End Function

Sub ConvertHexStringToByteArray (ByVal strHexString, ByRef pByteArray)
 Dim fso, stream, temp, ts, n
 ' This is an elegant way to convert a hex string to a Byte
 ' array. Typename(pByteArray) will return Byte(). pByteArray
 ' should be a null variant upon entry. strHexString should be
 ' an ASCII string containing nothing but hex characters, e.g.,
 ' FD70C1BC2206240B828F7AE31FEB55BE

 ' Code from Michael Harris, a MS MVP in Scripting

 Set fso = CreateObject ("scripting.filesystemobject")
 Set stream = CreateObject ("adodb.stream")

 temp = fso.gettempname ()
 Set ts = fso.createtextfile (temp)

 For n = 1 To (Len (strHexString) - 1) step 2
  ts.write Chr ("&h" & Mid (strHexString, n, 2))
 Next

 ts.close

 stream.type = 1
 stream.open
 stream.loadfromfile temp

 pByteArray = stream.read

 stream.close
 fso.deletefile temp

 Set stream = Nothing
 Set fso = Nothing
End Sub

Sub InitializeADSI
 Set Com  = WScript.CreateObject ("ADODB.Command")
 Set Conn = WScript.CreateObject ("ADODB.Connection")

 ' Open the connection.
 Conn.Provider = "ADsDSOObject"
 Conn.Open "ADs Provider"
End Sub

Sub DoneWithADSI
 Conn.Close

 Set Com  = Nothing
 Set Conn = Nothing
End Sub

Sub DoLDAPQuery (strLDAPQuery, resultSet)
 Com.ActiveConnection = Conn
 Com.CommandText      = strLDAPQuery

 Set resultSet = Com.Execute

End Sub

Sub FinishLDAPQuery (resultSet)
 resultSet.Close

 Set resultSet = Nothing
End Sub

Published Tuesday, November 13, 2007 7:45 PM by michael
Filed under: ,

Comments

Tuesday, November 13, 2007 7:51 PM by Michael's meanderings...

# Creating an Offline Address List in VBScript

Originally published April 30, 2005 Given the techniques we learned in this article about working with

Thursday, November 13, 2008 6:46 AM by Ken Brumfield's Blog

# Managing netbootGuid

The attribute on AD computer objects netbootGuid is very important to allowing some deployment options