WinRM Java Client 2.0.00
-
Home
- Usage
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-EnumerationRelease); 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
ResultSeton 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.
- [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
