WinRM Java Client 3.1.04
- Getting Started Overview Installation Preparing the Windows Host
- Usage WQL Queries Remote Commands File Transfers Remote Files Command-Line Client Authentication TLS / HTTPS Timeouts and Errors
- Reference Migrating from 1.x Migrating from winrm4j Legacy API Javadoc (API)
- Project Documentation Project Information 9 Project Reports 9
WinRM Java Client
Overview
The WinRM Java Client is a small library that talks to the Windows Remote Management (WS-Management) service on a remote Windows host. It lets a Java application:
- run WQL / WMI queries such as
SELECT Name, State FROM Win32_Serviceand read the rows back (WQL Queries[1]), - execute remote commands —
cmd.execommand lines or PowerShell scripts — capturing standard output, standard error and the exit code, optionally copying local script files to the host first (Remote Commands[2]), and - access remote files — read a file (whole, a byte range, a tail), download it to a local file, get its properties, or list a directory with filters evaluated on the host (Remote Files[3]).
All of them can also stream: WQL rows are consumed page by page as they arrive (stream()), command output is consumed while the command is still running (start(), returning a java.lang.Process-like handle), and file contents and directory listings are decoded as the host sends them — memory stays bounded regardless of the result size.
The standalone jar is also a command-line client[4] for the same operations (wql, command, shell, ls, stat, cat, get).
It supports NTLM over HTTP (with message encryption) and HTTPS, Kerberos (SPNEGO) over HTTPS, and HTTP Basic over HTTPS (Authentication[5]).
Since 2.0.00 the client has zero runtime dependencies (no Apache CXF / JAX-WS / JAXB stack, no SMB stack) and is immune by construction to JAXP ServiceLoader conflicts, because it uses the JDK-default XML factories. Problems are reported through exceptions only — the library pulls in no logging framework.
Upgrading from 1.x? Version 2.0.00 removed the legacy Apache CXF backend and now validates TLS certificates and verifies hostnames by default. If you connect over HTTPS to hosts with self-signed certificates, read Migrating from 1.x[6] first.
Add the dependency
The library is published on Maven Central[7].
Maven
<dependency>
<groupId>org.metricshub</groupId>
<artifactId>winrm-java</artifactId>
<version>3.1.04</version>
</dependency>
Gradle (Groovy)
implementation 'org.metricshub:winrm-java:3.1.04'
Gradle (Kotlin)
implementation("org.metricshub:winrm-java:3.1.04")
See Installation[8] for the coordinates, the supported JDKs, and the standalone command-line jar.
Quick start
On the target host, WinRM must be enabled and the account must have sufficient privileges. Windows Server 2012 and later have WinRM enabled by default and an administrator account works with no configuration; Windows 10 / 11, non-administrator accounts, and local administrator accounts other than the built-in Administrator need host-side setup. See Preparing the Windows Host[9].
Everything starts with the fluent WinRMClient[10] builder — one client authenticates once and can run any number of queries and commands over the same connection:
import java.time.Duration;
import org.metricshub.winrm.WinRMClient;
import org.metricshub.winrm.WqlResult;
import org.metricshub.winrm.WqlRow;
public class Example {
public static void main(String[] args) {
try (WinRMClient client = WinRMClient.builder("server.example.com")
.credentials("DOMAIN\\Administrator", "the-password".toCharArray())
.timeout(Duration.ofSeconds(30))
.build()) {
WqlResult result = client.wql("SELECT Name, State FROM Win32_Service").execute();
System.out.println(result.columns()); // [Name, State]
for (WqlRow row : result) {
System.out.println(row.string("Name") + " is " + row.string("State"));
}
}
}
}
Remote commands work the same way:
CommandResult result = client.command("ipconfig /all").execute();
System.out.println(result.stdout());
And so do PowerShell scripts — delivered base64-encoded (-EncodedCommand), so they need no quoting or escaping at all:
CommandResult ps = client.powerShell("Get-Service | Where-Object Status -eq 'Running'").execute();
Remote files go through the same connection — no SMB, no extra port:
String tail = client.file("D:\\logs\\app.log").offset(-8192).readText(StandardCharsets.UTF_8);
RemoteFileList logs = client.file("D:\\logs").list().glob("*.log").recursive().execute();
Failures are reported through the unchecked WinRMClientException[11] hierarchy. The static one-shot helpers that predate WinRMClient (WinRMWqlExecutor.executeWql(...)[12], WinRMCommandExecutor.execute(...)[13]) remain available and unchanged, with their checked exceptions.
Client options
build() does not connect: the first operation does. A client may be shared between threads, but its connection is a serial channel: operations run one at a time, and an open stream or process holds the connection until it is closed. For parallel work, use one client per concurrent task.
Besides the host name passed to builder(...), only credentials(...) is mandatory on the builder[14]:
| Option | Default | Details |
|---|---|---|
credentials(String, char[]) |
required | User name and domain[15] |
https() / http(), port(int) |
HTTP; port 5985 (5986 with HTTPS) | TLS / HTTPS[16] |
authentication(AuthScheme...) |
NTLM | Authentication[5] |
ticketCache(Path), allowDelegation() |
none, off | Kerberos[17], Credential delegation[18] |
sslContext(SSLContext) / trustAllCertificates() |
JDK trust store, hostname verified | TLS / HTTPS[16] |
timeout(Duration) |
30 s | Timeouts and Errors[19] |
retries(int, Duration) |
no retry | Retrying[20] |
namespace(String) |
ROOT\CIMV2 |
Choosing a namespace[21] |
loadUserProfile() |
not loaded | Loading the user profile[22] |
maxCommandsPerShell(int) |
10 | Shell reuse[23] |
consoleCodePage(int) |
65001 (UTF-8) | Input encoding[24] |
arraySeparator(String) |
\| |
Reading the result[25] |
Where to go next
- Installation[8] — coordinates, supported JDKs, and the standalone CLI jar
- Preparing the Windows Host[9] — prerequisites on the target: enabling WinRM and the privileges the account needs
- WQL Queries[1] — query WMI and read the result
- Remote Commands[2] — run commands and copy files to the host
- File Transfers[26] — how files are copied to the host and downloaded back through the WinRM channel
- Remote Files[3] — read remote files (whole, byte ranges, tails, streams, digests), get file properties, list directories
- Command-Line Client[4] — the standalone jar's manual page
- Authentication[5] — NTLM, Kerberos (including credential delegation), and Basic
- TLS / HTTPS[16] — certificate validation and trust stores
- Timeouts and Errors[19] — timeout semantics and the exception surface
- Migrating from 1.x[6] — the 2.0.00 breaking changes, and moving to the fluent API
- Migrating from winrm4j[27] — moving from cloudsoft/winrm4j: option mapping and behavioral differences
- Legacy API[28] — the static one-shot helpers that predate
WinRMClient
- [1] wql.html
- [2] commands.html
- [3] files.html
- [4] cli.html
- [5] authentication.html
- [6] migrating-from-1x.html
- [7] https://central.sonatype.com/artifact/org.metricshub/winrm-java
- [8] installation.html
- [9] preparing-the-host.html
- [10] apidocs/org/metricshub/winrm/WinRMClient.html
- [11] apidocs/org/metricshub/winrm/exceptions/WinRMClientException.html
- [12] apidocs/org/metricshub/winrm/wql/WinRMWqlExecutor.html
- [13] apidocs/org/metricshub/winrm/command/WinRMCommandExecutor.html
- [14] apidocs/org/metricshub/winrm/WinRMClient.Builder.html
- [15] authentication.html#user-name-and-domain
- [16] tls.html
- [17] authentication.html#kerberos-spnego
- [18] authentication.html#credential-delegation
- [19] timeouts-and-errors.html
- [20] timeouts-and-errors.html#retrying-transient-connection-failures
- [21] wql.html#choosing-a-namespace
- [22] commands.html#loading-the-user-profile
- [23] commands.html#shell-reuse
- [24] commands.html#input-encoding
- [25] wql.html#reading-the-result
- [26] file-transfers.html
- [27] migrating-from-winrm4j.html
- [28] legacy.html
