Q: I'm having problems with the
VBScript code in Listing 3. In this script,
Array1 is a dynamic array that's populated
by using Windows Management
Instrumentation (WMI) to retrieve the
properties of the Win32_Battery class.
When I try to use the contents of this
dynamic array to execute a query, I get
the error message Error: Object doesn't
support this property or method: 'Array1.'
I've tried everything I can think of to
make this script work but nothing has
worked. What am I missing?
A: There are several problems in your
script. Before I point out the problems
and suggest a possible solution, I
should take a minute to clarify what
the script is trying to do for the benefit
of our readers. In brief, the script is
trying to use Array1 as an interpolated
variable, as the code at callout C in
Listing 3 shows. What does that mean?
In the context of scripting languages, to
interpolate means to insert the value of
a variable into an expression, statement,
or string. Let's look at a simple
example in Perl, a scripting language
that supports interpolated variables.
Suppose you have the following
code in a script:
my $cn = "cn=tmtowtdi";
my $user = Win32::OLE->
GetObject("LDAP:\\\\$cn,...")
or die;
The snippet begins by assigning the
string "cn=tmtowtdi" to the variable
named $cn. Next, the code uses the
value stored in the $cn variable as part
of the connection string used to bind
to a user object in Active Directory
(AD). Notice how the $cn variable is
part of the connection string. That is,
the variable is embedded inside the
double quoted string; there's no string
concatenation or the like being used.
When Perl encounters a variable name
inside a double quoted string, Perl
automatically inserts the variable's
value at that point in the string—this
is interpolation at work.
VBScript doesn't support interpolated
variables. For example, the
following VBScript version of the previous
Perl snippet is invalid:
cn = "cn=tmtowtdi"
Set user = _
GetObject("LDAP:\\cn,...")
To get this code to work in VBScript,
you must break the connection string
into multiple parts and use string concatenation
to insert the value of cn, as
this code shows:
cn = "cn=tmtowtdi"
Set user = _
GetObject("LDAP:\\" & cn & ",...")
Now that you know what interpolated
strings and variables are, let's
take a closer look at the script in Listing
3. As I stated earlier, the script contains
several errors:
- In the For Each…Next statement
that callout A highlights, you use
the variable i.However, you didn't
initialize that variable before you
used it.
- The nested For…Next and For
Each…Next statements after the
code at callout A appear to be
backward. My guess is that you're
trying to loop through each item in
the collection returned by Exec-
Query, and for each item in the collection,
echo the item's properties.
As written, the script loops through
the properties in the array named
Array1 first, and for each property
in the array, loops through the collection
returned by ExecQuery.
- In the code that callout B shows,
you set the wmiQuery variable to
the Win32_Battery class query,
obtain an instance of the WMI
scripting library's SWbemServices
object, then call that object's Exec-
Query method to perform the query
on the local computer—all inside a
For...Next statement. By placing this
code inside this For loop, you're
repeatedly performing these
actions, which isn't good scripting
practice because it wastes valuable
system resources. This code should
go near the beginning of the script,
outside any loops, so that the
actions are performed only once.
- In the For Each loop at callout C,
you use an interpolated variable,
objItem.array1(b), which is the
source of the problem that
prompted your question. However,
as I mentioned earlier, VBScript
doesn't support interpolated variables
or strings.
- The Win32_Battery class has properties
of type CIM_ARRAY. However,
as written, the script doesn't
support properties of type
CIM_ARRAY. Nor does it support
properties of type CIM_OBJECT.
Based on your script, I'm guessing
you're trying to create a lightweight
version of Scriptomatic. As luck would
have it, one already exists called Scriptomatic
Lite. This tool automatically
retrieves and displays the values of
each property in a class. Moreover, it
supports properties of type CIM_
www.winnetmag.com/windowsscripting
ARRAY and gracefully handles embedded
CIM_OBJECT types. On the Windows
Scripting Solutions Web site,
you'll find VBScript and Perl versions
of the Scriptomatic Lite code I
adapted for the Win32_Battery class.
To download these files, go to http://
www.winnetmag.com/windows
scripting, enter 43315 in the Instant-
Doc ID box, then click the 43315.zip
hotlink. For more information about
Scriptomatic Lite, go to http://msdn
.microsoft.com/library/default.asp?
url=/library/en-us/dnclinic/html/
scripting01142003.asp.
The adapted Scriptomatic Lite
code, though, doesn't use interpolated
variables. If you're set on using them,
you'll need to use Perl code similar to
the code that Listing 4 shows. Note
that this code doesn't handle properties
of type CIM_ARRAY or CIM_
OBJECT, so you'd need to adapt it
accordingly.