Skip to content

Shell environment variables: environment(name, value) on the fluent API and --env NAME=VALUE on the CLI (winrs -env) - #156

Merged
bertysentry merged 2 commits into
mainfrom
feature/shell-environment-variables
Aug 10, 2026
Merged

Shell environment variables: environment(name, value) on the fluent API and --env NAME=VALUE on the CLI (winrs -env)#156
bertysentry merged 2 commits into
mainfrom
feature/shell-environment-variables

Conversation

@bertysentry

Copy link
Copy Markdown
Contributor

Closes #137.

What

The WSMan Create request can now carry the optional rsp:Environment block:

<rsp:Environment>
  <rsp:Variable Name="BUILD_NUMBER">42</rsp:Variable>
  <rsp:Variable Name="CONFIG">release</rsp:Variable>
</rsp:Environment>

Fluent API

CommandResult result = client.command("build.cmd")
    .environment("BUILD_NUMBER", "42")
    .environment("CONFIG", "release")
    .execute();

Same contract as workingDirectory(String): the environment is shell-scoped, honored when the shell is created — i.e. by the client's first command — with insertion order preserved, names validated non-blank, and values XML-escaped.

Pinning semantics (the #133 invariant)

The environment is pinned by the first command (defensively copied) and replayed with its ORIGINAL values when the server reaps the shell and the client silently recreates it — a recreation stays invisible, for the working directory and the environment alike.

Element order

Per the MS-WSMV Shell_Type schema sequence, the rsp:Shell body now emits Environment, then WorkingDirectory, then InputStreams/OutputStreams (the order of the protocol's own Create example). Note: WorkingDirectory previously came after the stream declarations; the schema order is asserted by the wire tests, but a run against a real Windows host is still advisable.

SPI

WindowsRemoteExecutor gains environment-aware default overloads of executeCommand and startCommand that delegate to the historical entry points when no variable is requested, and throw UnsupportedOperationException otherwise — an executor unaware of the variant keeps working, and variables are never silently dropped.

CLI

--env NAME=VALUE, repeatable (winrs-style), split on the first = (the value may itself contain =), valid for command and shell, usage error otherwise:

winrm-java -h server -u 'DOMAIN\user' -pf pw.txt \
  --env BUILD_NUMBER=42 --env CONFIG=release \
  exec build.cmd

Tests

  • Wire assertion of the rsp:Environment block (content, escaping, insertion order, schema element order) on Create, via FakeWsmanServer.
  • Pinned replay of the environment on shell recreation after a shell-not-found fault.
  • SPI default delegation/refusal for legacy executors.
  • CLI parsing (repeatable, first-= split, usage errors, wql rejection) and end-to-end CLI wire tests for exec and shell.

Docs

commands.md option table, cli.md options table, and one --help line.

🤖 Generated with Claude Code

…AME=VALUE (#137)

The WSMan Create request now carries an optional rsp:Environment block,
placed per the MS-WSMV Shell_Type schema sequence (Environment, then
WorkingDirectory, then the stream declarations). Like the working
directory, the environment is shell-scoped: it is honored by the
client's first command and replayed with its original values when a
reaped shell is silently recreated.

- Fluent API: CommandRequest.environment(name, value), repeatable,
  insertion order preserved, values XML-escaped.
- SPI: environment-aware default overloads on WindowsRemoteExecutor
  that delegate to the historical entry points when no variable is set
  and refuse (never silently drop) otherwise.
- CLI: --env NAME=VALUE, repeatable, split on the first '=', valid for
  the command and shell subcommands (winrs -env parity).
- Docs: commands.md option table, cli.md options table, --help line.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fe3fbf32d3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/main/java/org/metricshub/winrm/CommandRequest.java
…e shell (#137)

When .environment(...) is combined with .upload(...), the ShellFileCopy
transfer commands run first and are what actually creates (and pins the
settings of) the remote shell; the environment was discarded after
preparation and the real command silently ran without it.

ShellFileCopy.copyLocalFilesToRemote now takes the shell environment and
threads it into every command leg: whichever leg creates the shell pins
it, and the caller's command inherits it. The historical entry point
delegates with no environment, so the legacy WinRMCommandExecutor and
custom executors are unaffected.

Tests: transfer legs carry the environment (ShellFileCopyTest), and an
end-to-end wire test asserts the Create request of an upload-created
shell carries the rsp:Environment block (WinRMClientTest).

Addresses the Codex review on PR #156.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@bertysentry

Copy link
Copy Markdown
Contributor Author

@codex please review again

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🚀

Reviewed commit: 798d200d4f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@bertysentry
bertysentry merged commit d3cca5e into main Aug 10, 2026
5 checks passed
@bertysentry
bertysentry deleted the feature/shell-environment-variables branch August 10, 2026 22:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Shell environment variables: environment(name, value) on the fluent API and --env NAME=VALUE on the CLI (winrs -env)

1 participant