WQL Queries

WQL (WMI Query Language) is the SQL-like language used to query the Windows Management Instrumentation (WMI) repository. The client runs a query on the remote host and returns the rows.

Running a query

Build a WinRMClient[1], then prepare the query with wql(...) and run it with execute():

import java.time.Duration;
import org.metricshub.winrm.WinRMClient;
import org.metricshub.winrm.WqlResult;
import org.metricshub.winrm.WqlRow;

try (WinRMClient client = WinRMClient.builder("server.example.com")
        .credentials("DOMAIN\\Administrator", password)
        .timeout(Duration.ofSeconds(30))
        .build()) {

    WqlResult result = client.wql("SELECT Name, State FROM Win32_Service").execute();

    for (WqlRow row : result) {
        System.out.println(row.string("Name") + " is " + row.string("State"));
    }
}

One client can run any number of queries (and commands[2]) over the same authenticated connection — see the Overview[3] for the builder options.

Query options

Everything between wql(...) and execute() is optional:

Option Default Meaning
namespace(String) the client's namespace (ROOT\CIMV2 unless set on the builder) The WMI namespace to query.
timeout(Duration) the client's timeout Wall-clock deadline for the whole query with execute(); inactivity timeout with stream(). See Timeouts and Errors[4].
pageSize(int) 32000 WS-Enumeration MaxElements: how many rows the server may return per protocol round trip.
pullTimeout(Duration) server default WS-Enumeration MaxTime: how long the server may hold a single Pull open before answering with the rows it has.
WqlResult events = client.wql("SELECT * FROM Win32_NTLogEvent")
    .namespace("root\\cimv2")
    .pageSize(5000)
    .pullTimeout(Duration.ofSeconds(10))
    .timeout(Duration.ofMinutes(2))
    .execute();

pageSize and pullTimeout matter for very large result sets (for example Windows event logs): a smaller page bounds each response's size, and a pull timeout keeps the server from holding a Pull open past your deadline while it gathers rows.

Streaming the rows

execute() collects the complete result in memory. For very large result sets — Windows event logs, software inventories — end the same request with stream() instead: it returns a lazy java.util.stream.Stream of WqlRow[5]s that yields each row as soon as it is parsed and pulls the next WS-Enumeration page from the server only as the stream advances. Memory stays bounded by one page (pageSize(int)), not by the whole result set.

try (Stream<WqlRow> rows = client.wql("SELECT * FROM Win32_NTLogEvent")
        .pageSize(5000)
        .stream()) {

    rows.filter(row -> "Error".equals(row.string("Type")))
        .limit(100)
        .forEach(this::process);
}

Points to know:

  • Close the stream — use try-with-resources, exactly like Files.lines(...). Closing before the last row tells the server to free the enumeration immediately (WS-Enumeration Release); an exhausted stream cleans up on its own.
  • The stream holds the client's serial connection while open: other operations on the same client wait until it is closed or exhausted (the same contract as a JDBC ResultSet on its connection).
  • The timeout is an inactivity timeout — the longest silence tolerated from the server between two responses — not an overall deadline: consuming a huge result can take arbitrarily long as long as the server keeps answering. See Timeouts and Errors[4].
  • The stream is sequential and ordered; failures while iterating are reported through the same unchecked exceptions as execute() (see below).

Reading the result

WqlResult[6] is immutable and iterable:

Method Returns Description
columns() List<String> The property (column) names, in query order.
rows() List<WqlRow[5]> The result rows.
size() / isEmpty() int / boolean Row count.
elapsed() java.time.Duration Wall-clock time of the query.

Each WqlRow[5] exposes the instance properties:

Method Returns Description
string(String) String The property value as a string, or null.
get(String) Object The raw property value, or null.
asMap() Map<String, Object> All properties, in server order (unmodifiable).

Property lookup is case-insensitive, matching WMI semantics: row.string("name") and row.string("Name") return the same value.

Property order and case

  • When you select explicit properties (SELECT Name, State FROM ...), the columns keep the order of the query and the exact case reported by WMI.
  • With SELECT * FROM ..., the properties are returned in alphabetical order (case-insensitive).
  • If the query returns no rows, the columns fall back to the property names exactly as written in the query (WMI's own casing cannot be recovered from an empty result set).

Supported WQL syntax

The client validates that the query is a simple SELECT:

SELECT * FROM Win32_OperatingSystem
SELECT Name, State, StartMode FROM Win32_Service
SELECT Name FROM Win32_Process WHERE Name = 'explorer.exe'

The grammar is a single SELECT of either * or a comma-separated property list, a FROM clause, and an optional WHERE clause. Joins, sub-selects, and other advanced constructs are not part of the supported syntax. An invalid query raises a WqlSyntaxException[7] before anything is sent to the host.

Choosing a namespace

Most Windows classes live under the default ROOT\CIMV2 namespace. To query a different one — for example ROOT\Microsoft\SqlServer or ROOT\WMI — set it per query with namespace(...), or set a client-wide default with namespace(...) on the builder. Both ROOT\WMI and ROOT/WMI are accepted.

Exceptions

execute() reports failures through the unchecked WinRMClientException[8] hierarchy:

Exception When
WqlSyntaxException[7] The query does not match the supported SELECT syntax.
WinRMAuthenticationException[9] The credentials were rejected.
WinRMFaultException[10] The remote service answered with a WSMan fault (e.g. an unknown class or namespace) — the fault code and detail are available as fields.
WinRMTimeoutException[11] The query did not complete within its timeout.
WinRMClientException[8] Any other failure (connection, TLS, protocol).

See Timeouts and Errors[4] for the full exception surface.

From the command line

The standalone jar exposes the same capability through its wql subcommand, streaming the rows to stdout as JSON Lines — see the Command-Line Client[12] manual.

wql wmi query win32 namespace root cimv2 cim winrm wql wmi windows ntlm kerberos java remote management
Links:
  • [1] apidocs/org/metricshub/winrm/WinRMClient.html
  • [2] commands.html
  • [3] index.html
  • [4] timeouts-and-errors.html
  • [5] apidocs/org/metricshub/winrm/WqlRow.html
  • [6] apidocs/org/metricshub/winrm/WqlResult.html
  • [7] apidocs/org/metricshub/winrm/exceptions/WqlSyntaxException.html
  • [8] apidocs/org/metricshub/winrm/exceptions/WinRMClientException.html
  • [9] apidocs/org/metricshub/winrm/exceptions/WinRMAuthenticationException.html
  • [10] apidocs/org/metricshub/winrm/exceptions/WinRMFaultException.html
  • [11] apidocs/org/metricshub/winrm/exceptions/WinRMTimeoutException.html
  • [12] cli.html
Searching...
No results.