VBScript and REG_BINARY registry values

Pain in the neck huh?

Here’s some stuff I wrote to get around the limitations.

Write a REG_BINARY

Sub regWriteBinary(sRegKey, sRegValue, sBinaryData)
      ' Expects sBinaryData to be a comma separated string of hex values
      ' sRegKey needs to start with full registry root, e.g. HKEY_CURRENT_USER and not VBScript short form HKCU
      Dim oShell, oFSO, oFile, oExec
      Dim sTempFile
      Set oShell = CreateObject("WScript.Shell")
      Set oFSO = CreateObject("Scripting.FileSystemObject")
      sTempFile = oShell.ExpandEnvironmentStrings("%temp%\RegWriteBinary.reg")
      Set oFile = oFSO.CreateTextFile(sTempFile,True)
      oFile.WriteLine("Windows Registry Editor Version 5.00")
      oFile.WriteLine("")
      oFile.WriteLine("[" & sRegKey & "]")
      oFile.WriteLine(Chr(34) & sRegValue & Chr(34) & "=" & "hex:" & sBinaryData)
      oFile.Close
      Set oExec = oShell.Exec("reg.exe import """ & sTempFile & """")
      If InStr(1,oExec.StdErr.ReadAll,"operation completed successfully",vbTextCompare) Then
             ' Yes the success text IS sent out via StdErr and NOT StdOut
             WScript.Echo "Registry updated sucessfully"
             oFSO.DeleteFile sTempFile
      Else
             WScript.Echo "regWriteBinary: Registry import of " & sTempFile & " failed: " & oExec.StdErr.ReadAll
      End If
End Sub

Usage:

regWriteBinary "HKEY_LOCAL_MACHINE\Software\Something\Some Key", "Value name to create/overwrite", "0A,00,02,75,FF,BA,04"

Note that unlike most of VBScript registry stuff, you have to use the full registry root with this.

Read a REG_BINARY

Function regReadBinary(sRegValue)
      'read a REG_BINARY and return it as a text string
      Dim aBin, aInt(), i, iBinSize, sString, oShell, iChar, sChar
      Set oShell = CreateObject("WScript.Shell")
      On Error Resume Next
      Err.Clear
      aBin = oShell.RegRead(sRegValue)
      If Err.Number = 0 Then
             iBinSize = UBound(aBin)
             ReDim aInt(iBinSize)
             For i = LBound(aBin) To UBound(aBin)
                   aInt(i) = CInt(aBin(i))
                   If aInt(i) <> 0 Then
                         iChar = aInt(i)
                         sChar = Chr(iChar)
                         sString = sString&sChar
                   End If
             Next
             regReadBinary=sString
      End If
End Function

Usage:

sReturnText = regReadBinary("HKCU\Software\Something\some binary value")

Note that it strips out (skips over) any 0x00 hex values with the specified REG_BINARY which is a) necessary as appending one of these to a text string doesn’t work, and b) makes it much nicer when used to read stuff out of anything to do with Outlook mail profiles. Note also that this one uses the VBScript short form of registry root.

Having just posted these, it would probably be nicer if regWriteBinary was a function that set itself to True or False depending on whether the import works or not.

On the subject of the import, both reg.exe and regedit.exe will import basically any old nonsense from a .reg file and claim sucess even if the data or location is invalid. The registry won’t be updated with the broken values but the utilities claim success anyway. Nice.

Note to software developers: Please don’t store text strings in REG_BINARY values. Frankly, just don’t use REG_BINARY at all.

This entry was posted in Scripting, Windows and tagged , , , , , , . Bookmark the permalink.

4 Responses to VBScript and REG_BINARY registry values

  1. Pingback: Outlook 2007 AutoArchive PST location change VBScript | Robin CM's IT Blog

  2. Bryan says:

    Robin,

    I’m trying to use your first example but it’s not working for me –

    Sub regWriteBinary “HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections”, “DefaultConnectionSettings”, “46,00,00,00,05,00,00,00,01,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,01,00,00,00,00,00,00,00,70,6a,b1,f9,e2,b2,ce,01,00,00,00,00,00,00,00,00,00,00,00,00,02,00,00,00,17,00,00,00,00,00,00,00,fe,80,00,00,00,00,00,00,f5,56,1e,e4,95,48,47,ec,0c,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,02,00,00,00,0a,00,2d,81,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00”

    ‘ Expects sBinaryData to be a comma separated string of hex values
    ‘ sRegKey needs to start with full registry root, e.g. HKEY_CURRENT_USER and not VBScript short form HKCU
    [snip]

    Like

  3. DHeath says:

    Hi, the Write a REG_BINARY is what I need, but have a problem in that its not returning anything in the oExec.StdErr.ReadAll

    I realize you specifically state that oExec.StdErr.ReadAll contains the output, however since I had tried everything else if threw this in…

    Do Until objExec.Status = 1
    WScript.Sleep(10)
    Loop
    MsgBox objExec.StdOut.ReadAll
    MsgBox objExec.StdErr.ReadAll

    The ‘do until’ to make sure it waited for completion, but the important part is the StdOut is what contained the operation successful message. Since you went out of your way to comment on the opposite, I figure it must be scripting host specific or os specific I just wanted to let you know. I am using fully updated xpsp3 and cscript to test. Just a heads up and thanks for the code!

    Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.