Working with Windows Management Instrumentation (WMI)
Windows Management Instrumentation (WMI) is Microsoft's version of the industry standard
Web-based Enterprise Management (WBEM), which uses the Common Information Model (CIM) industry standard
to represent managed objects.
In layman's terms this means that Microsoft has made an abstraction layer on top of, among other
things, hardware and software information and you get an sql-like syntax to get or set information.
This is a very good thing, because if you use the Windows API directly, no two information is retrieved
the same way. As with all abstraction there is a price to pay, which in this case is performance.
But luckily you can use built-in FastTrack Scripting Host functions for common operations instead
of using WMI and this way you do not pay the penalty. But if you move outside querying common information
or you need to invoke methods, you must use WMI.
If you are not familiar with WMI, please have a look at the
official Microsoft WMI page.
Using WMI to get a single value
If you go to the "WMI" node in the Engine Browser tree in the script editor, you will find only two sub-nodes.
One is the function that retrieves one WMI value and one is the collection that retrieves multiple values.
And essentially, this is all you need, because this is enough to get information from WMI.
If you are doing very advanced WMI scripting, you may need to work
on WMI objects, and this is described further down.
If we wanted to get the total memory installed, we would first have to find out in what WMI class we need, which
we can see here: Computer System Hardware Classes
In this case need the TotalPhysicalMemory from the Win32_ComputerSystem class. We know we just need to get one value
from WMI, so we can just use the WMIQuery function like this:
ShowMessage [WMIQuery Select TotalPhysicalMemory
And voila, we have the total memory. For demonstration purposes, we are just displaying the value on the screen.
In real life, the WMIQuery function could be used like this: "Set MyVariable = [WMIQuery Select TotalPhysicalMemoryFrom Win32_ComputerSystem]"
to save the information in a variable for later use.
But here is the one thing you must know, when using WMI with
FastTrack Scripting Host: If there is a native function to get the same information - use it. The
native version will in many cases give you this information in a few milliseconds, where the WMI
layer will take seconds to get the same information. Before you start to use WMI, try to search for a
native function with the F9 key (Search Engine Browser). Searching for "memory" will show us that
there is a function called "TotalMemory". So we can instead simply go:
Now there are a number of advantages using the native version. First of all, they are usually quicker
and secondly, they are often formatted. Where the WMI version will give you 4080713728 (bytes) on a 4 gigabyte
machine, the native version will give you a more useful 4080 (megabytes).
Using WMI to get multiple values
In some cases we would need more than one value from a query. In this case we need the
WMIValues collection. This could be relevant, if we wanted to collect all disk drives
in a computer. We could log this information to a file or store it elsewhere, but for
demonstration purposes, we will just show the retrieved names of the drives:
ForEach Model in [WMIValues SELECT model from Win32_DiskDrive]
ShowMessage [Var Model]
Using WMI to get multiple properties
If we need more than one property in a WMI query, we need to work on WMI objects
through COM. Refer to this page
for documentation on using COM with FastTrack.
As shown in the article, we can create an instance of the Win32_LogicalDisk class
and go through the results. In the example below, we are displaying the property "Name" of
each disk object, but all other properties and methods on the Win32_LogicalDisk object can
be used through the ObjectValue function, as we used the star-notation (*).
ForEachObject Drive in CreateWMIObject("Select
* from Win32_LogicalDisk")
ShowMessage [ObjectValue Drive.Name]
If the example, we are using one property. If we need to invoke a method, we can
do this the same way we use properties. The best example on using methods is the
Hyper-V Controller script shown here
where the "RequestStateChange" method is invoked to stop and start Hyper-V machines.