Working With WMI Objects in Scripts

Applies to TestComplete 14.40, last modified on April 22, 2021

Windows Management Instrumentation (WMI) is a component of Windows operating systems that is aimed at managing local and remote computers and collecting computer management information in the enterprise environment. WMI lets you start and stop services, monitor system drives, view or change user or user group permissions, change file or folder properties, monitor the event log and perform other administrative tasks. For more information on WMI, see the Windows Management Instrumentation article in the MSDN Library.

This topic explains how you should configure the computer in order to use WMI successfully, and describes how to access the WMI service in scripts.

Setting Security Permissions

In order to successfully execute scripts that use WMI, the computer where WMI queries are addressed (the computer where the script is executed or a remote computer) should meet the following requirements:

  • The computer must work under Windows XP or later operating system.

  • The WMI service must be running on the computer. In English versions of Windows, this service is called Windows Management Instrumentation.

  • The user account TestComplete is running under must be a member of the Administrators group on the computer to which WMI queries are addressed.

    Also, users who interact with the computer via WMI should have the correct permissions to perform the needed operations. To change the WMI security permissions, follow the instructions below:

    • Open the WMI Config Manager dialog. To do this:

      • Open the Control Panel | Administrative Tools | Computer Management dialog.

      • Select Services and Applications | WMI Control in the tree view on the left of the dialog.

      • Right-click the WMI Control node and choose Properties from the context menu.

    • In the WMI Config Manager dialog, switch to the Security page.

    • On this page, select the namespace that will be used in scripts, and press Security. In the subsequent dialog, set the desired permissions for the LOCAL SERVICE account (this account is used by the WMI service). Note that WMI requires administrator permissions for most actions.

    • Press OK to save your changes.

    To change the permissions, you must be a member of the Administrators group on the computer or you must have the correct permissions.
Connecting to WMI in Scripts

In order to use the WMI functionality in your scripts, you need to connect to WMI on the target computer. You can do this in two ways: either using WMI scripting API, or using the TestComplete WMI object.

Using WMI Scripting API

If you use JScript, VBScript, C#Script or C++Script, you can use the built-in GetObject function of these languages to obtain the Windows SWbemServices object that provides access to the WMI service:

JScript

WmiService = GetObject ("WinMgmts:{impersonationLevel=impersonate}!//ComputerName/root/cimv2");

VBScript

Set WmiService = GetObject ("WinMgmts:{impersonationLevel=impersonate}!\\ComputerName\root\cimv2")

C++Script, C#Script

WmiService = GetObject ("WinMgmts:{impersonationLevel=impersonate}!//ComputerName/root/cimv2");

The parameter passed to the routine is a moniker string. In the case above, it contains the following parts:

  • WinMgmts - The obligatory moniker prefix.
  • impersonationLevel=impersonate - The instruction for the target system to use the account that the script is running under when executing WMI objects’ routines or retrieving data.
  • ComputerName - The name of the target computer where the WMI queries are addressed ("." in case of the local computer).
  • root\cimv2 - The namespace of the WMI objects used in scripts.

If you use JavaScript, Python or DelphiScript, then scripting access to WMI will consist of two steps. First, you should use the Sys.OleObject routine to obtain the helper SWbemLocator object with ProgID WbemScripting.SWbemLocator. Then you can connect to WMI using the ConnectServer method of the obtained object:

JavaScript

let Locator = getActiveXObject("WbemScripting.SWbemLocator");
let WmiService = Locator.ConnectServer(ComputerName, Namespace, UserName, Password);

Python

Locator = Sys.OleObject["WbemScripting.SWbemLocator"]
WmiService = Locator.ConnectServer (ComputerName, Namespace, UserName, Password)

DelphiScript

Locator := Sys.OleObject ('WbemScripting.SWbemLocator');
WmiService := Locator.ConnectServer (ComputerName, Namespace, UserName, Password);

In this example, we use the SWbemLocator.ConnectServer method with the following parameters:

  • ComputerName - The name of the target computer where the WMI queries are addressed. Optional. An empty string or '.' means the current computer.
  • Namespace - The namespace of the WMI objects used in scripts. Optional. An empty string means the default namespace.
  • UserName and Password - The user name and password of the account used to connect to WMI on the target computer. Optional. Empty strings mean that the current account and security context will be used.
Using the WMI Object

TestComplete includes the WMI scripting object that makes access to WMI services easier. Specifically, you can obtain a reference to the SWbemLocator object by simply using the WMI.Service property. To specify the target computer, use the WMI.ComputerName property or the WMI.ConnectToComputer method.

Note: The WMI object connects to WMI using the default Windows authentication, impersonate-level impersonation and the security permissions needed for successful execution of the WMI object methods. To execute custom WMI calls, you may need to directly specify the required security settings for the WMI.Service object.
Using WMI Services in Scripts

After you get access to the WMI service, you can execute WMI queries, obtain various WMI objects (for example, those that correspond to the system’s logical drives, files and folders, printers, registry, services, event logs and others) and perform the desired tasks.

To learn how you use WMI services in your script code and for a complete WMI scripting API reference, see the following topics in the MSDN Library (http://msdn.microsoft.com):

Example

The following example increments the hours part of the date on a local computer. To use this routine to change the time on a remote computer, specify the desired computer name using the ComputerName variable or the WMI.ComputerName property.

JavaScript

function ChangeDate()
{
  // Using the SWbemServices object directly:
  let ComputerName = ".";
  let wbemImpersonationLevelImpersonate = 3;
  let Locator = getActiveXObject("WbemScripting.SWbemLocator");
  Locator.Security_.ImpersonationLevel = wbemImpersonationLevelImpersonate;
  Locator.Security_.Privileges.AddAsString("SeSystemTimePrivilege");
  let WmiService = Locator.ConnectServer(ComputerName, "/root/cimv2");

  let OSList = WmiService.InstancesOf("Win32_OperatingSystem");

  let DateTime = getActiveXObject("WbemScripting.SWbemDateTime");

  let OSEnum = Utils.Enumerator(OSList);
  while (!OSEnum.atEnd)
  {
    let OS = OSEnum.item;
    DateTime.Value = OS.LocalDateTime;
    Log.Message("Current time: " + aqConvert.DateTimeToStr(DateTime.GetVarDate()));

    DateTime.Hours++;
    if (OS.SetDateTime(DateTime.Value) != 0)
      Log.Error("Cannot set system time.");
    else
      Log.Message("New time: " + aqConvert.DateTimeToStr(DateTime.GetVarDate()));
    OSEnum.moveNext();
  }
}

JScript

function ChangeDate()
{
  var WmiService, ComputerName, OSList, OSEnum, OS, DateTime;

  // Using the SWbemServices object directly:
  ComputerName = ".";
  WmiService = GetObject ("winmgmts:{impersonationLevel=impersonate, (Systemtime)}!//" + ComputerName + "/root/cimv2");
  OSList = WmiService.InstancesOf ("Win32_OperatingSystem");

  // Using the WMI object:
  // WMI.ComputerName = ".";
  // WMI.Service.Security_.Privileges.AddAsString("SeSystemtimePrivilege");
  // OSList = WMI.Service.InstancesOf ("Win32_OperatingSystem");

  DateTime = new ActiveXObject ("WbemScripting.SWbemDateTime");

  OSEnum = new Enumerator (OSList);
  for ( ; !OSEnum.atEnd(); OSEnum.moveNext())
  {
    OS = OSEnum.item();
    DateTime.Value = OS.LocalDateTime;
    Log.Message ("Current time: " + aqConvert.DateTimeToStr(DateTime.GetVarDate()));

    DateTime.Hours ++;
    if (OS.SetDateTime(DateTime.Value) != 0)
      Log.Error ("Cannot set system time.");
    else
      Log.Message ("New time: " + aqConvert.DateTimeToStr(DateTime.GetVarDate()));
  }
}

Python

def ChangeDate():
  
  # Using the SWbemServices object directly:
  ComputerName = "."
  wbemImpersonationLevelImpersonate = 3
  Locator = Sys.OleObject["WbemScripting.SWbemLocator"]
  Locator.Security_.ImpersonationLevel = wbemImpersonationLevelImpersonate
  Locator.Security_.Privileges.AddAsString("SeSystemtimePrivilege")
  WmiService = Locator.ConnectServer (ComputerName, "root\cimv2")

  OSList = WmiService.InstancesOf ("Win32_OperatingSystem")

  DateTime = Sys.OleObject["WbemScripting.SWbemDateTime"]

  OSEnum = Utils.Enumerator(OSList)
  while not OSEnum.atEnd:
    OS = OSEnum.item
    DateTime.Value = OS.LocalDateTime
    Log.Message ("Current time: " + aqConvert.DateTimeToStr(DateTime.GetVarDate()))

    DateTime.Hours +=1
    if OS.SetDateTime(DateTime.Value) != 0:
      Log.Error ("Cannot set system time.")
    else:
      Log.Message ("New time: " + aqConvert.DateTimeToStr(DateTime.GetVarDate()))
    OSEnum.moveNext()

VBScript

Sub ChangeDate
  Dim WmiService, ComputerName, OSList, OS, DateTime

  ' Using the SWbemServices object directly:
  ComputerName = "."
  Set WmiService = GetObject ("WinMgmts:{impersonationLevel=impersonate, (Systemtime)}!\\" & ComputerName & "\root\cimv2")
  Set OSList = WmiService.InstancesOf ("Win32_OperatingSystem")

  ' Using the WMI object:
  ' WMI.ComputerName := '.';
  ' WMI.Service.Security_.Privileges.AddAsString('SeSystemtimePrivilege');
  ' OSList := WMI.Service.InstancesOf ('Win32_OperatingSystem');

  Set DateTime = CreateObject ("WbemScripting.SWbemDateTime")

  For Each OS In OSList
    DateTime.Value = OS.LocalDateTime
    Log.Message "Current time: " & aqConvert.DateTimeToStr(DateTime.GetVarDate)

    DateTime.Hours = DateTime.Hours + 1
    If OS.SetDateTime(DateTime.Value) <> 0 Then
      Log.Error "Cannot set system time."
    Else
      Log.Message "New time: " & aqConvert.DateTimeToStr(DateTime.GetVarDate)
    End If
  Next
End Sub

DelphiScript

procedure ChangeDate;
const wbemImpersonationLevelImpersonate = 3;
var Locator, WmiService, ComputerName, OSList, OSEnum, OS, DateTime;
begin
  // Using the SWbemServices object directly:
  ComputerName := '.';
  Locator := Sys.OleObject ('WbemScripting.SWbemLocator');
  Locator.Security_.ImpersonationLevel := wbemImpersonationLevelImpersonate;
  Locator.Security_.Privileges.AddAsString('SeSystemtimePrivilege');
  WmiService := Locator.ConnectServer (ComputerName, 'root\cimv2');
  OSList := WmiService.InstancesOf ('Win32_OperatingSystem');

  // Using the WMI object:
  // WMI.ComputerName := '.';
  // WMI.Service.Security_.Privileges.AddAsString('SeSystemtimePrivilege');
  // OSList := WMI.Service.InstancesOf ('Win32_OperatingSystem');

  DateTime := Sys.OleObject('WbemScripting.SWbemDateTime');

  OSEnum := Utils.Enumerator (OSList);
  while not OSEnum.AtEnd do
  begin
    OS := OSEnum.Item;
    DateTime.Value := OS.LocalDateTime;
    Log.Message ('Current time: ' + aqConvert.DateTimeToStr(DateTime.GetVarDate));

    DateTime.Hours := DateTime.Hours + 1;
    if OS.SetDateTime(DateTime.Value) <> 0 then
      Log.Error('Cannot set system time.')
    else
      Log.Message('New time: ' + aqConvert.DateTimeToStr(DateTime.GetVarDate));

    OSEnum.MoveNext;
  end;
end;

C++Script, C#Script

function ChangeDate()
{
  var WmiService, ComputerName, OSList, OSEnum, OS, DateTime;

  // Using the SWbemServices object directly:
  ComputerName = ".";
  WmiService = GetObject ("winmgmts:{impersonationLevel=impersonate, (Systemtime)}!//" + ComputerName + "/root/cimv2");
  OSList = WmiService["InstancesOf"]("Win32_OperatingSystem");

  // Using the WMI object:
  // WMI["ComputerName"] = ".";
  // WMI["Service"]["Security_"]["Privileges"]["AddAsString"]("SeSystemtimePrivilege");
  // OSList = WMI["Service"]["InstancesOf"]("Win32_OperatingSystem");

  DateTime = new ActiveXObject ("WbemScripting.SWbemDateTime");

  OSEnum = new Enumerator (OSList);
  for ( ; !OSEnum["atEnd"](); OSEnum["moveNext"]())
  {
    OS = OSEnum["item"]();
    DateTime["Value"] = OS["LocalDateTime"];
    Log["Message"]("Current time: " + aqConvert["DateTimeToStr"](DateTime["GetVarDate"]()));

    DateTime["Hours"]++;
    if (OS["SetDateTime"](DateTime["Value"]) != 0)
      Log["Error"]("Cannot set system time.");
    else
      Log["Message"]("New time: " + aqConvert["DateTimeToStr"](DateTime["GetVarDate"]()));
  }
}

See Also

Script Tests
WMI Object

Highlight search results