Skip to content

PingCastle 4.0 documentation - #1270

Open
JoeDibley wants to merge 43 commits into
devfrom
JD/PingCastle-4-0
Open

PingCastle 4.0 documentation#1270
JoeDibley wants to merge 43 commits into
devfrom
JD/PingCastle-4-0

Conversation

@JoeDibley

@JoeDibley JoeDibley commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • New PingCastle 4.0 documentation: install/architecture, Entra scanning, scheduler rewrite, audit log, split settings pages
  • Adds screenshots for the new 4.0 pages (audit log, Entra tenant wizard, scheduler, settings tabs)

Test plan

  • Vale/Dale clean on changed files
  • Build succeeds with no broken links
  • Spot-check screenshots render correctly in each doc

Closes #1278

JoeDibley and others added 12 commits July 26, 2026 08:31
Adds Enterprise/Pro/Standard docs for PingCastle 4.0, registers the
version in products.js as the new default, and removes the unsupported
Azure hosting section from the Enterprise install guide now that
deployment is Windows-only via the installer.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…r labels

CloudAPI microservice and PingCastleSchedulerService replace the old
Windows Task Scheduler model; docs and diagrams updated to match.
Manual/Linux install and appsettings.json sections removed since
Enterprise 4.0 is Windows Server + IIS + SQL Server only. Logging
docs rewritten for the new web portal-based configuration.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ork ports

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…NET version refs

Expand quick install Step 2 in both tabs with the full wizard walkthrough (prerequisite check, license, install type, app pool identity, auth methods, HTTPS, email) and post-install gotchas; correct ASP.NET 8.0 references to 10.0.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Break the monolithic install page into architecture, requirements,
auth setup, email setup, license, post-install, settings, and
troubleshooting pages; update sidebar and cross-links accordingly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Note deleted objects lack links, and list the two audit-log settings
under Data Retention instead of just linking out.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Break out action plans, application, data retention, Entra scanner,
and scanning/scheduling settings into dedicated pages; update related
docs and sidebar links.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Link text still said "Settings: X" and "Enterprise Scheduling" from
before the settings pages were split and renamed; update references
to match the current page titles, and fill in the Entra tenant
connection steps.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… clarify 3.5-only migration

Config migration content belongs with settings docs, not the upgrade guide; also flags the exe.config migration as a one-time 3.5 event.
…/Graph conflict

Setup-EntraScannerApp.ps1 had several runtime bugs found while testing against
a live tenant: wrong Add-RoleGroupMember param for EXO's cmdlet, missing
Get-MgDirectoryRole module import, non-idempotent app role grants on reuse,
EXO replication lag on the new service principal, and an Azure.Core version
clash between Az.Resources and Microsoft.Graph in the same process. Also
exports the generated self-signed cert as a .pfx.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…duler, and settings pages

Captures 18 cropped screenshots (content panels only, no nav/sidebar chrome)
for new PingCastle 4.0 pages and replaces their TODO markers.
@JoeDibley
JoeDibley requested a review from a team as a code owner July 28, 2026 01:20
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Broken Anchor Links

1 broken anchor link(s) found — these will cause the build to fail.

  docs/pingcastle/4.0/enterprisearchitecture.md:75
    - Scheduled scans of local and trusted domains are handled by `PingCastleSchedulerService` (see [Scheduling scans](enterprisepostinstall.md#scheduling-scans))
    #scheduling-scans not found in docs/pingcastle/4.0/enterprisepostinstall.md
    Available: #post-installation-configuration-for-pingcastle-enterprise · #common-steps · #configuring-https · #iis-maximum-upload-configuration · #manual-report-import-size-limit · #automatic-forest-exploration-setup · #manual-execution · #automated-execution-for-agent-setup · #scheduling-your-first-scan · #scheduling-an-active-directory-scan · #scheduling-an-entra-scan · #initial-startup · #initial-configuration · #entities · #encryption · #bulk-import-of-existing-reports · #report-archiving-configuration · #configuration · #how-archiving-works · #what-gets-archived · #pingcastle-agent-deployment · #synchronization-feature · #configuration · #synchronization-patterns · #synchronization-patterns-at-import-time · #connection-tests

Auto-Fix Summary

2 issues fixed, 10 skipped across 26 files

Category Fixes
Dale: positional-references 2
Skipped (needs manual review) Reason
docs/pingcastle/4.0/enterpriseemailsetup.md:45 — Netwrix.TypeVsEnter 'type' is used as a noun ('the credential type the app registration uses'), not the verb instructing a user to supply text. False positive.
docs/pingcastle/4.0/enterpriseentrascan.md:118 — Netwrix.FirstPerson 'my' is part of the literal, bolded Entra admin center menu label 'APIs my organization uses'. Rewriting would misname a UI element and break accuracy.
docs/pingcastle/4.0/enterpriseentrascan.md:134 — Netwrix.FirstPerson 'my' is part of the literal, bolded Entra admin center menu label 'APIs my organization uses'. Rewriting would misname a UI element and break accuracy.
docs/pingcastle/4.0/enterprisesettings-entrascanner.md:13 — Netwrix.OxfordComma 'request and client timeouts' is a single compound list item, not a three-item series. The list already has its Oxford comma before 'and circuit breaker thresholds'. Adding a comma would be incorrect.
docs/pingcastle/4.0/enterprisetroubleshooting.md:177 — Netwrix.OxfordComma 'Enterprise and CloudAPI' is a two-item pairing, not a series of three, so no Oxford comma applies. False positive.
docs/pingcastle/4.0/enterpriseemailsetup.md:615 — Dale: exclamatory-sentences Exclamation is inside a PowerShell Write-Host string within a code block, not prose; changing it would alter the script output.
docs/pingcastle/4.0/enterpriseemailsetup.md:622 — Dale: exclamatory-sentences Exclamation is inside a PowerShell Write-Host string within a code block, not prose; changing it would alter the script output.
docs/pingcastle/4.0/enterpriseuser.md:9 — Dale: xy-slop 'The goal of the tool isn't perfection, but to provide reliable data' uses the negative-positive form, but the contrast is intentional expectation-setting; rewriting would drop meaningful nuance.
docs/pingcastle/4.0/proinstall.md:8 — Dale: xy-slop Same 'goal isn't perfection, but to provide reliable data' framing; the contrast conveys intended scope, so rewriting risks changing meaning.
docs/pingcastle/4.0/prouser.md:11 — Dale: xy-slop Same 'goal ... wasn't to aim for perfection, but to provide reliable data' framing; intentional contrast, skipped to preserve meaning.

Ask @claude on this PR if you'd like an explanation of any fix.

Comment thread docs/pingcastle/4.0/enterpriseauthsetup.md Outdated
Comment thread docs/pingcastle/4.0/index.md Outdated
Comment thread docs/pingcastle/4.0/index.md Outdated
JoeDibley and others added 2 commits July 29, 2026 07:55
…reenshots

Microsoft rebranded Azure AD to Entra ID; update terminology across enterprise/pro
4.0 docs and refresh accompanying screenshots to match current UI.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Broken Anchor Links

1 broken anchor link(s) found — these will cause the build to fail.

  docs/pingcastle/4.0/enterprisearchitecture.md:75
    - `PingCastleSchedulerService` handles scheduled scans of local and trusted domains (see [Scheduling scans](enterprisepostinstall.md#scheduling-scans))
    #scheduling-scans not found in docs/pingcastle/4.0/enterprisepostinstall.md
    Available: #post-installation-configuration-for-pingcastle-enterprise · #common-steps · #configuring-https · #iis-maximum-upload-configuration · #manual-report-import-size-limit · #automatic-forest-exploration-setup · #manual-execution · #automated-execution-for-agent-setup · #scheduling-your-first-scan · #scheduling-an-active-directory-scan · #scheduling-an-entra-scan · #initial-startup · #initial-configuration · #entities · #encryption · #bulk-import-of-existing-reports · #report-archiving-configuration · #configuration · #how-archiving-works · #what-gets-archived · #pingcastle-agent-deployment · #synchronization-feature · #configuration · #synchronization-patterns · #synchronization-patterns-at-import-time · #connection-tests

Auto-Fix Summary

10 issues fixed, 11 skipped across 26 files

Category Fixes
Dale: passive-voice 9
Dale: wordiness 1
Skipped (needs manual review) Reason
docs/pingcastle/4.0/enterpriseemailsetup.md:45 — Netwrix.TypeVsEnter False positive. 'The credential type' uses 'type' as a noun (a category of credential), not as an instruction to type text into a field. Changing to 'enter' would break the sentence.
docs/pingcastle/4.0/enterpriseentrascan.md:118 — Netwrix.FirstPerson False positive. 'APIs my organization uses' is the literal UI menu label in the Entra admin center. Removing 'my' would misrepresent the actual UI string the user must click.
docs/pingcastle/4.0/enterpriseentrascan.md:134 — Netwrix.FirstPerson False positive. 'APIs my organization uses' is the literal UI menu label in the Entra admin center. Removing 'my' would misrepresent the actual UI string the user must click.
docs/pingcastle/4.0/enterprisesettings-entrascanner.md:13 — Netwrix.OxfordComma False positive. 'request and client timeouts' is a compound pair (request timeouts and client timeouts), not a third series item. The list already includes its Oxford comma before 'and circuit breaker thresholds'.
docs/pingcastle/4.0/enterprisetroubleshooting.md:177 — Netwrix.OxfordComma False positive. 'If Entra ID scanning isn't available, Enterprise and CloudAPI aren't integrated correctly' is a conditional clause with a two-item subject ('Enterprise and CloudAPI'), not a three-or-more-item series requiring an Oxford comma.
docs/pingcastle/4.0/enterpriseuser.md:9 — Dale: xy-slop 'The goal of the tool isn't perfection, but to provide reliable data' — rephrasing to positive form would drop the intended 'not perfection' nuance; low confidence the meaning is preserved. Same construction also in proinstall.md:8 and prouser.md:11.
docs/pingcastle/4.0/enterpriselicense.md:8 — Dale: passive-voice 'Domain Controllers aren't counted for licensing purposes, only domains' — active rewrites either reintroduce a negative-positive contrast or shift the emphasis; not confident meaning is preserved.
docs/pingcastle/4.0/enterprisepostinstall.md:337 — Dale: passive-voice 'The Sync button is shown if the sync link is configured AND if the user has permission' — sentence contains multiple stacked passives and a conditional; restructuring risks altering the conditions.
docs/pingcastle/4.0/enterprisepostinstall.md:314 — Dale: passive-voice Synchronization section describes system behavior with dense 'will be recomputed/forwarded' constructions; rewriting the interdependent clauses risks changing technical meaning.
docs/pingcastle/4.0/enterpriseuser.md:235 — Dale: undefined-acronyms 'CMMI methodology' used without expansion, but CMMI is an industry framework rather than a product-specific acronym; not confident the intended expansion is wanted.
docs/pingcastle/4.0/prouser.md:24 — Dale: passive-voice prouser.md and proinstall.md contain dense legacy translated prose with many passive/awkward constructions; isolated fixes would leave surrounding text inconsistent and risk altering meaning.

Ask @claude on this PR if you'd like an explanation of any fix.

…sages

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Auto-Fix Summary

109 issues fixed, 32 skipped across 39 files

Category Fixes
Removed filler 1
BoilerplateCrossRef (rewrite) 1
Dale: idioms 1
Dale: misplaced-modifiers 1
Dale: passive-voice 98
Dale: undefined-acronyms 3
Dale: wordiness 4
Skipped (needs manual review) Reason
docs/endpointprotector/admin/systempar.md:12 — Netwrix.OxfordComma False positive. The sentence already has the Oxford comma ('...their translations, and define custom notifications...'). The rule's regex '\w+,\s+\w+\s+and\b' matched the boundary between the first and second list items, not a missing comma.
docs/pingcastle/3.5/enterpriseinstall.md:2786 — Netwrix.Contractions Inside a PowerShell code block — the text is a Write-Host output string in a sample script. Prose contraction rules should not rewrite code.
docs/pingcastle/4.0/enterpriseemailsetup.md:45 — Netwrix.TypeVsEnter False positive. 'type' is a noun here ('The credential type the app registration uses'), not the verb 'type'. The rule's 'type the' substitution would produce nonsense.
docs/pingcastle/4.0/enterpriseentrascan.md:124 — Netwrix.FirstPerson 'my' appears in the literal Entra admin center UI label 'APIs my organization uses'. UI strings must be reproduced verbatim.
docs/pingcastle/4.0/enterpriseentrascan.md:142 — Netwrix.FirstPerson 'my' appears in the literal Entra admin center UI label 'APIs my organization uses'. UI strings must be reproduced verbatim.
docs/pingcastle/4.0/enterprisesettings-entrascanner.md:15 — Netwrix.OxfordComma False positive. 'request and client timeouts' is a single compound list item; the series already has its Oxford comma before 'and circuit breaker thresholds'.
docs/pingcastle/4.0/enterprisesettings-scim.md:28 — Netwrix.OxfordComma False positive. Not a series — 'revoke and regenerate' is a compound verb following a subordinate clause ('Because a compromised token stays valid indefinitely, ...').
docs/pingcastle/4.0/enterprisetroubleshooting.md:173 — Netwrix.OxfordComma False positive. Not a series — 'Enterprise and CloudAPI' is a compound subject following a conditional clause ('If Entra ID scanning isn't available, ...').
docs/pingcastle/4.0/enterpriseuser-dashboard.md:154 — Netwrix.OxfordComma False positive. The series already has its Oxford comma ('...expired or unused objects, and other legacy artifacts'). The regex matched within the compound item 'inactive user and computer accounts'.
docs/accessanalyzer/2601/install/install-commands.md:195 — Dale: passive-voice Inside an HTML-commented HIDDEN block that isn't published; editing draft-hidden content adds diff noise without reader benefit
docs/endpointprotector/admin/systempar.md:42 — Dale: minimizing-difficulty "With Endpoint Protector, you can create informative notifications" lacks a minimizing qualifier such as "easily", so the rule's pattern isn't actually triggered
docs/endpointprotector/admin/systempar.md:50 — Dale: wordiness "making it easier for users to understand" / "visually engaging notifications that capture user attention" is promotional but rewriting would cut substantive author content; needs a writer's judgment call
docs/endpointprotector/admin/systempar.md:229 — Dale: undefined-acronyms "EPP Client" appears only in table cells and the doc otherwise says "Endpoint Protector Client"; unclear whether to define EPP or normalize to the full product name, so a terminology decision is needed
docs/endpointprotector/admin/systempar.md:306 — Dale: passive-voice "is disabled by default" describes a product default state rather than a hidden actor; rewriting reads worse and the agent is genuinely the product's shipped configuration
docs/endpointprotector/admin/systempar.md:323 — Dale: wordiness "To enable and enforce the end-user to view User Remediation pop-up notifications" is ungrammatical and the intended meaning is ambiguous (enable for, or force?)
docs/pingcastle/4.0/enterpriseemailsetup.md:202 — Dale: passive-voice "This should be automatically configured, but verify it" has no identifiable actor — Exchange, Entra ID, or the mailbox creation wizard — so any active rewrite would assert a fact not in the source
docs/pingcastle/3.5/enterpriseinstall.md:2389 — Dale: passive-voice Same ambiguous-actor sentence as the 4.0 email setup page
docs/pingcastle/3.5/enterpriseinstall.md:1855 — Dale: passive-voice "Configuration options are documented here" also trips the Vale WeakLinkText rule; fixing the passive requires rewriting the link text, which the Vale autofix pass owns
docs/pingcastle/3.5/enterpriseinstall.md:3410 — Dale: passive-voice "# Emergency Procedures" is an H1 in the middle of the document (heading-level skip), which is a structural issue outside the Dale rule set
docs/pingcastle/4.0/enterpriseauthsetup.md:158 — Dale: passive-voice "Configuration options are documented here" overlaps the Vale WeakLinkText rule; left for the Vale pass to avoid conflicting rewrites of the same link
docs/pingcastle/4.0/enterprisesettings-scim.md:28 — Dale: passive-voice "if you suspect it has been exposed" has several equally valid active rewrites ("suspect exposure", "suspect someone has exposed it", "suspect it's compromised") with different security nuance
docs/pingcastle/4.0/enterpriseentrascan.md:78 — Dale: xy-slop "are application permissions, not delegated permissions" is positive-then-negative disambiguation of two real Entra permission types, not the negative-positive "x is not y, x is z" pattern the rule targets
docs/pingcastle/4.0/enterpriseuser.md:33 — Dale: passive-voice "if password-based authentication is enabled" has an ambiguous actor (administrator, installer, or settings screen); an active rewrite would name a specific actor the source doesn't
docs/pingcastle/4.0/enterpriseuser-dashboard.md:32 — Dale: wordiness "ensure all domains have an owner and that this owner is doing its job" is vague and uses "its" for a person; the intended meaning of "doing its job" is unclear
docs/pingcastle/4.0/enterpriseuser-dashboard.md:34 — Dale: wordiness "ensure all domains aren't connected to external companies" scopes the negation ambiguously (no domain is connected, vs. not all are); needs author clarification
docs/pingcastle/4.0/index.md:738 — Dale: idioms "in the hands of administrators" sits inside a verbatim blockquoted Netwrix security statement; quoted material shouldn't be reworded (same text at 3.5/index.md line 677)
docs/pingcastle/4.0/index.md:9 — Dale: undefined-acronyms CISO (and KPI elsewhere) are standard business terms rather than product-specific acronyms, so the rule's exclusion for well-known acronyms applies
docs/pingcastle/4.0/index.md:531 — Dale: passive-voice "Check if LAPS and/or BitLocker has been enabled" and similar table cells are terse scanner-description fragments echoing the tool's own help text; rewriting risks diverging from the product strings
docs/pingcastle/4.0/prouser.md:23 — Dale: passive-voice Escaped-quote artifacts (") and an unbalanced quote at line 174 are conversion damage, not a Dale rule violation; flagged for a separate cleanup
docs/pingcastle/4.0/proinstall.md:129 — Dale: wordiness "copy ClientID and TenantID and keep it with you" is awkward but the intent (record the values for later) is clear enough that a rewrite risks changing emphasis
docs/pingcastle/4.0/proinstall.md:586 — Dale: passive-voice "It then display the welcome screen" is a subject-verb agreement error, not a passive-voice or other Dale violation
docs/pingcastle/4.0/enterprisepostinstall.md:15 — Dale: passive-voice Escaped-quote artifacts ("Admin") are markdown conversion damage rather than a Dale rule violation

Ask @claude on this PR if you'd like an explanation of any fix.

Adds migration-verification-table image, new enterpriseschedulingmigration.md
guide, and upgrade doc note that prereqs (ASP.NET Hosting Bundle) install
automatically from the bundled installer without web access.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Auto-Fix Summary

8 issues fixed, 22 skipped across 40 files

Category Fixes
Dale: misplaced-modifiers 1
Dale: passive-voice 5
Dale: wordiness 2
Skipped (needs manual review) Reason
docs/endpointprotector/admin/systempar.md:12 — Netwrix.OxfordComma False positive. The series is already correctly punctuated: 'view and manage device types and notifications, view and enable default notifications and their translations, and define custom notifications...' The Oxford comma is present before 'and define'. The rule matched the coordinating 'and' inside the second item ('view and enable').
docs/pingcastle/3.5/enterpriseinstall.md:2786 — Netwrix.Contractions Inside a fenced PowerShell code block (fence opens at line 2497, closes at line 2826). The text is a Write-Host string literal in a sample script; changing it would alter code output rather than prose.
docs/pingcastle/4.0/enterpriseemailsetup.md:45 — Netwrix.TypeVsEnter False positive. 'type' is used as a noun ('The credential type the app registration uses'), not as the verb meaning to supply text. No instruction to the reader is involved.
docs/pingcastle/4.0/enterpriseentrascan.md:134 — Netwrix.FirstPerson 'my' appears inside the literal Microsoft Entra admin center UI label 'APIs my organization uses'. Procedures must cite exact UI strings; rewording would make the step inaccurate.
docs/pingcastle/4.0/enterpriseentrascan.md:152 — Netwrix.FirstPerson 'my' appears inside the literal Microsoft Entra admin center UI label 'APIs my organization uses'. Procedures must cite exact UI strings; rewording would make the step inaccurate.
docs/pingcastle/4.0/enterprisesettings-entrascanner.md:15 — Netwrix.OxfordComma False positive. The Oxford comma is present before the final item: 'Retry attempts, backoff delay, request and client timeouts, and circuit breaker thresholds'. The rule matched the 'and' inside the compound item 'request and client timeouts'.
docs/pingcastle/4.0/enterprisesettings-scim.md:28 — Netwrix.OxfordComma False positive. 'revoke and regenerate it immediately' is a two-verb compound predicate following a subordinate clause, not a series of three or more items. Adding a comma would be incorrect.
docs/pingcastle/4.0/enterprisetroubleshooting.md:177 — Netwrix.OxfordComma False positive. 'If Entra ID scanning isn't available, Enterprise and CloudAPI aren't integrated correctly.' is a conditional clause followed by a two-item compound subject, not a series of three or more items.
docs/pingcastle/4.0/enterpriseuser-dashboard.md:154 — Netwrix.OxfordComma False positive. The Oxford comma is present before the final item: 'inactive user and computer accounts, expired or unused objects, and other legacy artifacts'. The rule matched the 'or' inside the compound item 'expired or unused objects'.
docs/endpointprotector/admin/systempar.md:46 — Dale: wordiness The HTML notification paragraph ("making it easier for users to understand... This results in visually engaging notifications that capture user attention...") is wordy and promotional, but tightening it would require dropping claims the author may have intended to keep. Left for a human editor.
docs/endpointprotector/admin/systempar.md:229 — Dale: passive-voice The Events table uses "Logged when..." phrasing across many rows. These read as product event descriptions rather than prose, and rewriting the whole table risks diverging from the UI strings.
docs/endpointprotector/admin/systempar.md:241 — Dale: passive-voice "User Remediation dialog was closed by the user" appears to be a verbatim event description string from the product UI, not authored prose.
docs/endpointprotector/admin/systempar.md:150 — Dale: wordiness "To avoid eventual changes that interfere with the Endpoint Protector Client" is unclear; the intended meaning of "eventual" is ambiguous, so any rewrite could change the meaning.
docs/pingcastle/3.5/index.md:16 — Dale: passive-voice "The source code of the program is licensed to the Non-Profit Open Software License" is legal licensing text; rewording licensing statements is out of scope for a style fix.
docs/pingcastle/3.5/index.md:677 — Dale: idioms "in the hands of administrators" appears inside a quoted Netwrix security statement in a blockquote. Editing quoted material would misrepresent the source.
docs/pingcastle/4.0/index.md:531 — Dale: passive-voice Scanner table entries such as "Check if LAPS and/or BitLocker has been enabled" and "determine if patches have been applied" mirror the scanner descriptions emitted by the tool; rewriting them risks diverging from the product output.
docs/pingcastle/4.0/enterpriseemailsetup.md:202 — Dale: passive-voice "This should be automatically configured, but verify it" has no clear agent — it is unclear whether Microsoft 365, Exchange, or an earlier step performs the configuration, so an active rewrite would assert something unverified.
docs/pingcastle/4.0/enterpriseuser-dashboard.md:32 — Dale: wordiness "ensure all domains have an owner and that this owner is doing its job" is colloquial and uses "its" for a person, but the intended scope of the owner's responsibility is unclear, so a rewrite could change the meaning.
docs/pingcastle/4.0/proinstall.md:716 — Dale: wordiness "Indeed, you may have purchased a batch product which is looking for failure or dependencies" is unclear as written; the intended meaning can't be recovered confidently.
docs/pingcastle/4.0/proinstall.md:851 — Dale: wordiness "Indeed, by default you have a firewall preventing remote connection and that the database may not be exposed" has broken syntax; correcting it requires knowing which claim the author intended.
docs/pingcastle/3.5/enterpriseinstall.md:3055 — Dale: xy-slop "the web application doesn't execute PingCastle scans. Instead, remote systems must push their scan results..." uses a negative-then-positive shape, but here the negative statement carries the security rationale and removing it would lose information.
docs/pingcastle/3.5/enterpriseinstall.md:3091 — Dale: wordiness The "PingCastle Enterprise high trust / low trust" block appears to be truncated or corrupted source content rather than a style issue; it needs an author to supply the missing text.

Ask @claude on this PR if you'd like an explanation of any fix.

bturlea
bturlea previously approved these changes Aug 11, 2026
Comment thread sidebars/pingcastle/4.0.js
Comment thread docs/pingcastle/4.0/enterpriseauthsetup.md Outdated

@RichardHNetwrix RichardHNetwrix 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.

I think docs\pingcastle\CLAUDE.md needs updating. Right now it says "The current version is 3.5 (only one version exists)."

…10 API

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Auto-Fix Summary

35 issues fixed, 24 skipped across 40 files

Category Fixes
Dale: passive-voice 6
Dale: positional-references 1
Dale: undefined-acronyms 1
Dale: wordiness 27
Skipped (needs manual review) Reason
docs/endpointprotector/admin/systempar.md:12 — Netwrix.OxfordComma False positive. The series already has an Oxford comma: 'view and manage device types and notifications, view and enable default notifications and their translations, and define custom notifications...'. The flagged 'notifications, view and' spans two separate list items; adding a comma would be wrong.
docs/pingcastle/3.5/enterpriseinstall.md:2786 — Netwrix.Contractions Line is inside a fenced PowerShell code block (lines 2497-2826) — a Write-Host output string in a sample script. Editing script output text is out of scope and would alter the code sample.
docs/pingcastle/4.0/enterpriseemailsetup.md:45 — Netwrix.TypeVsEnter False positive. 'type' is a noun here ('The credential type the app registration uses'), not the verb 'type' instructing the user to supply text.
docs/pingcastle/4.0/enterpriseentrascan.md:134 — Netwrix.FirstPerson False positive. 'APIs my organization uses' is the literal UI tab label in the Entra admin center. Rewording would break the match with the product UI.
docs/pingcastle/4.0/enterpriseentrascan.md:152 — Netwrix.FirstPerson False positive. Same literal Entra admin center UI label, 'APIs my organization uses'.
docs/pingcastle/4.0/enterprisesettings-entrascanner.md:15 — Netwrix.OxfordComma False positive. 'request and client timeouts' is a single compound item (request timeouts and client timeouts), and the list already has an Oxford comma before 'and circuit breaker thresholds'.
docs/pingcastle/4.0/enterprisesettings-scim.md:28 — Netwrix.OxfordComma False positive. 'revoke and regenerate it' is a two-verb pair, not a series of three or more items. The preceding comma closes an introductory clause.
docs/pingcastle/4.0/enterprisetroubleshooting.md:177 — Netwrix.OxfordComma False positive. 'Enterprise and CloudAPI' is a two-item pair; the comma closes the conditional clause 'If Entra ID scanning isn't available,'.
docs/pingcastle/4.0/enterpriseuser-dashboard.md:154 — Netwrix.OxfordComma False positive. 'expired or unused objects' is a two-adjective pair modifying one item, and the surrounding series already has an Oxford comma before 'and other legacy artifacts'.
docs/pingcastle/4.0/index.md:17 — Dale: passive-voice License wording ('The source code of the program is licensed to the Non-Profit OSL 3.0') is legal boilerplate; rewriting risks changing legal meaning
docs/pingcastle/3.5/index.md:16 — Dale: passive-voice Same legal license boilerplate as the 4.0 guide
docs/pingcastle/4.0/index.md:729 — Dale: passive-voice Passive constructions appear inside the quoted Netwrix security statement blockquote; altering quoted text would misrepresent it
docs/pingcastle/4.0/index.md:745 — Dale: wordiness 'The list of components used by PingCastle, but not limited to, is:' is awkward, but every concise rewrite either duplicates the preceding sentence or changes the 'not limited to' hedge
docs/pingcastle/4.0/enterprisesettings-scim.md:28 — Dale: passive-voice 'if you suspect it has been exposed' has a genuinely unknown agent; an active rewrite would invent one
docs/pingcastle/4.0/enterpriseemailsetup.md:202 — Dale: passive-voice 'This should be automatically configured, but verify it' — the configuring agent (Exchange vs. the mailbox creation step) is ambiguous, so an active rewrite would assert something unverified
docs/pingcastle/3.5/enterpriseinstall.md:2389 — Dale: passive-voice Same ambiguous agent as the 4.0 email setup page
docs/pingcastle/4.0/enterprisesettings-dataretention.md:49 — Dale: passive-voice 'What gets archived:' is a list lead-in; rewrites either break the parallelism of the mixed-subject bullets that follow or read as a heading change
docs/pingcastle/4.0/enterpriseuser-import.md:16 — Dale: wordiness 'In case of a failure, hovering over the item displays the associated error message to help you upload the file' — the trailing purpose clause is vague, and any concise rewrite drops or reinterprets it
docs/pingcastle/4.0/prouser.md:182 — Dale: wordiness Same sentence and same ambiguity as the Enterprise import page
docs/endpointprotector/admin/systempar.md:241 — Dale: passive-voice 'User Remediation dialog was closed by the user' is an event-name table cell that mirrors product UI strings; rewording could break the match with the product
docs/endpointprotector/admin/systempar.md:156 — Dale: undefined-acronyms MTP appears only inside the UI feature name 'Advanced Printer and MTP Scanning'; expanding it would no longer match the product label
docs/endpointprotector/admin/systempar.md:229 — Dale: undefined-acronyms EPP appears only in table cells describing logged events, not in body prose
docs/accessanalyzer/2601/install/install-commands.md:195 — Dale: passive-voice Sentence sits inside a commented-out HIDDEN block, so it isn't published content
docs/pingcastle/4.0/proinstall.md:851 — Dale: wordiness 'Indeed, by default you have a firewall preventing remote connection and that the database may not be exposed' is garbled enough that any rewrite would guess at the intended meaning

Ask @claude on this PR if you'd like an explanation of any fix.

@github-actions

Copy link
Copy Markdown
Contributor

Documentation PR Review

Editorial Review

This PR adds a full PingCastle 4.0 doc set (36 new files) plus voice/clarity edits to four existing files. Most of the new content is well structured and the cross-reference graph checks out — every relative link and anchor I spot-checked resolves. The findings below concentrate on cross-file contradictions introduced by the new 4.0 set, plus a few structural and completeness gaps.


Cross-cutting issues (affect several new 4.0 files)

  • Completeness — Contradictory restart behavior for Settings changes. enterpriseauthsetup.md:16 states that six settings — "the three file logging settings, maximum concurrent scans, and both SCIM rate limit settings" — "require you to restart PingCastle Enterprise manually after saving." But enterprisesettings-logging.md:10 says "Changes to these settings take effect within about 30 seconds, without a restart," enterprisesettings-scanningscheduling.md:10 says the same (and lists Max concurrent scans), and enterprisesettings-scim.md:6 says a restart is scheduled "automatically." A reader who lands on the Logging page will change a setting and wonder why it didn't apply. Suggested fix: state the restart rule once (an admonition on enterprisesettings.md), then on each affected page flag only the specific fields that need a manual restart — e.g. on the Logging page: "Changing File logging enabled, Log file path, or Log file size limit (MB) requires a manual restart of PingCastle Enterprise."

  • Structure — The restart note in enterpriseauthsetup.md:16 is on the Authentication page but describes settings on the Logging, Scanning and Scheduling, and Provisioning pages. Readers of those pages never see it. Suggested fix: move the global restart explanation to enterprisesettings.md and link to it from each settings page.

  • Clarity — Six new files carry French auto-generated image alt text: Une image contenant texte Description générée automatiquement (enterpriseuser-entities.md:50,54,88,94, enterpriseuser-dashboard.md:108,126, enterpriseuser.md:51,55,61,65, and similar in proupgrade.md, prouser.md, proinstall.md). This is meaningless to screen-reader users and to anyone whose image fails to load. Many other new images use empty alt text (![](/images/...)). Suggested fix: replace with descriptive alt text, following the pattern already used well elsewhere in this PR — e.g. enterprisescheduling.md:9 ("A screenshot of the Scheduled scans overview page, listing scan jobs with their type, target, next run time, and last status.").

  • Structure — Four new files open with an ## heading that just restates the # title: enterpriseinstall.md (# Installing PingCastle Enterprise## Installation), enterpriseauthsetup.md (→ ## Authentication), enterpriseemailsetup.md (→ ## Email), enterprisetroubleshooting.md:6 (→ ## Troubleshooting). These appear to exist only to give other pages an anchor to link to. Suggested fix: drop the redundant ## heading and point the incoming links at the file instead ([Authentication](enterpriseauthsetup.md) rather than [Authentication](enterpriseauthsetup.md#authentication)).


docs/pingcastle/4.0/index.md

  • Completeness — Line 81 and line 89 state "PingCastle runs on any system that supports .NET 8" and "PingCastle is a standalone executable that runs on .NET 8," but enterpriserequirements.md:22 states "The PingCastle.exe scanner targets .NET 10.0 (net10.0-windows)." Same product, same version, two different runtimes. An admin sizing a scan host gets the wrong answer from one of these pages. Suggested fix: correct the runtime in index.md to match the actual 4.0 scanner target, and update the surrounding "Client Side" section (lines 76-84), which still frames everything around the 3.5 / .NET 8 transition.
  • Completeness — Line 281-282: the [Example] links on ad_hc_summary_full_node_map.html and ad_hc_summary_simple_node_map.html were dropped while the equivalent link on ad_hc_summary.html (line 280) was kept and improved. The reader now has a live sample for one of three output files with no explanation of why. Suggested fix: restore the two links in the same "See an [example ...]" form, e.g. "See an example full node map."
  • Clarity — Line 34 reads "PingCastle for Service Providers" while docs/pingcastle/3.5/index.md:33 reads "PingCastle For Service Providers." Two spellings of one product name across versions. Suggested fix: pick one (lowercase "for" is correct for a preposition inside a product name) and apply it to both files.

docs/pingcastle/4.0/enterpriserequirements.md

  • Clarity — Line 34 lists internal NuGet package names and patch versions: "Entity Framework Core 10.0.8 (the Microsoft.EntityFrameworkCore.SqlServer, Relational, Design, Tools, and InMemory packages) ... with the Npgsql provider at version 10.0.2." None of this is actionable for an IT administrator provisioning a database, and it goes stale with every patch release. Suggested fix: "PingCastle Enterprise uses Entity Framework Core for database operations. It provides partial support for PostgreSQL on a best-effort basis and doesn't specifically support other database engines."
  • Structure — Line 6 opens with a bold pseudo-heading, **System Specifications**, while the rest of the page uses real ## headings (## Database, ## External System Dependencies, ## Logon Providers). The first section is therefore missing from the page's table of contents and can't be linked to. Suggested fix: change to ## System specifications.

docs/pingcastle/4.0/enterpriseinstall.md

  • Completeness — Line 209, in the SQL Authentication tab, the sample connection string combines SQL credentials with Trusted_Connection=True: Server=tcp:server.fqdn.com;Database=PingCastle;User Id=pingcastle;Password=pingcastle;Trusted_Connection=True;MultipleActiveResultSets=true. Trusted_Connection=True selects Windows integrated authentication and causes SQL Server to ignore User Id and Password, so a reader who copies this string from the SQL Authentication tab gets a Windows-auth connection and a confusing failure. Suggested fix: drop Trusted_Connection=True from the SQL Authentication example. (The same string appears at proinstall.md:452.)
  • Clarity — Line 219: "Installation doesn't create the database schema. Any connection issues will appear on first run." This sits alongside enterprisepostinstall.md:8 ("When the application first runs, it creates the database"), and the installer wizard step at line 100 says the installer "creates the database and grants permissions automatically." Three statements about who creates what. Suggested fix: distinguish database from schema explicitly — the installer creates the database; the application creates the schema on first run.

docs/pingcastle/4.0/enterprisepostinstall.md

  • Clarity — Line 8: "When the application first runs, it creates the database." Per enterpriseinstall.md, the installer creates the database and the application creates the schema. Suggested fix: "When the application first runs, it creates the database schema."

docs/pingcastle/4.0/enterpriseupgrade.md

  • Completeness — The guide covers the installer, configuration migration, and post-upgrade verification, but never mentions that 4.0 replaces Task Scheduler-based scanning and that existing scheduled scans must be migrated. enterpriseschedulingmigration.md documents exactly this for the 3.5.1 → 4.0 path — the same path this guide covers — but nothing links to it. An admin who follows this guide end to end will finish with scans that no longer run as expected. Suggested fix: add a step after line 42: "Migrate your scheduled scans. Version 4.0 replaces Task Scheduler-based scanning with PingCastleSchedulerService. See Migrating scheduled scans from PingCastle Enterprise 3.5.1."
  • Structure — Line 42, step 3, describes what the installer does rather than an action the reader takes, inside a numbered procedure where steps 1 and 2 are reader actions. Suggested fix: fold it into step 2 as trailing explanatory text, or reword as an outcome ("Confirm the installer detects the existing 3.5.1 installation and proceeds with an in-place upgrade").

docs/pingcastle/4.0/enterprisearchitecture.md

  • Structure — Lines 69 and 108 both use the heading text "PingCastle Enterprise Server" (as #### under Key Components and ##### under Network Ports). Duplicate heading text produces duplicate anchor slugs, so one becomes #pingcastle-enterprise-server-1 and any link to it is fragile. Suggested fix: rename the ports subsection to "Enterprise server ports."
  • Structure — "Network Ports" (line 106) is nested as a #### under "Key Components" (line 67), but a port table isn't a component. Suggested fix: promote it to ### Network ports, as a sibling of Key Components.

docs/pingcastle/4.0/enterpriseauthsetup.md

  • Completeness — Line 126: "The key is off by default and has no toggle on the Settings screens — enable it by adding it to the application configuration." The reader is told to edit "the application configuration" without being told which file, where it lives, or what the key/value syntax is — and enterprisesettings.md:44 says 4.0 moved configuration into the database, which makes "the application configuration" genuinely ambiguous. Suggested fix: name the file and show the entry, e.g. "add \"RemoveUserIfNotInWindowsGroupAnymore\": true to appsettings.Production.json in the installation directory, then restart PingCastle Enterprise," and link to Editing the appsettings.Production.json File.

docs/pingcastle/4.0/enterprisesettings.md

  • Completeness — Line 44 states that 4.0 stores configuration settings in the database "instead" of appsettings.Production.json, but enterpriseinstall.md:219 tells readers to edit that file for the connection string and enterprisetroubleshooting.md devotes a whole section to editing it. The reader is left unsure whether the file still matters. Suggested fix: qualify the scope — "PingCastle Enterprise stores these settings in the database instead. appsettings.Production.json remains in the installation directory and still holds the database connection string and other bootstrap settings."
  • Structure — In the System list (lines 36-40), Database is described inline in a long paragraph while every other entry is a one-line label plus link. Suggested fix: give Database its own short page (matching the other settings screens) or trim the inline description to one sentence.

docs/pingcastle/4.0/enterprisesettings-scim.md

  • Completeness — Line 28 tells the reader to "revoke and regenerate" a token if it's exposed, but the page never explains how to revoke one, and the SCIM tokens table visible in the screenshot at line 18 is never described. The reader is given a security instruction they can't act on. Suggested fix: add a short "Revoking a token" procedure after line 28 covering the tokens table and the revoke action.

docs/pingcastle/4.0/enterpriseagentdeployment.md

  • Clarity — Lines 43 and 53 use --Level Full while the rest of the page (lines 20, 26) and every other 4.0 page use --level Full. Command-line flags read as case-sensitive, so the inconsistency invites a failed copy-paste. Suggested fix: use --level Full in both commands.
  • Structure — Headings on this page mix cases: "Program version," "Scheduling," "Command line," "Common issues" (sentence case) against "Automatic Forest Exploration Setup," "Manual Execution," "Automated Execution for Agent Setup," "Parameters" (title case). Suggested fix: use sentence case throughout — "Automatic forest exploration setup," "Manual execution," "Automated execution for agent setup."

docs/pingcastle/4.0/enterpriseuser-dashboard.md

  • Clarity — Line 42: "A star indicates whether a single rule linked to a measure is raising an alert." "Indicates whether" leaves the reader unsure which state the star represents — earned or failed. Suggested fix: "You earn the star for a measure when no rule linked to that measure is raising an alert."
  • Clarity — Line 34: "External Trusts - ensure all domains aren't connected to external companies." The scope of the negation is ambiguous ("not all domains are connected" vs "no domain is connected"). Suggested fix: "External Trusts — ensure no domain is connected to an external company."

docs/pingcastle/4.0/enterpriseuser-account.md

  • Clarity — Lines 31-32 gate two features to "Internal users only," but this page never defines an internal user, and the term appears nowhere else in the 4.0 set except an unexplained "external user account" mention in enterpriseauthsetup.md. Suggested fix: define it on first use — "Internal users only (accounts that authenticate with a PingCastle Enterprise username and password, rather than through Windows Authentication, OIDC, or SAML2)."

docs/pingcastle/4.0/enterprisesynchronization.md

  • Structure — Line 124 opens with a bare Note: paragraph, where the rest of the 4.0 set uses :::note admonitions. Suggested fix: wrap it — :::note / "An inner exception may contain the error details, as the following screenshot shows..." / :::.

docs/pingcastle/4.0/proinstall.md

  • Completeness — Line 53, in the PingCastle Pro requirements: "PingCastle Enterprise uses the 'asp.net core 8.0 framework' but still relies on 'dotnet standard 2.0'." This is the wrong product for this page, and it contradicts enterpriserequirements.md:40, which requires the ASP.NET 10.0 Hosting Bundle for 4.0 Enterprise. Line 418 has the same problem ("PingCastleEnterprise doesn't support password rotation" in a Pro procedure). Suggested fix: state the Pro requirement on the Pro page and remove the Enterprise references, or move the Enterprise sentence to enterpriserequirements.md with the correct version.
  • Completeness — Line 45 says Netwrix may support "any database that Entity Framework Core 2 supports," while enterpriserequirements.md:34 says Enterprise 4.0 uses Entity Framework Core 10. If Pro genuinely still runs on EF Core 2, saying so explicitly would help; if not, this is stale. Suggested fix: state the Pro framework version explicitly, or drop the version number.
  • Structure — Line 806: ![](/images/pingcastle/proinstall/image62.webp)Solution: — an image and the following body text share one line with no blank line between them, so "Solution:" renders inline after the image instead of as its own paragraph. Suggested fix: split into two lines with a blank line between, and give the image alt text.
  • Clarity — Product and technology names are inconsistently cased throughout the added content: "asp.net core" (lines 53, 60, 67), "PostGres" (lines 44, 137, 155), "smtp" (lines 306-309), "dotnet framework 2.0" (line 50). Suggested fix: ASP.NET Core, PostgreSQL, SMTP, .NET Framework 2.0.

docs/pingcastle/4.0/prouser.md

  • Completeness — Lines 41-43 list the frameworks as "asp.net core 3.1," "bootstrap 4," "jQuery 3," while proinstall.md:53 in the same 4.0 set says asp.net core 8.0. One of the two is wrong for the version this doc set ships under. Suggested fix: verify the actual Pro framework version and use it in both files (and apply the capitalization fix above).

docs/pingcastle/4.0/proupgrade.md

  • Completeness — The upgrade-path table (lines 29-33) stops at "3.2 to 3.x | Upgrade ASP.NET from 6.0 to 8.0," with no row for upgrading to the version this doc set documents. A reader on the 4.0 Pro upgrade page can't find their own upgrade path. Suggested fix: add the row for the current target version, or state explicitly that Pro has no 4.0 release and this guide covers 3.x upgrades only.

docs/endpointprotector/admin/systempar.md

  • Structure — Line 382: the continuation of the nested list item lost its indentation (one leading space where the sibling at line 383 uses four, and the parent item's continuation at line 379 uses three). Suggested fix: indent to match — will automatically switch back to the username of the logged-in user.
  • Clarity — Line 381 introduces "EPP Notifier" without expansion, and the surrounding steps call the same thing "the Endpoint Protector notifier" (line 366). Suggested fix: use "Endpoint Protector Notifier" consistently, or expand on first use.
  • Clarity — Line 109 was corrected to "Custom Device Control User Remediation Notifications" (plain fi), but the file's other headings and body text still carry the ligature — "Notifications" (lines 10, 18, 33), "justification" (lines 375-376), "specific" (line 251). The heading is now inconsistent with its own page, and ligature characters break in-page search. Suggested fix: replace with fi throughout the file in a follow-up pass.

docs/pingcastle/3.5/index.md

  • Completeness — Lines 236-237: same as the 4.0 file — the [Example] links for the full and simple node maps were removed while the one on line 235 was kept. Suggested fix: restore both, matching the "See an [example ...]" form used on line 235.

docs/accessanalyzer/2601/install/install-commands.md — No issues found. (The retargeted anchor quickinstall.md#step-4-run-the-installer resolves correctly, and Step 4 is indeed where the bind password is supplied.)

docs/pingcastle/3.5/enterpriseinstall.md — No issues found. The edits are consistent voice and clarity improvements.

docs/pingcastle/4.0/enterpriseauditlog.md — No issues found.

docs/pingcastle/4.0/enterprisedecryptionkeys.md — No issues found. The round trip with index.md#report-encryption is clear and the public/private key roles are stated correctly.

docs/pingcastle/4.0/enterpriseemailsetup.md — No issues found beyond the cross-cutting restart contradiction noted above.

docs/pingcastle/4.0/enterpriseentrascan.md — No issues found. The permissions reference is thorough and the SharePoint certificate-only constraint is well flagged in both the setup section and the permissions section.

docs/pingcastle/4.0/enterprisehttpssetup.md — No issues found.

docs/pingcastle/4.0/enterpriselicense.md — No issues found.

docs/pingcastle/4.0/enterprisescheduling.md — No issues found beyond the cross-cutting restart contradiction noted above.

docs/pingcastle/4.0/enterpriseschedulingmigration.md — No issues found.

docs/pingcastle/4.0/enterprisesettings-actionplans.md — No issues found.

docs/pingcastle/4.0/enterprisesettings-application.md — No issues found.

docs/pingcastle/4.0/enterprisesettings-dataretention.md — No issues found.

docs/pingcastle/4.0/enterprisesettings-entrascanner.md — No issues found.

docs/pingcastle/4.0/enterprisesettings-logging.md — No issues found beyond the cross-cutting restart contradiction noted above.

docs/pingcastle/4.0/enterprisesettings-scanningscheduling.md — No issues found beyond the cross-cutting restart contradiction noted above.

docs/pingcastle/4.0/enterprisesettings-security.md — No issues found. The threshold and reset-interval explanations, with the worked example, are a good model for the other settings pages.

docs/pingcastle/4.0/enterprisetroubleshooting.md — No issues found beyond the duplicate-heading pattern noted above.

docs/pingcastle/4.0/enterpriseuser.md — No issues found beyond the alt-text issue noted above.

docs/pingcastle/4.0/enterpriseuser-entities.md — No issues found beyond the alt-text issue noted above.

docs/pingcastle/4.0/enterpriseuser-import.md — No issues found.

docs/pingcastle/4.0/enterpriseuser-infrastructure.md — No issues found.

Summary

29 editorial suggestions across 21 files (4 of them cross-cutting across the new 4.0 set); 19 files reviewed clean. The highest-impact items are the .NET version contradiction between 4.0/index.md and 4.0/enterpriserequirements.md, the conflicting restart guidance across the Settings pages, the missing scheduler-migration step in the 4.0 upgrade guide, and the SQL Authentication connection string that includes Trusted_Connection=True. Vale and Dale issues are auto-fixed separately.


What to do next:

Comment @claude on this PR followed by your instructions to get help:

  • @claude fix all issues — fix all editorial issues
  • @claude help improve the flow of this document — get writing assistance
  • @claude explain the voice issues — understand why something was flagged

You can ask Claude anything about the review or about Netwrix writing standards.

Automated fixes are only available for branches in this repository, not forks.

@github-actions

Copy link
Copy Markdown
Contributor

Auto-Fix Summary

29 issues fixed, 26 skipped across 40 files

Category Fixes
Dale: misplaced-modifiers 2
Dale: passive-voice 16
Dale: positional-references 1
Dale: wordiness 10
Skipped (needs manual review) Reason
docs/endpointprotector/admin/systempar.md:12 — Netwrix.OxfordComma False positive. The series already carries its Oxford comma: 'view and manage device types and notifications, view and enable default notifications and their translations, and define custom notifications'. The flagged 'notifications, view and' spans the boundary between item one and item two, where the 'and' joins the verb pair 'view and enable' inside item two. Adding a comma would break the sentence.
docs/pingcastle/3.5/enterpriseinstall.md:2786 — Netwrix.Contractions Line falls inside a fenced ```powershell block (lines 2497-2826). The text is a Write-Host console string emitted by the sample script; rewriting 'does not' to 'doesn't' would alter code a reader may copy and run. Prose contraction rules do not apply to code samples.
docs/pingcastle/4.0/enterpriseemailsetup.md:45 — Netwrix.TypeVsEnter False positive. 'type' is a noun, not an input verb: 'The credential type the app registration uses: a client secret or a certificate.' There is no instruction to supply text, so 'Enter the' does not fit.
docs/pingcastle/4.0/enterpriseentrascan.md:134 — Netwrix.FirstPerson 'my' belongs to the literal Entra admin center UI label 'APIs my organization uses', rendered in bold as a UI string. Rewording would stop the label matching what the reader sees on screen and break the procedure.
docs/pingcastle/4.0/enterpriseentrascan.md:152 — Netwrix.FirstPerson Same literal Entra admin center UI label 'APIs my organization uses' as line 134. Accuracy of the UI string outweighs the first-person rule.
docs/pingcastle/4.0/enterprisesettings-entrascanner.md:15 — Netwrix.OxfordComma False positive. The series is already correctly punctuated: 'Retry attempts, backoff delay, request and client timeouts, and circuit breaker thresholds'. The flagged 'delay, request and' straddles a list boundary where 'request and client timeouts' is a single item with a shared head noun.
docs/pingcastle/4.0/enterprisesettings-scim.md:28 — Netwrix.OxfordComma Not a series. The comma ends the subordinate clause 'Because a compromised token stays valid indefinitely', and 'revoke and regenerate' is a two-verb pair, which takes no Oxford comma.
docs/pingcastle/4.0/enterprisetroubleshooting.md:177 — Netwrix.OxfordComma Not a series. The comma closes the conditional clause "If Entra ID scanning isn't available", and 'Enterprise and CloudAPI' is a compound subject of two items.
docs/pingcastle/4.0/enterpriseuser-dashboard.md:154 — Netwrix.OxfordComma False positive. The series already has its Oxford comma: 'inactive user and computer accounts, expired or unused objects, and other legacy artifacts'. The flagged 'accounts, expired or' crosses a list boundary where 'expired or unused objects' is one item.
docs/endpointprotector/admin/systempar.md:229 — Dale: passive-voice Event-description table cells use the elliptical 'Logged when ...' convention throughout the table; rewriting only the new rows would break consistency with the surrounding product-derived event descriptions
docs/endpointprotector/admin/systempar.md:203 — Dale: passive-voice Event Name/Description table entries such as 'File written to device' and 'File encrypted using EasyLock' mirror product UI strings; rewording could desync the docs from the product
docs/endpointprotector/admin/systempar.md:51 — Dale: wordiness 'This results in visually engaging notifications that capture user attention...' is marketing-toned and wordy, but any tightening would drop claims the author may have intended
docs/endpointprotector/admin/systempar.md:323 — Dale: wordiness 'To enable and enforce the end-user to view User Remediation pop-up notifications' is ungrammatical; the intended meaning is ambiguous, so a rewrite risks changing it
docs/pingcastle/4.0/enterpriseemailsetup.md:202 — Dale: passive-voice 'This should be automatically configured, but verify it' — the actor (Exchange Online vs. Entra ID) isn't stated anywhere nearby, so an active rewrite would assert a fact not in the source
docs/pingcastle/3.5/enterpriseinstall.md:2389 — Dale: passive-voice Same as the 4.0 email setup page: the actor for 'This should be automatically configured' isn't determinable from context
docs/pingcastle/4.0/index.md:729 — Dale: passive-voice 'can also be misused by attackers' and 'No malicious payloads ... are present' sit inside the quoted Netwrix Security Statement blockquote; editing a verbatim quotation isn't appropriate
docs/pingcastle/3.5/index.md:668 — Dale: passive-voice Same quoted Netwrix Security Statement blockquote as in the 4.0 guide
docs/pingcastle/4.0/index.md:17 — Dale: passive-voice 'The source code of the program is licensed to the Non-Profit Open Software License 3.0' is licensing language; rewording could alter its legal sense
docs/pingcastle/4.0/index.md:531 — Dale: passive-voice Scanner table descriptions ('Check if LAPS and/or BitLocker has been enabled', 'must be run from inside the domain') mirror the tool's own CLI help text
docs/pingcastle/4.0/enterprisedecryptionkeys.md:6 — Dale: passive-voice 'so reports aren't exposed in plain text in transit or in email' — the natural active rewrites ('so no one can read reports...') overstate the guarantee
docs/pingcastle/4.0/enterprisesettings-scim.md:28 — Dale: passive-voice 'if you suspect it has been exposed' — an active rewrite would have to invent an actor, and the point is that the exposure route is unknown
docs/pingcastle/4.0/proinstall.md:854 — Dale: passive-voice '(in the following case, remote access is forbidden because TCP/IP is disabled)' sits in a paragraph whose surrounding grammar is already broken; a targeted passive fix would leave the passage no clearer
docs/pingcastle/4.0/proinstall.md:608 — Dale: wordiness 'You can configure PingCastle program to send their report to the program' has an unclear referent for 'the program'; can't rewrite without knowing which component is meant
docs/pingcastle/4.0/enterpriseauthsetup.md:11 — Dale: misplaced-modifiers '..., allowing users to choose their preferred login method' reads as an absolute construction attached to the whole clause rather than a true dangling modifier
docs/pingcastle/4.0/enterpriseuser-dashboard.md:32 — Dale: wordiness 'ensure all domains have an owner and that this owner is doing its job' is awkward and uses the wrong pronoun for a person, but no Dale rule covers pronoun agreement
docs/accessanalyzer/2601/install/install-commands.md:195 — Dale: passive-voice 'Terminal progress output isn't affected' sits inside an HTML comment block marked HIDDEN, so it isn't published content

Ask @claude on this PR if you'd like an explanation of any fix.

@github-actions

Copy link
Copy Markdown
Contributor

Code Review

Scope: correctness, security, and build/routing impact only — docs content and style are handled by the other workflows.

High

1. PingCastle Pro docs are orphaned in 4.0 — sidebars/pingcastle/4.0.js

sidebars/pingcastle/3.5.js is a single {type: 'autogenerated', dirName: '.'}, so every file in the version folder lands in the sidebar. The new 4.0.js is hand-written and enumerates each doc — but proinstall, proupgrade, and prouser exist in docs/pingcastle/4.0/ and are not listed in it. No other 4.0 page links to them either (checked every relative link in the folder).

Because this PR also sets isLatest: true / defaultVersion: '4.0' (src/config/products.js:436), 4.0 is what /docs/pingcastle/ redirects to and what the evergreen aliases resolve against. Net effect: all PingCastle Pro documentation becomes unreachable from navigation on the default version. The routes still build, so nothing fails loudly — Docusaurus just logs a "docs pages without sidebar" warning.

Either add a Pro category to the 4.0 sidebar, or drop the three files if 4.0 intentionally has no Pro tier.

Medium

2. DOCS_PRODUCT=kb now silently builds an empty site — src/config/products.js:802

getActiveProducts() returns [] for kb, and generateDocusaurusPlugins() skips the KB plugin when targetProduct === 'kb' (products.js:983). Result: zero docs plugins, empty navbar, empty homepage, build succeeds.

The guard this replaced in docusaurus.config.js threw for any value not matching a product id, kb included, so that path was previously unreachable. The new docstring says it throws "instead of silently building an empty site" — kb is the one input that does exactly that. Either make it a real KB-only build (return [] but keep the KB plugin) or drop the special case so it throws like everything else.

3. Update-MgApplication -KeyCredentials wipes existing certificates — static/files/pingcastle/Setup-EntraScannerApp.ps1:196

Update-MgApplication -ApplicationId $app.Id -KeyCredentials @($keyCredential) is a replace, not an append. The script documents -UseExisting for reusing an existing app registration, so the common rerun path silently removes every certificate already registered on that app — including the one a live scanner is authenticating with. Read $app.KeyCredentials and append.

4. The script is not idempotent despite advertising -UseExisting

With $ErrorActionPreference = 'Stop', a second run fails at:

  • New-ServicePrincipal -AppId ... -ObjectId ... (line 221) — the Exchange service principal already exists.
  • New-MgDirectoryRoleMemberByRef (line 255) — already a member of Global Reader. No existence check, unlike Grant-AppRoleIfMissing.

Worse, the Add-RoleGroupMember retry loop (lines 223-237) catches all exceptions, so "already a member" is indistinguishable from the replication delay it is retrying for — a rerun spins for 10 × 15 s before rethrowing.

Low

5. Lookup misses produce opaque failures — Setup-EntraScannerApp.ps1

$appRole.Id (208-209), $exchangeAppRole (215), $sharePointAppRole (245), and $globalReaderRole.Id (254) are all used without null checks. Get-MgDirectoryRole -Filter "displayName eq 'Global Reader'" returns nothing when the role has not been activated from its template in the tenant, which is common — the user gets a null-parameter error instead of a message telling them to activate the role.

6. OData filter injection — Setup-EntraScannerApp.ps1:144

Get-MgApplication -Filter "displayName eq '$DisplayName'" interpolates a mandatory user-supplied parameter straight into an OData filter. A DisplayName containing an apostrophe produces a malformed filter, and a crafted one can change which app is matched — which then gets its key credentials rewritten (see #3). Escape by doubling single quotes.

7. generateProductCategories throws if only its second argument is supplied — src/config/products.js:1036

activeVersionsByProduct[product.id] is undefined for any product not in the map, and the next line calls .includes on it. Safe today because both arguments come from the same customFields object and the activeIds filter runs first, but a ?? product.versions.map(v => v.version) fallback costs nothing.

8. Category generation moved into the render body — src/components/HomepageFeatures/index.js:98

generateProductCategories() used to run once at module scope; it now walks all 27 products and their versions on every render, and the product cards hold useState. Wrap it in useMemo.

9. Derived KB version filter ignores the product it was handed — scripts/copy-kb-to-versions.mjs:578

When COPY_KB_PRODUCTS names a product other than DOCS_PRODUCT and DOCS_PRODUCT_LATEST_ONLY=true, getActiveVersions() short-circuits on product.id !== getTargetProductId() (products.js:817) and returns every version, so the latest-only scoping quietly does not apply. Harmless — it just copies more — but the intent does not hold.

10. docs/pingcastle/CLAUDE.md is stale on arrival

Its file table documents only the 3.5/ layout and its sidebar_position values, while this PR adds a 4.0 tree with 30+ files and an explicit hand-written sidebar where sidebar_position is irrelevant.

11. Worth a second look: Sites.FullControl.All

The script grants tenant-wide SharePoint full control (line 245) to a scanner whose other grants are all *.Read.All / Reader. If PingCastle genuinely needs it, fine — but it is a broad grant applied by a script users download and run, so it deserves an explicit call-out rather than sitting quietly in a permissions table.

Checked and clean

  • Every relative .md link and #anchor in docs/pingcastle/4.0/ resolves to an existing file and heading (onBrokenMarkdownLinks and onBrokenAnchors are both throw).
  • Every referenced /images/pingcastle/... asset exists, including the new enterpriseauditlog, enterpriseentrascan, enterprisescheduling, enterpriselicense, and enterprisesettings-* directories.
  • Tabs/TabItem are imported in all five files that use them; <Tabs> and <details> open/close counts balance; the one bare angle-bracket placeholder token sits inside a fenced code block.
  • /files/pingcastle/Setup-EntraScannerApp.ps1 exists at static/files/pingcastle/.
  • The two new docs/kb/pingcastle/0-images/*.png files fix previously-broken references in scheduler-or-agent-deployment-returns-401-unauthorized-error.md.
  • The node -e gate around gen-api-docs in package.json is safe: no "type": "module", so require works, and build-and-deploy.yml runs npm run ci without DOCS_PRODUCT, so API docs still generate in CI.
  • No workflow files changed, so triggers, permissions, and secret usage are untouched.

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.

KB review: PingCastle 4.0 documentation (PR #1270)

5 participants