Skip to content

Document the WinRM prerequisites on the targeted host - #149

Merged
bertysentry merged 5 commits into
mainfrom
docs-preparing-the-windows-host
Jul 29, 2026
Merged

Document the WinRM prerequisites on the targeted host#149
bertysentry merged 5 commits into
mainfrom
docs-preparing-the-windows-host

Conversation

@bertysentry

Copy link
Copy Markdown
Contributor

What

Adds a Preparing the Windows Host documentation page: what must be true on the targeted Windows host before this client can reach it, and how to make it true.

Documentation only — no code, no behavior change.

Why

The library documented its own API thoroughly but said nothing about the prerequisites on the other end, which is where most "it doesn't connect" reports actually originate. Two questions came up in particular:

  • Is WinRM already enabled, and when? There's a widespread belief that domain membership is what enables it. It isn't — being a Windows Server edition (2012+) is. A domain-joined Windows 11 workstation still has WinRM off; a standalone Server 2022 in a workgroup has it on. The page corrects this explicitly and separates out the three things domain membership does change (Kerberos becomes possible, Group Policy becomes the practical mass-enablement route, and domain accounts escape UAC token filtering).
  • What privileges does the account need? Domain admin works, but the interesting cases are local admin and non-admin.

Privileges, summarized

Account Works out of the box?
Domain admin, or any domain account in the host's local Administrators Yes
Built-in local Administrator Yes (exempt from UAC token filtering)
Any other local admin No — denied until LocalAccountTokenFilterPolicy=1
Non-admin No — needs explicit grants on the listener and on WMI

The third row is the one that eats afternoons, so it gets its own section with Microsoft's own wording, the registry fix, a warning that it weakens the host against lateral movement (recommending a domain account in Administrators instead), and the diagnostic: if the built-in Administrator authenticates but another local admin doesn't with a known-good password, it's token filtering essentially every time.

Two things specific to this library

Worth a reviewer's attention, because generic WinRM guidance gets both wrong for us:

  • Privileges aren't one thing. The client uses two different plug-ins, gated separately: WQL needs the WMI plug-in plus namespace rights (Enable Account, Remote Enable, Execute Methods), commands need remote-shell access, and transfer-and-run needs both plus write access to <windir>\Temp and certutil/forfiles. An account can pass one and fail the other, so the page has readers test both (wql … and command whoami) via the CLI jar rather than one.
  • A "don't change these" list. AllowUnencrypted stays False (NTLM message encryption already satisfies the service over plain HTTP — the usual AllowUnencrypted=true advice targets Basic-auth clients), Basic/CredSSP stay False, and TrustedHosts is a Windows-client setting a Java client never reads. Relatedly, the default RootSDDL does not include Remote Management Users, so just adding an account to that group doesn't work either.

Also covered: enabling over HTTP and HTTPS, the Public-profile refusal on client editions, the Group Policy path plus the two things that policy doesn't do (open the firewall, start the service), configuring a non-administrator account step by step, the second-hop limitation (no CredSSP → avoid it), host quotas with old-vs-modern defaults, and a symptom→cause troubleshooting table keyed to the library's own exception types.

Wiring

New entry in the Getting Started menu, cross-linked from index, installation, authentication, tls, file-transfers and timeouts-and-errors, with the prerequisites summarized in README.md per the project convention that user-facing changes are documented there.

Notes for the reviewer

  • Facts are sourced from Microsoft docs, not from memory — Enable-PSRemoting, WinRM installation and configuration (service defaults, RootSDDL, quotas, WinRMRemoteWMIUsers__), Configure remote management in Server Manager (default-enabled state, the UAC statement), and the AllowAutoConfig policy.
  • One area is deliberately hedged: non-admin command execution. Listener access lets a non-admin open a shell, but what the command can then do is ordinary Windows security, and the shell plug-in's own descriptor is version-dependent. I couldn't verify those defaults against a live host, so the page recommends non-admin for WQL-only workloads and says to verify with command whoami rather than asserting specifics.
  • No CHANGELOG entry, since every existing entry there describes code or behavior and this is purely documentation — happy to add one under a Documentation heading if you'd prefer.
  • mvn site builds clean; all in-page anchors and cross-page links resolve, and the tables and callouts render correctly in the skin.

🤖 Generated with Claude Code

Users had no guidance on what must be true on the Windows host before
this client can reach it, which is the most common source of "it does
not connect" reports. Add a "Preparing the Windows Host" page covering
both prerequisites: WinRM being enabled and reachable, and the account
having sufficient privileges.

Highlights:

- When WinRM is already on: enabled by default on Windows Server 2012
  and later, off on client editions. Being domain-joined is not what
  enables it - being a Server edition is. Domain membership does matter
  for three other things: Kerberos becomes possible at all, Group Policy
  becomes the practical mass-enablement route, and domain accounts escape
  UAC token filtering.
- Enabling it over HTTP and HTTPS, the Public-profile refusal on client
  editions, firewall rules, and the Group Policy path - plus the two
  things that policy does not do (open the firewall, start the service).
- Privileges: domain admins, domain accounts in the host's local
  Administrators, and the built-in local Administrator work as-is. Other
  local admins are denied by UAC remote token filtering until
  LocalAccountTokenFilterPolicy is set, with a warning about what that
  weakens. Non-admin accounts need explicit grants on the listener
  (RootSDDL) and on WMI (WinRMRemoteWMIUsers__ plus namespace rights).
- Privileges are not one thing: WQL goes through the WMI plug-in and
  needs namespace rights, commands go through the remote-shell plug-in,
  and transfer-and-run needs both. An account can pass one and fail the
  other, so the page has readers test both with the CLI jar.
- A "do not change these" list: AllowUnencrypted, Basic, CredSSP and
  TrustedHosts all stay as they are, since NTLM message encryption
  already protects the payload over plain HTTP, and TrustedHosts is a
  Windows-client setting that a Java client never reads.
- Host quotas with old-vs-modern defaults, the second-hop limitation
  (no CredSSP support), and a symptom-to-cause troubleshooting table
  keyed to the library's own exceptions.

Wire the page into the Getting Started menu, cross-link it from the pages
where the question comes up (overview, installation, authentication, TLS,
file transfers, timeouts and errors), and summarize the prerequisites in
README.md.

Co-Authored-By: Claude Opus 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: 46bdc1b553

ℹ️ 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/site/markdown/preparing-the-host.md Outdated
Comment thread src/site/markdown/preparing-the-host.md
…t Users is not enough

Two review points on the new prerequisites page.

Execute Methods (accepted): a WQL SELECT needs only Enable Account and
Remote Enable on the namespace. Execute Methods authorizes invoking WMI
class methods, which this client never does - it runs SELECT queries and
rejects anything else locally as a WqlSyntaxException. Recommending it
expanded a non-administrator's privileges beyond what the API needs, so
it is gone, with a note saying why in case a reader has seen it in a
vendor guide.

Remote Management Users (declined, clarified instead): the review claimed
the default RootSDDL grants that group on Windows 8 / Server 2012 and
later, making the RootSDDL edit unnecessary. It does not. The documented
default is unchanged through Server 2022:

  O:NSG:BAD:P(A;;GA;;;BA)(A;;GR;;;IU)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)

Administrators (BA) full, interactive users (IU) read, no RM entry. The
group *is* granted on the PowerShell session configurations, which is
where the confusion comes from and why the group works for PowerShell
remoting but not for winrs, this client, or other third-party WinRM
clients. The page previously explained that distinction and lost it when
the PowerShell discussion was removed, which is presumably what made the
claim look wrong.

So the recommendation stands, but the page now states the default
descriptor inline, tells the reader to inspect their own value first (a
hardening baseline may have changed it), warns explicitly that group
membership is not sufficient and why, and prefers the configSDDL dialog
over assigning RootSDDL as a string since the dialog adds to the existing
descriptor rather than replacing it.

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

Copy link
Copy Markdown
Contributor Author

@codex please review again

@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: 37978771c1

ℹ️ 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/site/markdown/preparing-the-host.md Outdated
Comment thread src/site/markdown/preparing-the-host.md
Comment thread src/site/markdown/preparing-the-host.md Outdated
Comment thread src/site/markdown/preparing-the-host.md Outdated
…il for uploadFile, modern quota defaults

All four points accepted; each was verified before changing.

- HTTPS listener: the New-WSManInstance ValueSet now carries Hostname
  alongside CertificateThumbprint, which makes the certificate-to-name
  binding the surrounding prose describes explicit rather than implied.
- Group Policy: enabling "Allow remote server management through WinRM"
  also requires its IPv4/IPv6 filter fields; an empty filter disables the
  listener for that address family, so an "Enabled" policy with blank
  filters leaves the fleet with no listener at all. Called out as a
  warning, since the failure looks like the policy simply did not apply.
- uploadFile(...) requires certutil too: it delegates to
  ShellFileCopy.copyLocalFileToRemoteFile, whose digest probes
  (certutil -hashfile) and decoding (certutil -f -decode) are the same
  engine transfer-and-run uses. forfiles is genuinely specific to
  transfer-and-run, which purges its transfer directory, so the row now
  names certutil and says what it does not need.
- Quota defaults: MaxEnvelopeSizekb and IdleTimeout were quoted from the
  Win32 documentation's older WinRM 2.0 values. Modern hosts default to
  500 KB and 7200000 ms respectively, so both rows now distinguish old
  from modern like the three rows above them already did.

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

Copy link
Copy Markdown
Contributor Author

@codex please review again

@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: e735a808d4

ℹ️ 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/site/markdown/preparing-the-host.md
Comment thread src/site/markdown/preparing-the-host.md
Both review points were P1 and both are declined; one produced a useful
clarification anyway.

Remote Management Users (declined): the review asks to swap
WinRMRemoteWMIUsers__ for Remote Management Users, calling the former
legacy. It is not. Microsoft's current WinRM documentation names
WinRMRemoteWMIUsers__ for WMI plug-in access on "Windows 8 and Windows
Server 2012" and later, which is exactly the platform range this page
targets. And the substitution would break the procedure rather than fix
it: Remote Management Users is still absent from the default RootSDDL
(verified again this round), so membership in it cannot grant a
third-party WS-Man client access to the listener at all.

The confusion is understandable, though: Windows gives both groups the
identical description, "can access WMI resources over management
protocols". So rather than restate the RootSDDL point, this commit adds a
note that names both groups, says which one the WinRM documentation
prescribes and that it is current rather than legacy, mentions that it
only exists once WinRM has been configured, and states plainly that
membership in neither group suffices on its own - the namespace rights
and the RootSDDL entry are what grant access.

License header (declined): site markdown is outside the license-header
workflow in this project. The plugin is declared in pluginManagement only,
with no execution and no configuration, so nothing binds it to a phase and
src/site is not among its default roots. Running the documented
`mvn license:update-file-header` scans 64 files and leaves every markdown
page untouched, including this one; none of the eleven pre-existing site
pages carries a header either. A header would also have to sit above the
keywords/description metadata block Doxia requires at the top of the file,
and would render as visible text in the published page.

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

Copy link
Copy Markdown
Contributor Author

@codex please review again

@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: 48ca7c4314

ℹ️ 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 README.md Outdated
…mmands

Accepted, and it exposed an inconsistency in the page itself: the
operation-by-operation table correctly listed WMI rights for WQL only,
while both summaries - the short-answer table and the README bullet -
presented "listener and WMI" as one blanket requirement for every
non-administrator. A command-only account was therefore being told to
grant namespace access it can never use.

Verified against the source before changing: the only internal WQL queries
are the transfer directory lookup (SELECT WindowsDirectory, transfer-and-run
only) and getWindowsEncodingCharset, which is deprecated since 2.0.00 and
has no callers - command output is decoded with the code page the shell is
created with, so client.command(...) and uploadFile(...) issue no WMI
request at all.

The short-answer table and the README bullet now qualify the WMI grants as
WQL-only, and the non-administrator walkthrough states that step 1 is
always required while step 2 applies only to WQL and transfer-and-run.

One deliberate omission: the CLI's *interactive* shell does query
SELECT CodeSet to pin the remote ANSI code page, but a denial there falls
back to code page 1252 rather than failing, so it is not a privilege
requirement and naming it would imply one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@bertysentry
bertysentry merged commit 134da85 into main Jul 29, 2026
5 checks passed
@bertysentry
bertysentry deleted the docs-preparing-the-windows-host branch July 29, 2026 16:41
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.

1 participant