VBScript Includes

librarian I’ve been using VBScript for a very long time. One drawback it has always had as a scripting language is an INCLUDE statement.  In other languages you can use something like INCLUDE scriptfile at the beginning of the script. This would load any functions and variables in the specified script file into your current script.  In PowerShell we can accomplish this by dot sourcing scripts.

. c:\scripts\myfunctions.ps1
. \\file01\admins\teamfunctions.ps1
# main code here but I can call any function that is defined
# in myfunctions.ps1 or teamfunctions.ps1 just as if they
# were in this script.

I never knew of a way to do the same thing with VBScript until now. Sure, if you write a Windows Script File (WSF), that has the ability to include external scripts, but not a plain VBS script.

Recently in the SAPIEN support forums someone asked about this topic in relationship to PrimalScript. The customer then posted a short example, which was found somewhere online. I tried it out and it seems to work. I took the sample code and tweaked it a bit to create a function. Here’s an example of how it might be used.

Function LoadLibrary(sScriptFile)
    Set oFSO=CreateObject("Scripting.FileSystemObject")
    If oFSO.FileExists(sScriptFile) Then
        Set sFile=oFso.OpenTextFile(sScriptfile)
        ExecuteGlobal sInput
        WScript.Echo "Failed to find " & sScriptFile
    End If
End Function
LoadLibrary "c:\scripts\ScriptFunctionLibrary.vbs"
'GetOS is a function in ScriptFunctionLibrary.vbs
WScript.Echo OS

The LoadLibrary function takes a script path as a parameter. Assuming the file exists, its contents are read into a variable. Now here’s the magic part. The ExecuteGlobal function. Here’s my description from WSH and VBScript Core: TFM.

In VBScript, it is possible to have an ambiguous expression. For example b=x could be interpreted as assigning the value of variable x to variable b. Or it could be interpreted as a comparison test. Does b have the same value as x? In VBScript, Execute applies the former interpretation and Eval applies the latter.

Execute and ExecuteGlobal essentially perform the same task. The significant difference is that any result from ExecuteGlobal is available to all namespaces or scopes within your script.

What happens is that ExecuteGlobal takes all of the defined functions, that’s all that is in ScriptFunctionLibrary.vbs and executes them globally, which has the effect of loading them into the current script scope. Yep, VBScript has scope just like PowerShell. Thus I can invoke any function in my current script that has been defined in my library script. If there were defined variables in the library script I could access them as well. I wrote the function to make it easier in case you needed to load multiple script files.

Of course, none of this is without risk. You have to be aware of name and variable collisions. Do you really know what is in the contents of the library script you are loading? This function could easily be used to load malicious code. Signing your scripts would help mitigate this risk.

Download a text version of my LoadLibrary function here.