Class LightWinRMService

java.lang.Object
org.metricshub.winrm.light.LightWinRMService
All Implemented Interfaces:
AutoCloseable, WindowsRemoteExecutor

public final class LightWinRMService extends Object implements WindowsRemoteExecutor
Dependency-free WindowsRemoteExecutor backed by WsmanClient. A drop-in replacement for the CXF-based WinRMService that shipped before 2.0.0: same public behaviour, no Apache CXF / JAX-WS / JAXB stack, and immune by construction to JAXP ServiceLoader poisoning (it uses the JDK-default XML factories).

Supports NTLM over HTTP (with message encryption) and over HTTPS (plaintext SOAP inside TLS, validating the server certificate by default; see LightTls), Kerberos over HTTPS (SPNEGO via the JDK GSS-API; see KerberosAuthScheme), and HTTP Basic (the credential rides the Authorization header of every request; see BasicAuthScheme). A multi-scheme request such as [KERBEROS, NTLM] is tried in order with fallback.

  • Field Details

    • DEFAULT_ARRAY_SEPARATOR

      public static final String DEFAULT_ARRAY_SEPARATOR
      The default string joining the elements of a WMI array property in a WQL row.
      See Also:
    • DEFAULT_MAX_COMMANDS_PER_SHELL

      public static final int DEFAULT_MAX_COMMANDS_PER_SHELL
      The default number of commands a remote command shell runs before the client replaces it. Each command holds one of the user's WSMan operations until its shell is deleted, and Windows Server 2008 R2 allows only 15 per user (MaxConcurrentOperationsPerUser).
      See Also:
  • Method Details

    • createInstance

      public static LightWinRMService createInstance(WinRMEndpoint winRMEndpoint, long timeout, Path ticketCache, List<AuthenticationEnum> authentications) throws WinRMException
      Create a light WinRM executor.
      Parameters:
      winRMEndpoint - endpoint with credentials (mandatory)
      timeout - timeout in milliseconds (must be > 0)
      ticketCache - Kerberos ticket cache path (used by the Kerberos scheme; null logs in with the password)
      authentications - requested authentication schemes, tried in order (NTLM, Kerberos, and/or Basic); null/empty means NTLM only
      Returns:
      a new LightWinRMService
      Throws:
      WinRMException - on invalid arguments or an unsupported authentication request
    • createInstance

      public static LightWinRMService createInstance(WinRMEndpoint winRMEndpoint, long timeout, Path ticketCache, List<AuthenticationEnum> authentications, SSLContext sslContext, boolean trustAllCertificates) throws WinRMException
      Create a light WinRM executor with an explicit TLS configuration, overriding the org.metricshub.winrm.tls.insecure system property for this instance.
      Parameters:
      winRMEndpoint - endpoint with credentials (mandatory)
      timeout - timeout in milliseconds (must be > 0)
      ticketCache - Kerberos ticket cache path (used by the Kerberos scheme; null logs in with the password)
      authentications - requested authentication schemes, tried in order (NTLM, Kerberos, and/or Basic); null/empty means NTLM only
      sslContext - the SSLContext providing the HTTPS socket factory (hostname verification stays on); null uses the default configuration
      trustAllCertificates - when true (and no sslContext is given), trust every server certificate and skip hostname verification — insecure, testing only
      Returns:
      a new LightWinRMService
      Throws:
      WinRMException - on invalid arguments or an unsupported authentication request
    • createInstance

      public static LightWinRMService createInstance(WinRMEndpoint winRMEndpoint, long timeout, Path ticketCache, List<AuthenticationEnum> authentications, SSLContext sslContext, boolean trustAllCertificates, int consoleCodePage) throws WinRMException
      Create a light WinRM executor with an explicit console code page for the command shell.
      Parameters:
      winRMEndpoint - endpoint with credentials (mandatory)
      timeout - timeout in milliseconds (must be > 0)
      ticketCache - Kerberos ticket cache path (used by the Kerberos scheme; null logs in with the password)
      authentications - requested authentication schemes, tried in order (NTLM, Kerberos, and/or Basic); null/empty means NTLM only
      sslContext - the SSLContext providing the HTTPS socket factory (hostname verification stays on); null uses the default configuration
      trustAllCertificates - when true (and no sslContext is given), trust every server certificate and skip hostname verification — insecure, testing only
      consoleCodePage - the console code page of the command shell; 0 keeps the default 65001, which makes command output UTF-8 whatever the remote locale
      Returns:
      a new LightWinRMService
      Throws:
      WinRMException - on invalid arguments or an unsupported authentication request
    • createInstance

      public static LightWinRMService createInstance(WinRMEndpoint winRMEndpoint, long timeout, Path ticketCache, List<AuthenticationEnum> authentications, SSLContext sslContext, boolean trustAllCertificates, int consoleCodePage, int connectRetries, long retryDelay) throws WinRMException
      Create a light WinRM executor with an opt-in retry policy for transient connection failures. A round trip is retried only when it failed to establish and authenticate the connection — TCP connect, DNS resolution, TLS handshake, or a transport error during the authentication handshake — i.e. when its request provably never reached the server; a request that may have started executing is never retried, preserving at-most-once execution semantics.
      Parameters:
      winRMEndpoint - endpoint with credentials (mandatory)
      timeout - timeout in milliseconds (must be > 0)
      ticketCache - Kerberos ticket cache path (used by the Kerberos scheme; null logs in with the password)
      authentications - requested authentication schemes, tried in order (NTLM, Kerberos, and/or Basic); null/empty means NTLM only
      sslContext - the SSLContext providing the HTTPS socket factory (hostname verification stays on); null uses the default configuration
      trustAllCertificates - when true (and no sslContext is given), trust every server certificate and skip hostname verification — insecure, testing only
      consoleCodePage - the console code page of the command shell; 0 keeps the default 65001, which makes command output UTF-8 whatever the remote locale
      connectRetries - how many times one round trip may re-attempt to connect and authenticate (must be >= 0); 0 keeps the historical fail-fast behavior
      retryDelay - the pause in milliseconds before each retry (must be >= 0)
      Returns:
      a new LightWinRMService
      Throws:
      WinRMException - on invalid arguments or an unsupported authentication request
    • createInstance

      public static LightWinRMService createInstance(WinRMEndpoint winRMEndpoint, long timeout, Path ticketCache, List<AuthenticationEnum> authentications, boolean allowDelegation, SSLContext sslContext, boolean trustAllCertificates, int consoleCodePage, boolean loadUserProfile, int connectRetries, long retryDelay) throws WinRMException
      Create a light WinRM executor that may delegate the caller's Kerberos credentials to the host, so remote commands can authenticate onward as the caller (the second hop), and may load the user profile in the command shell. WMI array properties are joined with DEFAULT_ARRAY_SEPARATOR.
      Parameters:
      winRMEndpoint - endpoint with credentials (mandatory)
      timeout - timeout in milliseconds (must be > 0)
      ticketCache - Kerberos ticket cache path (used by the Kerberos scheme; null logs in with the password)
      authentications - requested authentication schemes, tried in order (NTLM, Kerberos, and/or Basic); null/empty means NTLM only
      allowDelegation - whether Kerberos forwards the caller's ticket-granting ticket to the host (which must then be forwardable); requires Kerberos among authentications
      sslContext - the SSLContext providing the HTTPS socket factory (hostname verification stays on); null uses the default configuration
      trustAllCertificates - when true (and no sslContext is given), trust every server certificate and skip hostname verification — insecure, testing only
      consoleCodePage - the console code page of the command shell; 0 keeps the default 65001, which makes command output UTF-8 whatever the remote locale
      loadUserProfile - whether the command shell loads the user profile (registry hive, per-user environment variables); false is the historical behavior
      connectRetries - how many times one round trip may re-attempt to connect and authenticate (must be >= 0); 0 keeps the historical fail-fast behavior
      retryDelay - the pause in milliseconds before each retry (must be >= 0)
      Returns:
      a new LightWinRMService
      Throws:
      WinRMException - on invalid arguments or an unsupported authentication request
    • createInstance

      public static LightWinRMService createInstance(WinRMEndpoint winRMEndpoint, long timeout, Path ticketCache, List<AuthenticationEnum> authentications, boolean allowDelegation, SSLContext sslContext, boolean trustAllCertificates, int consoleCodePage, boolean loadUserProfile, String arraySeparator, int connectRetries, long retryDelay) throws WinRMException
      Create a light WinRM executor that may delegate the caller's Kerberos credentials to the host, so remote commands can authenticate onward as the caller (the second hop), may load the user profile in the command shell, and joins WMI array properties with a custom separator. The command shell is replaced every DEFAULT_MAX_COMMANDS_PER_SHELL commands.
      Parameters:
      winRMEndpoint - endpoint with credentials (mandatory)
      timeout - timeout in milliseconds (must be > 0)
      ticketCache - Kerberos ticket cache path (used by the Kerberos scheme; null logs in with the password)
      authentications - requested authentication schemes, tried in order (NTLM, Kerberos, and/or Basic); null/empty means NTLM only
      allowDelegation - whether Kerberos forwards the caller's ticket-granting ticket to the host (which must then be forwardable); requires Kerberos among authentications
      sslContext - the SSLContext providing the HTTPS socket factory (hostname verification stays on); null uses the default configuration
      trustAllCertificates - when true (and no sslContext is given), trust every server certificate and skip hostname verification — insecure, testing only
      consoleCodePage - the console code page of the command shell; 0 keeps the default 65001, which makes command output UTF-8 whatever the remote locale
      loadUserProfile - whether the command shell loads the user profile (registry hive, per-user environment variables); false is the historical behavior
      arraySeparator - the string joining the elements of a WMI array property in a WQL row; see DEFAULT_ARRAY_SEPARATOR
      connectRetries - how many times one round trip may re-attempt to connect and authenticate (must be >= 0); 0 keeps the historical fail-fast behavior
      retryDelay - the pause in milliseconds before each retry (must be >= 0)
      Returns:
      a new LightWinRMService
      Throws:
      WinRMException - on invalid arguments or an unsupported authentication request
    • createInstance

      public static LightWinRMService createInstance(WinRMEndpoint winRMEndpoint, long timeout, Path ticketCache, List<AuthenticationEnum> authentications, boolean allowDelegation, SSLContext sslContext, boolean trustAllCertificates, int consoleCodePage, boolean loadUserProfile, String arraySeparator, int maxCommandsPerShell, int connectRetries, long retryDelay) throws WinRMException
      Create a light WinRM executor that may delegate the caller's Kerberos credentials to the host, so remote commands can authenticate onward as the caller (the second hop), may load the user profile in the command shell, joins WMI array properties with a custom separator, and replaces the command shell after a given number of commands.
      Parameters:
      winRMEndpoint - endpoint with credentials (mandatory)
      timeout - timeout in milliseconds (must be > 0)
      ticketCache - Kerberos ticket cache path (used by the Kerberos scheme; null logs in with the password)
      authentications - requested authentication schemes, tried in order (NTLM, Kerberos, and/or Basic); null/empty means NTLM only
      allowDelegation - whether Kerberos forwards the caller's ticket-granting ticket to the host (which must then be forwardable); requires Kerberos among authentications
      sslContext - the SSLContext providing the HTTPS socket factory (hostname verification stays on); null uses the default configuration
      trustAllCertificates - when true (and no sslContext is given), trust every server certificate and skip hostname verification — insecure, testing only
      consoleCodePage - the console code page of the command shell; 0 keeps the default 65001, which makes command output UTF-8 whatever the remote locale
      loadUserProfile - whether the command shell loads the user profile (registry hive, per-user environment variables); false is the historical behavior
      arraySeparator - the string joining the elements of a WMI array property in a WQL row; see DEFAULT_ARRAY_SEPARATOR
      maxCommandsPerShell - how many commands a command shell runs before it is replaced (must be > 0); see DEFAULT_MAX_COMMANDS_PER_SHELL
      connectRetries - how many times one round trip may re-attempt to connect and authenticate (must be >= 0); 0 keeps the historical fail-fast behavior
      retryDelay - the pause in milliseconds before each retry (must be >= 0)
      Returns:
      a new LightWinRMService
      Throws:
      WinRMException - on invalid arguments or an unsupported authentication request
    • executeWql

      public List<Map<String,Object>> executeWql(String wqlQuery, long timeout) throws TimeoutException, WqlQuerySyntaxException, WindowsRemoteException
      Description copied from interface: WindowsRemoteExecutor

      Execute a WQL query and process its result.

      Specified by:
      executeWql in interface WindowsRemoteExecutor
      Parameters:
      wqlQuery - the WQL query (required)
      timeout - Timeout in milliseconds (throws an IllegalArgumentException if negative or zero)
      Returns:
      a list of result rows. A result row is a Map(LinkedHashMap to preserve the query order) of properties/values.
      Throws:
      TimeoutException - to notify userName of timeout.
      WqlQuerySyntaxException - if WQL query syntax is invalid
      WindowsRemoteException - For any problem encountered
    • executeWql

      public List<Map<String,Object>> executeWql(String namespace, String wqlQuery, long timeout, int maxElements, long pullTimeout) throws TimeoutException, WqlQuerySyntaxException, WindowsRemoteException
      Description copied from interface: WindowsRemoteExecutor

      Execute a WQL query with explicit enumeration parameters: the WMI namespace, the WS-Enumeration MaxElements batch size, and the per-Pull MaxTime.

      The default implementation throws UnsupportedOperationException: only executors that can honor the namespace and enumeration parameters (such as the built-in lightweight backend) implement this method, and silently ignoring a namespace would query the wrong resource.

      Specified by:
      executeWql in interface WindowsRemoteExecutor
      Parameters:
      namespace - the WMI namespace to query, e.g. ROOT\CIMV2 (required)
      wqlQuery - the WQL query (required)
      timeout - Timeout in milliseconds (throws an IllegalArgumentException if negative or zero)
      maxElements - maximum number of rows per Enumerate/Pull response (throws an IllegalArgumentException if negative or zero); see WindowsRemoteExecutor.DEFAULT_WQL_MAX_ELEMENTS
      pullTimeout - maximum time in milliseconds the server may hold a single Pull open before answering with the rows it has (MaxTime); 0 leaves it to the server default
      Returns:
      a list of result rows. A result row is a Map(LinkedHashMap to preserve the query order) of properties/values.
      Throws:
      TimeoutException - to notify userName of timeout.
      WqlQuerySyntaxException - if WQL query syntax is invalid
      WindowsRemoteException - For any problem encountered
    • streamWql

      public WqlCursor streamWql(String namespace, String wqlQuery, long timeout, int maxElements, long pullTimeout) throws TimeoutException, WqlQuerySyntaxException, WindowsRemoteException
      Description copied from interface: WindowsRemoteExecutor

      Start a WQL enumeration and return a lazy WqlCursor over its rows: rows can be consumed as the WS-Enumeration pages arrive, and memory stays bounded by one page.

      The default implementation throws UnsupportedOperationException: only executors that support streaming (such as the built-in lightweight backend) implement this method.

      Specified by:
      streamWql in interface WindowsRemoteExecutor
      Parameters:
      namespace - the WMI namespace to query, e.g. ROOT\CIMV2 (required)
      wqlQuery - the WQL query (required)
      timeout - timeout in milliseconds of each WSMan round trip — the inactivity timeout of the stream, not an overall deadline (throws an IllegalArgumentException if negative or zero)
      maxElements - maximum number of rows per Enumerate/Pull response (throws an IllegalArgumentException if negative or zero); see WindowsRemoteExecutor.DEFAULT_WQL_MAX_ELEMENTS
      pullTimeout - maximum time in milliseconds the server may hold a single Pull open before answering with the rows it has (MaxTime); 0 leaves it to the server default
      Returns:
      a cursor over the result rows, owning the executor's connection until exhausted or closed — always close it (try-with-resources)
      Throws:
      TimeoutException - when the server does not answer the initial Enumerate in time
      WqlQuerySyntaxException - if WQL query syntax is invalid
      WindowsRemoteException - For any problem encountered
    • startCommand

      public CommandCursor startCommand(String command, String workingDirectory, long timeout) throws TimeoutException, WindowsRemoteException
      Description copied from interface: WindowsRemoteExecutor

      Start a command on the remote host and return a CommandCursor over its raw output: chunks can be consumed as the WSMan Receive responses arrive, before the command exits.

      The default implementation throws UnsupportedOperationException: only executors that support streaming (such as the built-in lightweight backend) implement this method.

      Specified by:
      startCommand in interface WindowsRemoteExecutor
      Parameters:
      command - The command to execute
      workingDirectory - Path of the directory for the spawned process on the remote system (can be null)
      timeout - timeout in milliseconds of each WSMan round trip — the inactivity timeout of the stream, not an overall deadline (throws an IllegalArgumentException if negative or zero)
      Returns:
      a cursor over the command output, owning the executor's connection until the command completes or the cursor is closed — always close it (try-with-resources)
      Throws:
      TimeoutException - when the server does not answer the command startup in time
      WindowsRemoteException - For any problem encountered
    • startCommand

      public CommandCursor startCommand(String command, String workingDirectory, long timeout, boolean consoleModeStdin) throws TimeoutException, WindowsRemoteException
      Description copied from interface: WindowsRemoteExecutor

      Variant of WindowsRemoteExecutor.startCommand(String, String, long) making the WINRS_CONSOLEMODE_STDIN option explicit. The three-argument variant keeps the historical console semantics (TRUE); pass false when the command will be fed standard input through CommandCursor.send(byte[], boolean) and must see it as an ordinary pipe — a console-mode stdin never reaches EOF for tools like sort or more.

      The default implementation delegates console-mode requests to WindowsRemoteExecutor.startCommand(String, String, long) — an executor that overrides only the historical three-argument variant keeps working for ordinary commands — and throws UnsupportedOperationException for pipe mode: only executors that support command input (such as the built-in lightweight backend) implement it.

      Specified by:
      startCommand in interface WindowsRemoteExecutor
      Parameters:
      command - The command to execute
      workingDirectory - Path of the directory for the spawned process on the remote system (can be null)
      timeout - timeout in milliseconds of each WSMan round trip — the inactivity timeout of the stream, not an overall deadline (throws an IllegalArgumentException if negative or zero)
      consoleModeStdin - the value of the WINRS_CONSOLEMODE_STDIN option: true for console semantics (the historical default), false for pipe semantics
      Returns:
      a cursor over the command output, owning the executor's connection until the command completes or the cursor is closed — always close it (try-with-resources)
      Throws:
      TimeoutException - when the server does not answer the command startup in time
      WindowsRemoteException - For any problem encountered
    • startCommand

      public CommandCursor startCommand(String command, String workingDirectory, Map<String,String> environment, long timeout, boolean consoleModeStdin) throws TimeoutException, WindowsRemoteException
      Description copied from interface: WindowsRemoteExecutor

      Variant of WindowsRemoteExecutor.startCommand(String, String, long, boolean) that also sets environment variables in the remote shell. Like the working directory, the environment is shell-scoped: it is honored only when the shell is created, i.e. by the first command this executor runs.

      The default implementation delegates to WindowsRemoteExecutor.startCommand(String, String, long, boolean) when no variable is requested — an executor unaware of this variant keeps working for ordinary commands — and throws UnsupportedOperationException otherwise: only executors that can put the variables on the wire (such as the built-in lightweight backend) implement it, and silently dropping them would run the command in the wrong environment.

      Specified by:
      startCommand in interface WindowsRemoteExecutor
      Parameters:
      command - The command to execute
      workingDirectory - Path of the directory for the spawned process on the remote system (can be null)
      environment - Environment variables of the remote shell, in insertion order (can be null or empty for none)
      timeout - timeout in milliseconds of each WSMan round trip — the inactivity timeout of the stream, not an overall deadline (throws an IllegalArgumentException if negative or zero)
      consoleModeStdin - the value of the WINRS_CONSOLEMODE_STDIN option: true for console semantics (the historical default), false for pipe semantics
      Returns:
      a cursor over the command output, owning the executor's connection until the command completes or the cursor is closed — always close it (try-with-resources)
      Throws:
      TimeoutException - when the server does not answer the command startup in time
      WindowsRemoteException - For any problem encountered
    • executeCommand

      public WindowsRemoteCommandResult executeCommand(String command, String workingDirectory, Charset charset, long timeout) throws WindowsRemoteException, TimeoutException
      Description copied from interface: WindowsRemoteExecutor
      Execute the command on the remote
      Specified by:
      executeCommand in interface WindowsRemoteExecutor
      Parameters:
      command - The command to execute
      workingDirectory - Path of the directory for the spawned process on the remote system (can be null)
      charset - The charset decoding the command output; null uses WindowsRemoteExecutor.SHELL_OUTPUT_CHARSET, which is what the remote shell actually emits
      timeout - Timeout in milliseconds
      Returns:
      The command result
      Throws:
      WindowsRemoteException - For any problem encountered
      TimeoutException - To notify userName of timeout.
    • executeCommand

      public WindowsRemoteCommandResult executeCommand(String command, String workingDirectory, Map<String,String> environment, Charset charset, long timeout) throws WindowsRemoteException, TimeoutException
      Description copied from interface: WindowsRemoteExecutor

      Variant of WindowsRemoteExecutor.executeCommand(String, String, Charset, long) that also sets environment variables in the remote shell. Like the working directory, the environment is shell-scoped: it is honored only when the shell is created, i.e. by the first command this executor runs.

      The default implementation delegates to WindowsRemoteExecutor.executeCommand(String, String, Charset, long) when no variable is requested — an executor unaware of this variant keeps working for ordinary commands — and throws UnsupportedOperationException otherwise: only executors that can put the variables on the wire (such as the built-in lightweight backend) implement it, and silently dropping them would run the command in the wrong environment.

      Specified by:
      executeCommand in interface WindowsRemoteExecutor
      Parameters:
      command - The command to execute
      workingDirectory - Path of the directory for the spawned process on the remote system (can be null)
      environment - Environment variables of the remote shell, in insertion order (can be null or empty for none)
      charset - The charset decoding the command output; null uses WindowsRemoteExecutor.SHELL_OUTPUT_CHARSET, which is what the remote shell actually emits
      timeout - Timeout in milliseconds
      Returns:
      The command result
      Throws:
      WindowsRemoteException - For any problem encountered
      TimeoutException - To notify userName of timeout.
    • getHostname

      public String getHostname()
      Description copied from interface: WindowsRemoteExecutor
      Get the hostname.
      Specified by:
      getHostname in interface WindowsRemoteExecutor
      Returns:
    • getUsername

      public String getUsername()
      Description copied from interface: WindowsRemoteExecutor
      Get the username.
      Specified by:
      getUsername in interface WindowsRemoteExecutor
      Returns:
    • getPassword

      public char[] getPassword()
      Description copied from interface: WindowsRemoteExecutor
      Get the password.
      Specified by:
      getPassword in interface WindowsRemoteExecutor
      Returns:
    • close

      public void close()
      Description copied from interface: WindowsRemoteExecutor
      Close the executor and release its resources. Narrows AutoCloseable.close() so it does not declare a checked exception, letting callers use try-with-resources without catching Exception.
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface WindowsRemoteExecutor