From 744b5d04d708cb84ad39d1918962695c74293be4 Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sat, 31 Jan 2026 23:50:33 +0100 Subject: [PATCH 01/28] removed duplicate PR md template --- .../pull_request_template.md | 49 ------------------- 1 file changed, 49 deletions(-) delete mode 100644 .github/PULL_REQUEST_TEMPLATE/pull_request_template.md diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md deleted file mode 100644 index af279bc5..00000000 --- a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +++ /dev/null @@ -1,49 +0,0 @@ -# Summary - -Provide a short summary of the changes. - -## Motivation - -Why is this change needed? What problem does it solve? - -## Type of Change - -Please select the relevant option: - -- [ ] Bug fix -- [ ] New feature -- [ ] Breaking change -- [ ] Documentation update -- [ ] Refactoring / internal improvement - -## Changes - -- -- -- - -## Testing - -Describe how this change was tested. - -- [ ] Unit tests -- [ ] Contract tests -- [ ] Manual testing - -### How to test & review - -If helpful, provide additional information how to test. - -## Checklist - -- [ ] Code follows STYLEGUIDE.md -- [ ] Tests added or updated -- [ ] Documentation updated -- [ ] No UI/auth logic added to IdLE.Core -- [ ] No breaking changes without discussion - -## Related Issues - -Link related issues here (if any). - -Closes #... From 663a7f71d2390d3ea4d59c45f250881a1df2b490 Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 00:05:28 +0100 Subject: [PATCH 02/28] adding providers reference index --- docs/reference/providers/index.md | 48 +++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 docs/reference/providers/index.md diff --git a/docs/reference/providers/index.md b/docs/reference/providers/index.md new file mode 100644 index 00000000..577afbbc --- /dev/null +++ b/docs/reference/providers/index.md @@ -0,0 +1,48 @@ +--- +title: Providers Reference +sidebar_label: Providers +--- + +# Provider Reference + +> Entry page for provider reference. This section is **reference-only**: what a provider implements, how to configure it, and which contracts/capabilities it exposes. + +--- + +## Built-in / first-party providers + +- **Active Directory (AD)** — Identity operations against on-prem AD via the AD provider module. → `./provider-ad.md` +- **Entra ID** — Identity operations against Microsoft Entra ID via Microsoft Graph. → `./provider-entraID.md` +- **Exchange Online** — Messaging / mailbox related operations against Exchange Online. → `./provider-ExchangeOnline.md` +- **DirectorySync.EntraConnect** — Directory synchronization provider for Entra Connect / sync-cycle related operations. → `./provider-directorysync-EntraConnect.md` +- **Mock** — In-memory / file-backed provider for tests and local development without live systems. → `./provider-mock.md` + +--- + +## Choosing a provider + +- Match the **capabilities required by your steps** to the provider’s `GetCapabilities()` output. +- Providers handle authentication/session acquisition via `Context.AcquireAuthSession(...)` (host-controlled). +- In workflows, steps select a provider by **alias** (defaults to `Identity` if omitted). + +Related: + +- [Capabilities Reference](../capabilities.md) +- [Provider fundamentals (concept)](../../about/concepts.md#providers) +- [Use Providers](../../use/providers.md) + +--- + +## Authoring a provider (for developers) + +- Minimal checklist: + - Implement provider contracts (only what you need) + - Advertise deterministic capabilities (`GetCapabilities()`) + - Acquire sessions via host context (no prompts inside providers) + - Add unit tests + contract tests (no live calls in CI) + +Related: + +- [Extensibility](../../extend/extensibility.md) +- Testing: `../advanced/testing.md` +- [Security considerations](../../about/security.md) From d0c2343e1641291b48fad5a6b8b428d5f97d78d6 Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 00:15:47 +0100 Subject: [PATCH 03/28] adding provider index --- website/sidebars.js | 1 + 1 file changed, 1 insertion(+) diff --git a/website/sidebars.js b/website/sidebars.js index 53bfe6e2..30743e7d 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -76,6 +76,7 @@ const sidebars = { }, 'reference/steps', 'reference/capabilities', + 'reference/providers/index', { type: 'category', label: 'Providers', From eb013ef1a602e970d34cf58df804dca19173de6b Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 00:15:55 +0100 Subject: [PATCH 04/28] adding provider reference template --- .../providers/_provider-name_template.md | 191 ++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 docs/reference/providers/_provider-name_template.md diff --git a/docs/reference/providers/_provider-name_template.md b/docs/reference/providers/_provider-name_template.md new file mode 100644 index 00000000..57def241 --- /dev/null +++ b/docs/reference/providers/_provider-name_template.md @@ -0,0 +1,191 @@ +# Provider Reference Template + +> **Purpose:** This page is a **reference** for a specific provider implementation. +> Keep it factual and contract-oriented. Put conceptual explanations elsewhere and link to them. + +--- + +## Summary + +- **Provider name:** `` +- **Module:** `` (e.g. `IdLE.Provider.*`) +- **Provider kind:** `` +- **Targets:** `` +- **Status:** `` +- **Since:** `` (optional) +- **Compatibility:** PowerShell 7+ (IdLE requirement) + +--- + +## What this provider does + +- **Primary responsibilities:** + - `` + - `` +- **Out of scope / non-goals:** + - `` + - `` + +--- + +## Contracts and capabilities + +### Contracts implemented + +List the IdLE provider contracts this provider implements and what they mean at a glance. + +| Contract | Used by steps for | Notes | +| --- | --- | --- | +| `` | `` | `` | +| `` | `` | `` | + +> Keep the contract list stable and link to the canonical contract reference. + +### Capability advertisement (`GetCapabilities()`) + +- **Implements `GetCapabilities()`**: `` +- **Capabilities returned (stable identifiers):** + - `` + - `` + - `` + +--- + +## Authentication and session acquisition + +> Providers must not prompt for auth. Use the host-provided broker contract. + +- **Auth session name(s) requested via `Context.AcquireAuthSession(...)`:** + - `` +- **Session options (data-only):** + - ``: `` — `` (optional default: `<...>`) + +:::warn + +**Security notes** + +- Do not pass secrets in provider options. +- Ensure token/credential objects are not emitted in events. + +::: + +--- + +## Configuration + +### Provider constructor / factory + +How to create an instance. + +- **Public constructor cmdlet(s):** + - `` — `` + +**Parameters (high signal only)** + +- `-Name ` — `<...>` +- `-Options ` — `<...>` + +> Do not copy full comment-based help here. Link to the cmdlet reference. + +### Provider bag / alias usage + +How to pass the provider instance to IdLE as part of the host's provider map. + +```powershell +$providers = @{ + = +} +``` + +- **Recommended alias pattern:** `` +- **Default alias expected by built-in steps (if any):** `` (if applicable) + +--- + +## Provider-specific options reference + +> Document only **data-only** keys. Keep this list short and unambiguous. + +| Option key | Type | Required | Default | Description | +| --- | --- | --- | --- | --- | +| `` | `` | `` | `<...>` | `<...>` | +| `` | `` | `` | `<...>` | `<...>` | + +--- + +## Operational behavior + +### Idempotency and consistency + +- **Idempotent operations:** `` +- **Consistency model:** `` +- **Concurrency notes:** `` + +### Error mapping and retry behavior + +- **Common error categories:** `` +- **Retry strategy:** `` + +--- + +## Observability + +- **Events emitted by provider (if any):** + - `` — `` — `` +- **Sensitive data redaction:** `` + +--- + +## Examples + +### Minimal host usage + +```powershell +# 1) Create provider instance +$provider = + +# 2) Build provider map +$providers = @{ = $provider } + +# 3) Plan + execute +$plan = New-IdlePlan -WorkflowPath -Request -Providers $providers +$result = Invoke-IdlePlan -Plan $plan -Providers $providers +``` + +### Example workflow snippet + +```powershell +@{ + Steps = @( + @{ + Name = '' + Type = '' + With = @{ + Provider = '' + # ... + } + } + ) +} +``` + +--- + +## Limitations and known issues + +- `` +- `` + +--- + +## Testing + +- **Unit tests:** `` +- **Contract tests:** `` +- **Known CI constraints:** `` + +--- + +## Changelog (optional) + +- `` — `` From 038a36c3971559a44e1f0fe12333a87af209e1c4 Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 00:27:48 +0100 Subject: [PATCH 05/28] added links to reference intro --- docs/reference/intro.md | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/docs/reference/intro.md b/docs/reference/intro.md index 4f19a58e..2655ed46 100644 --- a/docs/reference/intro.md +++ b/docs/reference/intro.md @@ -6,15 +6,8 @@ sidebar_label: Reference This section is the **authoritative reference** for IdLE. It contains precise, stable and normative information intended for lookup and verification. -Content here is not tutorial-style and usually assumes prior knowledge from the **Use** or -**Extend** sections. - -## What you will find here - -- Cmdlet reference -- Step reference -- Capability reference -- Specifications (schemas, formats, contracts) +Content here is not tutorial-style and usually assumes prior knowledge from the **[Use](../use/intro.md)** or +**[Extend](../extend/intro.md)** sections. ## How to use this section @@ -22,6 +15,11 @@ Content here is not tutorial-style and usually assumes prior knowledge from the - Verify assumptions during development or review - Link from guides and concepts to authoritative definitions -## Not the right section? +## What you will find here -If you are looking for guidance or explanations, start with [Use](../use/intro.md) or [Extend](../extend/intro.md) instead. +- [Cmdlet reference](./cmdlets.md) +- [Step reference](./steps.md) +- [Providers](./providers.md) +- [Capability reference](capabilities.md) +- Specifications (schemas, formats, contracts) + - [Plan Export JSON Schema](./specs/plan-export.md) From ea513e5f0228539f4d0ae8a1c8869718cb2a9d50 Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 00:28:02 +0100 Subject: [PATCH 06/28] improving reference order and link names --- website/sidebars.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/sidebars.js b/website/sidebars.js index 30743e7d..52eda437 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -63,7 +63,7 @@ const sidebars = { 'reference/cmdlets', { type: 'category', - label: 'Cmdlets', + label: 'Cmdlet Reference', collapsed: true, items: [ 'reference/cmdlets/Export-IdlePlan', @@ -76,10 +76,10 @@ const sidebars = { }, 'reference/steps', 'reference/capabilities', - 'reference/providers/index', + 'reference/providers', { type: 'category', - label: 'Providers', + label: 'Provider Reference', collapsed: true, items: [ 'reference/providers/provider-ad', From 96b7f5802e3f401d8810d02d2a99d7e2c1df4462 Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 00:28:47 +0100 Subject: [PATCH 07/28] updated package-lock.json --- website/package-lock.json | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/website/package-lock.json b/website/package-lock.json index 721dbe1b..d1d58d06 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -271,6 +271,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.6.tgz", "integrity": "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==", "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/generator": "^7.28.6", @@ -2117,6 +2118,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=18" }, @@ -2139,6 +2141,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=18" } @@ -2248,6 +2251,7 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "license": "MIT", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -2669,6 +2673,7 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "license": "MIT", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -3672,6 +3677,7 @@ "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.9.2.tgz", "integrity": "sha512-C5wZsGuKTY8jEYsqdxhhFOe1ZDjH0uIYJ9T/jebHwkyxqnr4wW0jTkB72OMqNjsoQRcb0JN3PcSeTwFlVgzCZg==", "license": "MIT", + "peer": true, "dependencies": { "@docusaurus/core": "3.9.2", "@docusaurus/logger": "3.9.2", @@ -3900,6 +3906,7 @@ "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.9.2.tgz", "integrity": "sha512-IGUsArG5hhekXd7RDb11v94ycpJpFdJPkLnt10fFQWOVxAtq5/D7hT6lzc2fhyQKaaCE62qVajOMKL7OiAFAIA==", "license": "MIT", + "peer": true, "dependencies": { "@docusaurus/core": "3.9.2", "@docusaurus/logger": "3.9.2", @@ -3940,6 +3947,7 @@ "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.9.2.tgz", "integrity": "sha512-6c4DAbR6n6nPbnZhY2V3tzpnKnGL+6aOsLvFL26VRqhlczli9eWG0VDUNoCQEPnGwDMhPS42UhSAnz5pThm5Ag==", "license": "MIT", + "peer": true, "dependencies": { "@docusaurus/mdx-loader": "3.9.2", "@docusaurus/module-type-aliases": "3.9.2", @@ -4852,6 +4860,7 @@ "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz", "integrity": "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==", "license": "MIT", + "peer": true, "dependencies": { "@types/mdx": "^2.0.0" }, @@ -5595,6 +5604,7 @@ "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", "license": "MIT", + "peer": true, "dependencies": { "@babel/core": "^7.21.3", "@svgr/babel-preset": "8.1.0", @@ -6226,6 +6236,7 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.10.tgz", "integrity": "sha512-WPigyYuGhgZ/cTPRXB2EwUw+XvsRA3GqHlsP4qteqrnnjDrApbS7MxcGr/hke5iUoeB7E/gQtrs9I37zAJ0Vjw==", "license": "MIT", + "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -6574,6 +6585,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -6641,6 +6653,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -6686,6 +6699,7 @@ "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.47.0.tgz", "integrity": "sha512-AGtz2U7zOV4DlsuYV84tLp2tBbA7RPtLA44jbVH4TTpDcc1dIWmULjHSsunlhscbzDydnjuFlNhflR3nV4VJaQ==", "license": "MIT", + "peer": true, "dependencies": { "@algolia/abtesting": "1.13.0", "@algolia/client-abtesting": "5.47.0", @@ -7162,6 +7176,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -8180,6 +8195,7 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "license": "MIT", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -8499,6 +8515,7 @@ "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.33.1.tgz", "integrity": "sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10" } @@ -8920,6 +8937,7 @@ "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", "license": "ISC", + "peer": true, "engines": { "node": ">=12" } @@ -10126,6 +10144,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -14733,6 +14752,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -15343,6 +15363,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -16246,6 +16267,7 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "license": "MIT", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -17062,6 +17084,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -17071,6 +17094,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -17126,6 +17150,7 @@ "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", "license": "MIT", + "peer": true, "dependencies": { "@types/react": "*" }, @@ -17154,6 +17179,7 @@ "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", "license": "MIT", + "peer": true, "dependencies": { "@babel/runtime": "^7.12.13", "history": "^4.9.0", @@ -18968,7 +18994,8 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" + "license": "0BSD", + "peer": true }, "node_modules/tsyringe": { "version": "4.10.0", @@ -19391,6 +19418,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -19651,6 +19679,7 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.104.1.tgz", "integrity": "sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==", "license": "MIT", + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", From 422500284022dbea0050d00411f19c65669b6723 Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 00:29:13 +0100 Subject: [PATCH 08/28] added providers index --- docs/reference/{providers/index.md => providers.md} | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) rename docs/reference/{providers/index.md => providers.md} (64%) diff --git a/docs/reference/providers/index.md b/docs/reference/providers.md similarity index 64% rename from docs/reference/providers/index.md rename to docs/reference/providers.md index 577afbbc..0509883c 100644 --- a/docs/reference/providers/index.md +++ b/docs/reference/providers.md @@ -11,11 +11,11 @@ sidebar_label: Providers ## Built-in / first-party providers -- **Active Directory (AD)** — Identity operations against on-prem AD via the AD provider module. → `./provider-ad.md` -- **Entra ID** — Identity operations against Microsoft Entra ID via Microsoft Graph. → `./provider-entraID.md` -- **Exchange Online** — Messaging / mailbox related operations against Exchange Online. → `./provider-ExchangeOnline.md` -- **DirectorySync.EntraConnect** — Directory synchronization provider for Entra Connect / sync-cycle related operations. → `./provider-directorysync-EntraConnect.md` -- **Mock** — In-memory / file-backed provider for tests and local development without live systems. → `./provider-mock.md` +- **[Active Directory (AD)](providers/provider-ad.md)** — Identity operations against on-prem AD via the AD provider module +- **[Entra ID](providers/provider-entraID.md)** — Identity operations against Microsoft Entra ID via Microsoft Graph +- **[Exchange Online](providers/provider-exchangeonline.md)** — Messaging / mailbox related operations against Exchange Online +- **[DirectorySync.EntraConnect](providers/provider-directorysync-EntraConnect.md)** — Directory synchronization provider for Entra Connect / sync-cycle related operations +- **[Mock Provider](providers/provider-mock.md)** — In-memory / file-backed provider for tests and local development without live systems --- From 5bc90ed1b0cc7bffb4a52d4148c60508972e43de Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 00:29:33 +0100 Subject: [PATCH 09/28] changed cmdlets title --- docs/reference/cmdlets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/cmdlets.md b/docs/reference/cmdlets.md index 96558f22..54c2435c 100644 --- a/docs/reference/cmdlets.md +++ b/docs/reference/cmdlets.md @@ -1,4 +1,4 @@ -# Cmdlet Reference +# Cmdlets > Generated file. Do not edit by hand. > Source: tools/Generate-IdleCmdletReference.ps1 From d4b51a1ef3f88918d955720fb6ff599ab2678f5a Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 00:38:20 +0100 Subject: [PATCH 10/28] neue provider index seite verlinkt --- docs/index.md | 20 ++++++++------------ docs/use/providers.md | 7 +------ src/IdLE.Provider.AD/README.md | 1 + src/IdLE.Provider.EntraID/README.md | 1 + 4 files changed, 11 insertions(+), 18 deletions(-) diff --git a/docs/index.md b/docs/index.md index 7dfbb5b9..a0427157 100644 --- a/docs/index.md +++ b/docs/index.md @@ -40,18 +40,10 @@ Learn how to [extend IdLE](extend/intro.md) as a developer. The [authoritative reference](reference/intro.md) for IdLE components. -- [Cmdlets](reference/cmdlets.md) - Public cmdlets and usage -- [Step Catalog](reference/steps.md) - Built-in step reference (generated) -- [Capabilities](reference/capabilities.md) - The capabilities catalog - -## Workflow Examples - -- [Workflow Examples](../examples/README.md) - Runnable examples and demo workflows - -### Provider Reference - -- [Active Directory Provider](reference/providers/provider-ad.md) -- [Entra ID Provider](reference/providers/provider-entraID.md) +- [Cmdlet Reference](reference/cmdlets.md) +- [Provider Reference](reference/providers.md) +- [Step Reference](reference/steps.md) +- [Capabilities](reference/capabilities.md) ### Specifications @@ -60,6 +52,10 @@ used between IdLE and its hosts. - [Plan export (JSON)](reference/specs/plan-export.md) - The JSON specification of the Plan export file +### Workflow Examples + +- [Workflow Examples](../examples/README.md) - Runnable examples and demo workflows + --- ## Developer Documentation diff --git a/docs/use/providers.md b/docs/use/providers.md index f7b3ffa3..f368ea56 100644 --- a/docs/use/providers.md +++ b/docs/use/providers.md @@ -144,11 +144,6 @@ With = @{ :::info -Please see the detailed Provider Reference documentation for authentication help. +Please see the detailed [Provider Reference](../reference/providers.md) documentation for authentication help. ::: - -## Provider Reference - -### [Active Directory Provider](../reference/providers/provider-ad.md) -### [Entra ID Provider](../reference/providers/provider-entraID.md) diff --git a/src/IdLE.Provider.AD/README.md b/src/IdLE.Provider.AD/README.md index a18f0f7a..1b19c6d5 100644 --- a/src/IdLE.Provider.AD/README.md +++ b/src/IdLE.Provider.AD/README.md @@ -24,6 +24,7 @@ $plan = New-IdlePlan -WorkflowPath '.\joiner.psd1' -Request $request -Providers ## Documentation See **[Complete Provider Documentation](../../docs/reference/providers/provider-ad.md)** for: + - Full usage guide and examples - Capabilities and built-in steps - Identity resolution and idempotency diff --git a/src/IdLE.Provider.EntraID/README.md b/src/IdLE.Provider.EntraID/README.md index 58f5173c..96eb61c2 100644 --- a/src/IdLE.Provider.EntraID/README.md +++ b/src/IdLE.Provider.EntraID/README.md @@ -35,6 +35,7 @@ $plan = New-IdlePlan -WorkflowPath '.\joiner.psd1' -Request $request -Providers ## Documentation See **[Complete Provider Documentation](../../docs/reference/providers/provider-entraID.md)** for: + - Full usage guide and examples - Capabilities and built-in steps - Authentication patterns (delegated + app-only) From 9d3ce545ffb30582b20753994d1788c3ef94fcea Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 00:40:48 +0100 Subject: [PATCH 11/28] fixed md title linting --- docs/reference/providers.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/reference/providers.md b/docs/reference/providers.md index 0509883c..5916fc83 100644 --- a/docs/reference/providers.md +++ b/docs/reference/providers.md @@ -3,8 +3,6 @@ title: Providers Reference sidebar_label: Providers --- -# Provider Reference - > Entry page for provider reference. This section is **reference-only**: what a provider implements, how to configure it, and which contracts/capabilities it exposes. --- From d9572a54a8fcba8f115c51971a5b3e28117e14a4 Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 13:03:08 +0100 Subject: [PATCH 12/28] updated step generator to step type index page + single pages --- tools/Generate-IdleStepReference.ps1 | 342 ++++++++++++++++++++++----- 1 file changed, 286 insertions(+), 56 deletions(-) diff --git a/tools/Generate-IdleStepReference.ps1 b/tools/Generate-IdleStepReference.ps1 index 0ba5a304..319aa9b7 100644 --- a/tools/Generate-IdleStepReference.ps1 +++ b/tools/Generate-IdleStepReference.ps1 @@ -5,11 +5,18 @@ param( [ValidateNotNullOrEmpty()] [string] $ModuleManifestPath, - # Markdown output path (will be created/overwritten). + # Markdown output path for the generated index page (will be created/overwritten). + # Example: ./docs/reference/steps.md [Parameter()] [ValidateNotNullOrEmpty()] [string] $OutputPath, + # Output directory for generated per-step-type pages. + # If omitted, it is derived from OutputPath: "/steps". + [Parameter()] + [ValidateNotNullOrEmpty()] + [string] $DetailOutputDirectory, + # Restrict which step modules are scanned. [Parameter()] [ValidateNotNullOrEmpty()] @@ -17,34 +24,53 @@ param( # Optional: Step function names to exclude (exact command names). [Parameter()] - [string[]] $ExcludeCommands = @() + [string[]] $ExcludeCommands = @(), + + # If specified, remove previously generated per-step-type pages that no longer exist. + # Safety: only deletes files that contain the generator marker string. + [Parameter()] + [switch] $CleanObsoleteDetailPages ) <# .SYNOPSIS -Generates Markdown reference documentation for IdLE steps. +Generates Markdown reference documentation for IdLE step types. .DESCRIPTION -This script imports the IdLE module from the current repository clone and generates a Markdown -"Step Catalog" based on functions following the naming convention: Invoke-IdleStep. +This script imports the IdLE modules from the current repository clone and generates: + +- An index page at -OutputPath (default: ./docs/reference/steps.md) +- One page per step type in -DetailOutputDirectory (default: ./docs/reference/steps/) + +Step types are discovered from functions following the naming convention: +Invoke-IdleStep. The generator uses comment-based help (Get-Help) as the primary source and adds a small amount of heuristic extraction from the step source file (e.g., required With.* keys when they are defined in a simple static pattern). Important: -- Do not edit the generated file by hand. Update step help/source and regenerate. +- Do not edit generated files by hand. Update step help/source and regenerate. +- Per-step-type filenames are slugified from the StepType (kebab-case) and do not include an "idle" prefix. + Example: "EnsureAttribute" -> "step-ensure-attribute.md" MDX compatibility: - Step help text may contain angle tokens like which MDX can interpret as JSX. - Step help text may contain braces like @{ ... } or {Name} which MDX can interpret as expressions. - This generator sanitizes help-derived text to be MDX-safe. +Markdown linting: +- Many linters require a blank line before lists. The generator ensures there is an empty line before + markdown list items like "- ", "* ", "+ ", or "1. ". + .PARAMETER ModuleManifestPath Path to the IdLE module manifest (IdLE.psd1). Defaults to ./src/IdLE/IdLE.psd1 relative to this script. .PARAMETER OutputPath -Path to the generated Markdown file. Defaults to ./docs/reference/steps.md relative to this script. +Path to the generated Markdown index page. Defaults to ./docs/reference/steps.md relative to this script. + +.PARAMETER DetailOutputDirectory +Directory for generated per-step-type pages. Defaults to "/steps". .PARAMETER StepModules Modules that contain step functions (IdLE.Steps.*). @@ -52,6 +78,9 @@ Modules that contain step functions (IdLE.Steps.*). .PARAMETER ExcludeCommands Specific step function names to exclude (exact command names). +.PARAMETER CleanObsoleteDetailPages +If specified, delete previously generated detail pages that are no longer produced. + .EXAMPLE pwsh ./tools/Generate-IdleStepReference.ps1 @@ -62,6 +91,8 @@ System.String Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' +$script:GeneratorMarker = 'Source: tools/Generate-IdleStepReference.ps1' + function Resolve-IdleRepoPath { [CmdletBinding()] param( @@ -85,6 +116,38 @@ function ConvertTo-IdleMarkdownSafeText { return $normalized.Trim() } +function Ensure-IdleBlankLineBeforeMarkdownLists { + [CmdletBinding()] + param( + [Parameter(Mandatory)] + [AllowEmptyString()] + [string] $Text + ) + + # Many markdown linters require a blank line before lists. + # + # Turn: + # Authentication: + # - item + # Into: + # Authentication: + # + # - item + # + # Also applies to: "* ", "+ ", and numbered lists "1. ". + $t = $Text -replace "`r`n", "`n" -replace "`r", "`n" + + # Insert an extra newline when a non-empty line is followed by a list item line. + # We only insert if there is not already an empty line. + $t = [regex]::Replace( + $t, + '(?m)(?<=\S)\n(?=(?:- |\* |\+ |\d+\. ))', + "`n`n" + ) + + return $t +} + function ConvertTo-IdleMdxSafeText { [CmdletBinding()] param( @@ -99,8 +162,7 @@ function ConvertTo-IdleMdxSafeText { # # 1) Replace simple angle tokens () that MDX might interpret as JSX. # 2) Escape braces so MDX does not treat them as expressions. - # - # Backslashes will not show up in rendered Markdown; they merely escape characters. + # 3) Ensure blank line before markdown lists for linting. $t = $Text -replace "`r`n", "`n" -replace "`r", "`n" @@ -108,10 +170,11 @@ function ConvertTo-IdleMdxSafeText { $t = $t -replace '<(?[A-Za-z][A-Za-z0-9_-]*)>', '<${tok}>' # Escape braces to avoid MDX expression parsing, e.g. @{ ... } or {Name}. - # We escape single braces as well as any brace characters in the text. $t = $t -replace '\{', '\{' $t = $t -replace '\}', '\}' + $t = Ensure-IdleBlankLineBeforeMarkdownLists -Text $t + return $t.Trim() } @@ -168,7 +231,12 @@ function Get-IdleRequiredWithKeysFromSource { $content = Get-Content -Path $filePath -Raw -ErrorAction Stop - $m = [regex]::Match($content, 'foreach\s*\(\s*\$key\s+in\s+@\((?[^)]*)\)\s*\)', 'IgnoreCase') + $m = [regex]::Match( + $content, + 'foreach\s*\(\s*\$key\s+in\s+@\((?[^)]*)\)\s*\)', + 'IgnoreCase' + ) + if (-not $m.Success) { return @() } @@ -189,7 +257,12 @@ function Get-IdleProviderMethodHintFromDescription { # Best-effort extraction: # "must implement an EnsureAttribute method" -> EnsureAttribute - $m = [regex]::Match($DescriptionText, 'must\s+implement\s+an?\s+(?[A-Za-z0-9_]+)\s+method', 'IgnoreCase') + $m = [regex]::Match( + $DescriptionText, + 'must\s+implement\s+an?\s+(?[A-Za-z0-9_]+)\s+method', + 'IgnoreCase' + ) + if (-not $m.Success) { return $null } @@ -197,7 +270,62 @@ function Get-IdleProviderMethodHintFromDescription { return $m.Groups['Method'].Value } -function ConvertTo-IdleStepMarkdownSection { +function ConvertTo-IdleKebabCase { + [CmdletBinding()] + param( + [Parameter(Mandatory)] + [ValidateNotNullOrEmpty()] + [string] $Text + ) + + # Robust kebab-case conversion (prevents per-letter splitting). + # + # 1) Split acronym-to-word boundaries: "EntraID" -> "Entra-ID" + # (?<=[A-Z])(?=[A-Z][a-z]) + # 2) Split lower-to-upper boundaries: "CreateIdentity" -> "Create-Identity" + # (?<=[a-z0-9])(?=[A-Z]) + $t = $Text + + $t = [regex]::Replace($t, '(?<=[A-Z])(?=[A-Z][a-z])', '-') + $t = [regex]::Replace($t, '(?<=[a-z0-9])(?=[A-Z])', '-') + + # Normalize common separators to hyphen + $t = $t -replace '[\._\s]+', '-' + + # Collapse duplicates and lowercase + $t = $t -replace '-{2,}', '-' + $t = $t.Trim('-').ToLowerInvariant() + + return $t +} + +function ConvertTo-IdleStepSlug { + [CmdletBinding()] + param( + [Parameter(Mandatory)] + [ValidateNotNullOrEmpty()] + [string] $StepType + ) + + $slug = ConvertTo-IdleKebabCase -Text $StepType + + # Remove optional IdLE-related prefixes (user-facing file names should not include "idle"). + $slug = $slug -replace '^idle-step-', '' + $slug = $slug -replace '^idle-', '' + + # Ensure the file name remains self-explanatory. + if (-not $slug.StartsWith('step-')) { + $slug = "step-$slug" + } + + if ([string]::IsNullOrWhiteSpace($slug)) { + throw "Failed to derive a slug for step type: '$StepType'." + } + + return $slug +} + +function New-IdleStepDocModel { [CmdletBinding()] param( [Parameter(Mandatory)] @@ -241,43 +369,134 @@ function ConvertTo-IdleStepMarkdownSection { $providerMethod = Get-IdleProviderMethodHintFromDescription -DescriptionText $description $contracts = if ($providerMethod) { "Provider must implement method: $providerMethod" } else { 'Unknown' } + $slug = ConvertTo-IdleStepSlug -StepType $stepType + + return [pscustomobject]@{ + StepType = $stepType + Slug = $slug + CommandName = $commandName + Synopsis = $synopsis + Description = $description + RequiredWithKeys = $requiredWithKeys + Idempotent = $idempotent + Contracts = $contracts + } +} + +function New-IdleStepDetailPageContent { + [CmdletBinding()] + param( + [Parameter(Mandatory)] + [ValidateNotNull()] + [pscustomobject] $Model + ) + $sb = New-Object System.Text.StringBuilder - [void]$sb.AppendLine("## $stepType") + [void]$sb.AppendLine("# $($Model.StepType)") [void]$sb.AppendLine() - [void]$sb.AppendLine(("- **Step Name**: ``{0}``" -f $stepType)) - [void]$sb.AppendLine(("- **Implementation**: ``{0}``" -f $commandName)) - [void]$sb.AppendLine(("- **Idempotent**: ``{0}``" -f $idempotent)) - [void]$sb.AppendLine(("- **Contracts**: ``{0}``" -f $contracts)) + [void]$sb.AppendLine('> Generated file. Do not edit by hand.') + [void]$sb.AppendLine("> $script:GeneratorMarker") + [void]$sb.AppendLine() + + [void]$sb.AppendLine('## Summary') + [void]$sb.AppendLine() + [void]$sb.AppendLine(("- **Step Type**: ``{0}``" -f $Model.StepType)) + [void]$sb.AppendLine(("- **Implementation**: ``{0}``" -f $Model.CommandName)) + [void]$sb.AppendLine(("- **Idempotent**: ``{0}``" -f $Model.Idempotent)) + [void]$sb.AppendLine(("- **Contracts**: ``{0}``" -f $Model.Contracts)) [void]$sb.AppendLine(("- **Events**: Unknown")) [void]$sb.AppendLine() - [void]$sb.AppendLine("**Synopsis**") + + [void]$sb.AppendLine('## Synopsis') [void]$sb.AppendLine() - [void]$sb.AppendLine($synopsis) + [void]$sb.AppendLine($Model.Synopsis.Trim()) [void]$sb.AppendLine() - if (-not [string]::IsNullOrWhiteSpace($description)) { - [void]$sb.AppendLine("**Description**") + if (-not [string]::IsNullOrWhiteSpace($Model.Description)) { + [void]$sb.AppendLine('## Description') [void]$sb.AppendLine() - [void]$sb.AppendLine($description) + [void]$sb.AppendLine($Model.Description.Trim()) [void]$sb.AppendLine() } - [void]$sb.AppendLine("**Inputs (With.\*)**") + [void]$sb.AppendLine('## Inputs (With.*)') [void]$sb.AppendLine() - if ($requiredWithKeys.Count -eq 0) { + if ($Model.RequiredWithKeys.Count -eq 0) { [void]$sb.AppendLine('_Unknown (not detected automatically). Document required With.* keys in the step help and/or use a supported pattern._') + [void]$sb.AppendLine() } else { [void]$sb.AppendLine('| Key | Required |') [void]$sb.AppendLine('| --- | --- |') - foreach ($k in $requiredWithKeys) { + foreach ($k in $Model.RequiredWithKeys) { [void]$sb.AppendLine("| $k | Yes |") } + [void]$sb.AppendLine() } - return $sb.ToString() + # Normalize output: ensure exactly one LF at EOF. + return ($sb.ToString().TrimEnd()) + "`n" +} + +function New-IdleStepsIndexPageContent { + [CmdletBinding()] + param( + [Parameter(Mandatory)] + [ValidateNotNull()] + [pscustomobject[]] $Models + ) + + $sb = New-Object System.Text.StringBuilder + + [void]$sb.AppendLine('# Steps') + [void]$sb.AppendLine() + [void]$sb.AppendLine('> Generated file. Do not edit by hand.') + [void]$sb.AppendLine("> $script:GeneratorMarker") + [void]$sb.AppendLine() + [void]$sb.AppendLine('| Step Type | Synopsis |') + [void]$sb.AppendLine('| --- | --- |') + + foreach ($m in ($Models | Sort-Object -Property StepType)) { + # Keep synopsis a single line in the table. + $syn = ($m.Synopsis -replace '\s+', ' ').Trim() + [void]$sb.AppendLine(('| [{0}](steps/{1}.md) | {2} |' -f $m.StepType, $m.Slug, $syn)) + } + + return ($sb.ToString().TrimEnd()) + "`n" +} + +function Remove-IdleObsoleteGeneratedPages { + [CmdletBinding()] + param( + [Parameter(Mandatory)] + [ValidateNotNullOrEmpty()] + [string] $Directory, + + [Parameter(Mandatory)] + [ValidateNotNull()] + [string[]] $KeepFileNames + ) + + if (-not (Test-Path -Path $Directory)) { + return + } + + $keep = @{} + foreach ($k in $KeepFileNames) { $keep[$k] = $true } + + Get-ChildItem -Path $Directory -Filter '*.md' -File -ErrorAction SilentlyContinue | ForEach-Object { + if ($keep.ContainsKey($_.Name)) { + return + } + + # Safety: only delete if it is clearly generated by this script. + $text = Get-Content -Path $_.FullName -Raw -ErrorAction SilentlyContinue + if ($null -ne $text -and $text -like "*$script:GeneratorMarker*") { + Remove-Item -Path $_.FullName -Force -ErrorAction Stop + } + } } # Resolve defaults relative to this script. @@ -292,14 +511,23 @@ if (-not $PSBoundParameters.ContainsKey('OutputPath')) { $ModuleManifestPath = Resolve-IdleRepoPath -Path $ModuleManifestPath -# Ensure output directory exists. +# Ensure output directories exist. $outDir = Split-Path -Path $OutputPath -Parent if (-not (Test-Path -Path $outDir)) { New-Item -Path $outDir -ItemType Directory -Force | Out-Null } +if (-not $PSBoundParameters.ContainsKey('DetailOutputDirectory') -or [string]::IsNullOrWhiteSpace($DetailOutputDirectory)) { + $DetailOutputDirectory = Join-Path -Path $outDir -ChildPath 'steps' +} + +if (-not (Test-Path -Path $DetailOutputDirectory)) { + New-Item -Path $DetailOutputDirectory -ItemType Directory -Force | Out-Null +} + # Import IdLE from working tree. Remove-Module -Name 'IdLE*' -Force -ErrorAction SilentlyContinue +Import-Module -Name $ModuleManifestPath -Force -ErrorAction Stop # Ensure step modules are loaded (Import-Module by name does NOT load nested step modules automatically). foreach ($m in $StepModules) { @@ -347,36 +575,38 @@ if (-not $stepCommands) { throw "No step commands found. Ensure step modules are included in -StepModules (currently: $($StepModules -join ', '))." } -$header = @( - '# Step Catalog' - '' - '> Generated file. Do not edit by hand.' - "> Source: tools/Generate-IdleStepReference.ps1" - '' - 'This page documents built-in IdLE steps discovered from `Invoke-IdleStep*` functions in `IdLE.Steps.*` modules.' - '' - '---' - '' -) -join "`n" - -$body = New-Object System.Text.StringBuilder -[void]$body.AppendLine($header) - -foreach ($cmd in ($stepCommands | Sort-Object)) { - $section = ConvertTo-IdleStepMarkdownSection -CommandInfo $cmd - if (-not [string]::IsNullOrWhiteSpace($section)) { - [void]$body.AppendLine($section) - [void]$body.AppendLine('---') - [void]$body.AppendLine() - } +# Build documentation models. +$models = foreach ($cmd in $stepCommands) { + New-IdleStepDocModel -CommandInfo $cmd } -# Normalize output: -# - remove trailing whitespace/newlines introduced by StringBuilder -# - enforce exactly one LF at EOF (avoids "one newline too many" / dangling blank line issues) -$content = ($body.ToString().TrimEnd()) + "`n" +$models = @($models | Where-Object { $null -ne $_ } | Sort-Object -Property StepType) + +if ($models.Count -eq 0) { + throw "No step documentation models produced. Ensure step functions match 'Invoke-IdleStep'." +} + +# Write per-step-type pages. +$generatedDetailNames = New-Object System.Collections.Generic.List[string] + +foreach ($m in $models) { + $fileName = "$($m.Slug).md" + $filePath = Join-Path -Path $DetailOutputDirectory -ChildPath $fileName + + $pageContent = New-IdleStepDetailPageContent -Model $m + Set-Content -Path $filePath -Value $pageContent -Encoding utf8 -NoNewline + + $generatedDetailNames.Add($fileName) | Out-Null +} + +# Optionally remove obsolete generated pages. +if ($CleanObsoleteDetailPages) { + Remove-IdleObsoleteGeneratedPages -Directory $DetailOutputDirectory -KeepFileNames $generatedDetailNames.ToArray() +} -Set-Content -Path $OutputPath -Value $content -Encoding utf8 -NoNewline +# Write index page. +$indexContent = New-IdleStepsIndexPageContent -Models $models +Set-Content -Path $OutputPath -Value $indexContent -Encoding utf8 -NoNewline $generatedFile = Get-Item -Path $OutputPath -"Generated step reference: $($generatedFile.FullName) ($($generatedFile.Length) bytes)" +"Generated`nStep reference index: $($generatedFile.FullName) ($($generatedFile.Length) bytes)`nDetail pages: $($models.Count) in '$DetailOutputDirectory'" From 94287c2baf7840b281a4f834802b570e020f5ef3 Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 13:03:28 +0100 Subject: [PATCH 13/28] updated steps reference --- docs/reference/steps.md | 338 +----------------- docs/reference/steps/step-create-identity.md | 43 +++ docs/reference/steps/step-delete-identity.md | 44 +++ docs/reference/steps/step-disable-identity.md | 40 +++ docs/reference/steps/step-emit-event.md | 26 ++ docs/reference/steps/step-enable-identity.md | 40 +++ docs/reference/steps/step-ensure-attribute.md | 44 +++ .../steps/step-ensure-entitlement.md | 50 +++ docs/reference/steps/step-move-identity.md | 43 +++ .../steps/step-trigger-directory-sync.md | 40 +++ 10 files changed, 381 insertions(+), 327 deletions(-) create mode 100644 docs/reference/steps/step-create-identity.md create mode 100644 docs/reference/steps/step-delete-identity.md create mode 100644 docs/reference/steps/step-disable-identity.md create mode 100644 docs/reference/steps/step-emit-event.md create mode 100644 docs/reference/steps/step-enable-identity.md create mode 100644 docs/reference/steps/step-ensure-attribute.md create mode 100644 docs/reference/steps/step-ensure-entitlement.md create mode 100644 docs/reference/steps/step-move-identity.md create mode 100644 docs/reference/steps/step-trigger-directory-sync.md diff --git a/docs/reference/steps.md b/docs/reference/steps.md index ca5fc9da..1f43aae8 100644 --- a/docs/reference/steps.md +++ b/docs/reference/steps.md @@ -1,332 +1,16 @@ -# Step Catalog +# Steps > Generated file. Do not edit by hand. > Source: tools/Generate-IdleStepReference.ps1 -This page documents built-in IdLE steps discovered from `Invoke-IdleStep*` functions in `IdLE.Steps.*` modules. - ---- - -## CreateIdentity - -- **Step Name**: `CreateIdentity` -- **Implementation**: `Invoke-IdleStepCreateIdentity` -- **Idempotent**: `Yes` -- **Contracts**: `Unknown` -- **Events**: Unknown - -**Synopsis** - -Creates a new identity in the target system. - -**Description** - -This is a provider-agnostic step. The host must supply a provider instance via -Context.Providers[<ProviderAlias>] that implements CreateIdentity(identityKey, attributes) -and returns an object with properties 'IdentityKey' and 'Changed'. - -The step is idempotent by design: if the identity already exists, the provider -should return Changed = $false without creating a duplicate. - -Authentication: -- If With.AuthSessionName is present, the step acquires an auth session via - Context.AcquireAuthSession(Name, Options) and passes it to the provider method - if the provider supports an AuthSession parameter. -- With.AuthSessionOptions (optional, hashtable) is passed to the broker for - session selection (e.g., @\{ Role = 'Tier0' \}). -- ScriptBlocks in AuthSessionOptions are rejected (security boundary). - -**Inputs (With.\*)** - -| Key | Required | +| Step Type | Synopsis | | --- | --- | -| IdentityKey | Yes | -| Attributes | Yes | - ---- - -## DeleteIdentity - -- **Step Name**: `DeleteIdentity` -- **Implementation**: `Invoke-IdleStepDeleteIdentity` -- **Idempotent**: `Yes` -- **Contracts**: `Unknown` -- **Events**: Unknown - -**Synopsis** - -Deletes an identity from the target system. - -**Description** - -This is a provider-agnostic step. The host must supply a provider instance via -Context.Providers[<ProviderAlias>] that implements DeleteIdentity(identityKey) -and returns an object with properties 'IdentityKey' and 'Changed'. - -The step is idempotent by design: if the identity is already deleted, the provider -should return Changed = $false. - -IMPORTANT: This step requires the provider to advertise the IdLE.Identity.Delete -capability, which is typically opt-in for safety. The provider must be configured -to allow deletion (e.g., AllowDelete = $true for AD provider). - -Authentication: -- If With.AuthSessionName is present, the step acquires an auth session via - Context.AcquireAuthSession(Name, Options) and passes it to the provider method - if the provider supports an AuthSession parameter. -- With.AuthSessionOptions (optional, hashtable) is passed to the broker for - session selection (e.g., @\{ Role = 'Tier0' \}). -- ScriptBlocks in AuthSessionOptions are rejected (security boundary). - -**Inputs (With.\*)** - -_Unknown (not detected automatically). Document required With.* keys in the step help and/or use a supported pattern._ - ---- - -## DisableIdentity - -- **Step Name**: `DisableIdentity` -- **Implementation**: `Invoke-IdleStepDisableIdentity` -- **Idempotent**: `Yes` -- **Contracts**: `Unknown` -- **Events**: Unknown - -**Synopsis** - -Disables an identity in the target system. - -**Description** - -This is a provider-agnostic step. The host must supply a provider instance via -Context.Providers[<ProviderAlias>] that implements DisableIdentity(identityKey) -and returns an object with properties 'IdentityKey' and 'Changed'. - -The step is idempotent by design: if the identity is already disabled, the provider -should return Changed = $false. - -Authentication: -- If With.AuthSessionName is present, the step acquires an auth session via - Context.AcquireAuthSession(Name, Options) and passes it to the provider method - if the provider supports an AuthSession parameter. -- With.AuthSessionOptions (optional, hashtable) is passed to the broker for - session selection (e.g., @\{ Role = 'Tier0' \}). -- ScriptBlocks in AuthSessionOptions are rejected (security boundary). - -**Inputs (With.\*)** - -_Unknown (not detected automatically). Document required With.* keys in the step help and/or use a supported pattern._ - ---- - -## EmitEvent - -- **Step Name**: `EmitEvent` -- **Implementation**: `Invoke-IdleStepEmitEvent` -- **Idempotent**: `Unknown` -- **Contracts**: `Unknown` -- **Events**: Unknown - -**Synopsis** - -Emits a custom event (demo step). - -**Description** - -This step does not change external state. It emits a custom event message. -The engine provides an EventSink on the execution context that the step can use -to write structured events. - -**Inputs (With.\*)** - -_Unknown (not detected automatically). Document required With.* keys in the step help and/or use a supported pattern._ - ---- - -## EnableIdentity - -- **Step Name**: `EnableIdentity` -- **Implementation**: `Invoke-IdleStepEnableIdentity` -- **Idempotent**: `Yes` -- **Contracts**: `Unknown` -- **Events**: Unknown - -**Synopsis** - -Enables an identity in the target system. - -**Description** - -This is a provider-agnostic step. The host must supply a provider instance via -Context.Providers[<ProviderAlias>] that implements EnableIdentity(identityKey) -and returns an object with properties 'IdentityKey' and 'Changed'. - -The step is idempotent by design: if the identity is already enabled, the provider -should return Changed = $false. - -Authentication: -- If With.AuthSessionName is present, the step acquires an auth session via - Context.AcquireAuthSession(Name, Options) and passes it to the provider method - if the provider supports an AuthSession parameter. -- With.AuthSessionOptions (optional, hashtable) is passed to the broker for - session selection (e.g., @\{ Role = 'Tier0' \}). -- ScriptBlocks in AuthSessionOptions are rejected (security boundary). - -**Inputs (With.\*)** - -_Unknown (not detected automatically). Document required With.* keys in the step help and/or use a supported pattern._ - ---- - -## EnsureAttribute - -- **Step Name**: `EnsureAttribute` -- **Implementation**: `Invoke-IdleStepEnsureAttribute` -- **Idempotent**: `Yes` -- **Contracts**: `Provider must implement method: EnsureAttribute` -- **Events**: Unknown - -**Synopsis** - -Ensures that an identity attribute matches the desired value. - -**Description** - -This is a provider-agnostic step. The host must supply a provider instance via -Context.Providers[<ProviderAlias>]. The provider must implement an EnsureAttribute -method with the signature (IdentityKey, Name, Value) and return an object that -contains a boolean property 'Changed'. - -The step is idempotent by design: it converges state to the desired value. - -Authentication: -- If With.AuthSessionName is present, the step acquires an auth session via - Context.AcquireAuthSession(Name, Options) and passes it to the provider method - if the provider supports an AuthSession parameter. -- With.AuthSessionOptions (optional, hashtable) is passed to the broker for - session selection (e.g., @\{ Role = 'Tier0' \}). -- ScriptBlocks in AuthSessionOptions are rejected (security boundary). - -**Inputs (With.\*)** - -| Key | Required | -| --- | --- | -| IdentityKey | Yes | -| Name | Yes | -| Value | Yes | - ---- - -## EnsureEntitlement - -- **Step Name**: `EnsureEntitlement` -- **Implementation**: `Invoke-IdleStepEnsureEntitlement` -- **Idempotent**: `Yes` -- **Contracts**: `Unknown` -- **Events**: Unknown - -**Synopsis** - -Ensures that an entitlement assignment is present or absent for an identity. - -**Description** - -This provider-agnostic step uses entitlement provider contracts to converge -an assignment to the desired state. The host must supply a provider instance -via `Context.Providers[<ProviderAlias>]` that implements: - -- ListEntitlements(identityKey) -- GrantEntitlement(identityKey, entitlement) -- RevokeEntitlement(identityKey, entitlement) - -The step is idempotent and only calls Grant/Revoke when the assignment needs -to change. - -Authentication: -- If With.AuthSessionName is present, the step acquires an auth session via - Context.AcquireAuthSession(Name, Options) and passes it to the provider methods - if the provider supports an AuthSession parameter. -- With.AuthSessionOptions (optional, hashtable) is passed to the broker for - session selection (e.g., @\{ Role = 'Tier0' \}). -- ScriptBlocks in AuthSessionOptions are rejected (security boundary). - -**Inputs (With.\*)** - -| Key | Required | -| --- | --- | -| IdentityKey | Yes | -| Entitlement | Yes | -| State | Yes | - ---- - -## MoveIdentity - -- **Step Name**: `MoveIdentity` -- **Implementation**: `Invoke-IdleStepMoveIdentity` -- **Idempotent**: `Yes` -- **Contracts**: `Unknown` -- **Events**: Unknown - -**Synopsis** - -Moves an identity to a different container/OU in the target system. - -**Description** - -This is a provider-agnostic step. The host must supply a provider instance via -Context.Providers[<ProviderAlias>] that implements MoveIdentity(identityKey, targetContainer) -and returns an object with properties 'IdentityKey' and 'Changed'. - -The step is idempotent by design: if the identity is already in the target container, -the provider should return Changed = $false. - -Authentication: -- If With.AuthSessionName is present, the step acquires an auth session via - Context.AcquireAuthSession(Name, Options) and passes it to the provider method - if the provider supports an AuthSession parameter. -- With.AuthSessionOptions (optional, hashtable) is passed to the broker for - session selection (e.g., @\{ Role = 'Tier0' \}). -- ScriptBlocks in AuthSessionOptions are rejected (security boundary). - -**Inputs (With.\*)** - -| Key | Required | -| --- | --- | -| IdentityKey | Yes | -| TargetContainer | Yes | - ---- - -## TriggerDirectorySync - -- **Step Name**: `TriggerDirectorySync` -- **Implementation**: `Invoke-IdleStepTriggerDirectorySync` -- **Idempotent**: `Unknown` -- **Contracts**: `Unknown` -- **Events**: Unknown - -**Synopsis** - -Triggers a directory sync cycle and optionally waits for completion. - -**Description** - -This is a provider-agnostic step. The host must supply a provider instance via -Context.Providers[<ProviderAlias>] that implements: -- StartSyncCycle(PolicyType, AuthSession) -- GetSyncCycleState(AuthSession) - -The step is designed for remote execution and requires an elevated auth session -provided by the host's AuthSessionBroker. - -Authentication: -- With.AuthSessionName (required): routing key for AuthSessionBroker -- With.AuthSessionOptions (optional, hashtable): forwarded to broker for session selection -- ScriptBlocks in AuthSessionOptions are rejected (security boundary) - -**Inputs (With.\*)** - -_Unknown (not detected automatically). Document required With.* keys in the step help and/or use a supported pattern._ - ---- +| [CreateIdentity](steps/step-create-identity.md) | Creates a new identity in the target system. | +| [DeleteIdentity](steps/step-delete-identity.md) | Deletes an identity from the target system. | +| [DisableIdentity](steps/step-disable-identity.md) | Disables an identity in the target system. | +| [EmitEvent](steps/step-emit-event.md) | Emits a custom event (demo step). | +| [EnableIdentity](steps/step-enable-identity.md) | Enables an identity in the target system. | +| [EnsureAttribute](steps/step-ensure-attribute.md) | Ensures that an identity attribute matches the desired value. | +| [EnsureEntitlement](steps/step-ensure-entitlement.md) | Ensures that an entitlement assignment is present or absent for an identity. | +| [MoveIdentity](steps/step-move-identity.md) | Moves an identity to a different container/OU in the target system. | +| [TriggerDirectorySync](steps/step-trigger-directory-sync.md) | Triggers a directory sync cycle and optionally waits for completion. | diff --git a/docs/reference/steps/step-create-identity.md b/docs/reference/steps/step-create-identity.md new file mode 100644 index 00000000..40da04f5 --- /dev/null +++ b/docs/reference/steps/step-create-identity.md @@ -0,0 +1,43 @@ +# CreateIdentity + +> Generated file. Do not edit by hand. +> Source: tools/Generate-IdleStepReference.ps1 + +## Summary + +- **Step Type**: `CreateIdentity` +- **Implementation**: `Invoke-IdleStepCreateIdentity` +- **Idempotent**: `Yes` +- **Contracts**: `Unknown` +- **Events**: Unknown + +## Synopsis + +Creates a new identity in the target system. + +## Description + +This is a provider-agnostic step. The host must supply a provider instance via +Context.Providers[<ProviderAlias>] that implements CreateIdentity(identityKey, attributes) +and returns an object with properties 'IdentityKey' and 'Changed'. + +The step is idempotent by design: if the identity already exists, the provider +should return Changed = $false without creating a duplicate. + +Authentication: + +- If With.AuthSessionName is present, the step acquires an auth session via + Context.AcquireAuthSession(Name, Options) and passes it to the provider method + if the provider supports an AuthSession parameter. + +- With.AuthSessionOptions (optional, hashtable) is passed to the broker for + session selection (e.g., @\{ Role = 'Tier0' \}). + +- ScriptBlocks in AuthSessionOptions are rejected (security boundary). + +## Inputs (With.*) + +| Key | Required | +| --- | --- | +| IdentityKey | Yes | +| Attributes | Yes | diff --git a/docs/reference/steps/step-delete-identity.md b/docs/reference/steps/step-delete-identity.md new file mode 100644 index 00000000..9b77a9eb --- /dev/null +++ b/docs/reference/steps/step-delete-identity.md @@ -0,0 +1,44 @@ +# DeleteIdentity + +> Generated file. Do not edit by hand. +> Source: tools/Generate-IdleStepReference.ps1 + +## Summary + +- **Step Type**: `DeleteIdentity` +- **Implementation**: `Invoke-IdleStepDeleteIdentity` +- **Idempotent**: `Yes` +- **Contracts**: `Unknown` +- **Events**: Unknown + +## Synopsis + +Deletes an identity from the target system. + +## Description + +This is a provider-agnostic step. The host must supply a provider instance via +Context.Providers[<ProviderAlias>] that implements DeleteIdentity(identityKey) +and returns an object with properties 'IdentityKey' and 'Changed'. + +The step is idempotent by design: if the identity is already deleted, the provider +should return Changed = $false. + +IMPORTANT: This step requires the provider to advertise the IdLE.Identity.Delete +capability, which is typically opt-in for safety. The provider must be configured +to allow deletion (e.g., AllowDelete = $true for AD provider). + +Authentication: + +- If With.AuthSessionName is present, the step acquires an auth session via + Context.AcquireAuthSession(Name, Options) and passes it to the provider method + if the provider supports an AuthSession parameter. + +- With.AuthSessionOptions (optional, hashtable) is passed to the broker for + session selection (e.g., @\{ Role = 'Tier0' \}). + +- ScriptBlocks in AuthSessionOptions are rejected (security boundary). + +## Inputs (With.*) + +_Unknown (not detected automatically). Document required With.* keys in the step help and/or use a supported pattern._ diff --git a/docs/reference/steps/step-disable-identity.md b/docs/reference/steps/step-disable-identity.md new file mode 100644 index 00000000..b473e462 --- /dev/null +++ b/docs/reference/steps/step-disable-identity.md @@ -0,0 +1,40 @@ +# DisableIdentity + +> Generated file. Do not edit by hand. +> Source: tools/Generate-IdleStepReference.ps1 + +## Summary + +- **Step Type**: `DisableIdentity` +- **Implementation**: `Invoke-IdleStepDisableIdentity` +- **Idempotent**: `Yes` +- **Contracts**: `Unknown` +- **Events**: Unknown + +## Synopsis + +Disables an identity in the target system. + +## Description + +This is a provider-agnostic step. The host must supply a provider instance via +Context.Providers[<ProviderAlias>] that implements DisableIdentity(identityKey) +and returns an object with properties 'IdentityKey' and 'Changed'. + +The step is idempotent by design: if the identity is already disabled, the provider +should return Changed = $false. + +Authentication: + +- If With.AuthSessionName is present, the step acquires an auth session via + Context.AcquireAuthSession(Name, Options) and passes it to the provider method + if the provider supports an AuthSession parameter. + +- With.AuthSessionOptions (optional, hashtable) is passed to the broker for + session selection (e.g., @\{ Role = 'Tier0' \}). + +- ScriptBlocks in AuthSessionOptions are rejected (security boundary). + +## Inputs (With.*) + +_Unknown (not detected automatically). Document required With.* keys in the step help and/or use a supported pattern._ diff --git a/docs/reference/steps/step-emit-event.md b/docs/reference/steps/step-emit-event.md new file mode 100644 index 00000000..c3a22bef --- /dev/null +++ b/docs/reference/steps/step-emit-event.md @@ -0,0 +1,26 @@ +# EmitEvent + +> Generated file. Do not edit by hand. +> Source: tools/Generate-IdleStepReference.ps1 + +## Summary + +- **Step Type**: `EmitEvent` +- **Implementation**: `Invoke-IdleStepEmitEvent` +- **Idempotent**: `Unknown` +- **Contracts**: `Unknown` +- **Events**: Unknown + +## Synopsis + +Emits a custom event (demo step). + +## Description + +This step does not change external state. It emits a custom event message. +The engine provides an EventSink on the execution context that the step can use +to write structured events. + +## Inputs (With.*) + +_Unknown (not detected automatically). Document required With.* keys in the step help and/or use a supported pattern._ diff --git a/docs/reference/steps/step-enable-identity.md b/docs/reference/steps/step-enable-identity.md new file mode 100644 index 00000000..124377de --- /dev/null +++ b/docs/reference/steps/step-enable-identity.md @@ -0,0 +1,40 @@ +# EnableIdentity + +> Generated file. Do not edit by hand. +> Source: tools/Generate-IdleStepReference.ps1 + +## Summary + +- **Step Type**: `EnableIdentity` +- **Implementation**: `Invoke-IdleStepEnableIdentity` +- **Idempotent**: `Yes` +- **Contracts**: `Unknown` +- **Events**: Unknown + +## Synopsis + +Enables an identity in the target system. + +## Description + +This is a provider-agnostic step. The host must supply a provider instance via +Context.Providers[<ProviderAlias>] that implements EnableIdentity(identityKey) +and returns an object with properties 'IdentityKey' and 'Changed'. + +The step is idempotent by design: if the identity is already enabled, the provider +should return Changed = $false. + +Authentication: + +- If With.AuthSessionName is present, the step acquires an auth session via + Context.AcquireAuthSession(Name, Options) and passes it to the provider method + if the provider supports an AuthSession parameter. + +- With.AuthSessionOptions (optional, hashtable) is passed to the broker for + session selection (e.g., @\{ Role = 'Tier0' \}). + +- ScriptBlocks in AuthSessionOptions are rejected (security boundary). + +## Inputs (With.*) + +_Unknown (not detected automatically). Document required With.* keys in the step help and/or use a supported pattern._ diff --git a/docs/reference/steps/step-ensure-attribute.md b/docs/reference/steps/step-ensure-attribute.md new file mode 100644 index 00000000..647b1a3d --- /dev/null +++ b/docs/reference/steps/step-ensure-attribute.md @@ -0,0 +1,44 @@ +# EnsureAttribute + +> Generated file. Do not edit by hand. +> Source: tools/Generate-IdleStepReference.ps1 + +## Summary + +- **Step Type**: `EnsureAttribute` +- **Implementation**: `Invoke-IdleStepEnsureAttribute` +- **Idempotent**: `Yes` +- **Contracts**: `Provider must implement method: EnsureAttribute` +- **Events**: Unknown + +## Synopsis + +Ensures that an identity attribute matches the desired value. + +## Description + +This is a provider-agnostic step. The host must supply a provider instance via +Context.Providers[<ProviderAlias>]. The provider must implement an EnsureAttribute +method with the signature (IdentityKey, Name, Value) and return an object that +contains a boolean property 'Changed'. + +The step is idempotent by design: it converges state to the desired value. + +Authentication: + +- If With.AuthSessionName is present, the step acquires an auth session via + Context.AcquireAuthSession(Name, Options) and passes it to the provider method + if the provider supports an AuthSession parameter. + +- With.AuthSessionOptions (optional, hashtable) is passed to the broker for + session selection (e.g., @\{ Role = 'Tier0' \}). + +- ScriptBlocks in AuthSessionOptions are rejected (security boundary). + +## Inputs (With.*) + +| Key | Required | +| --- | --- | +| IdentityKey | Yes | +| Name | Yes | +| Value | Yes | diff --git a/docs/reference/steps/step-ensure-entitlement.md b/docs/reference/steps/step-ensure-entitlement.md new file mode 100644 index 00000000..b5a59d9a --- /dev/null +++ b/docs/reference/steps/step-ensure-entitlement.md @@ -0,0 +1,50 @@ +# EnsureEntitlement + +> Generated file. Do not edit by hand. +> Source: tools/Generate-IdleStepReference.ps1 + +## Summary + +- **Step Type**: `EnsureEntitlement` +- **Implementation**: `Invoke-IdleStepEnsureEntitlement` +- **Idempotent**: `Yes` +- **Contracts**: `Unknown` +- **Events**: Unknown + +## Synopsis + +Ensures that an entitlement assignment is present or absent for an identity. + +## Description + +This provider-agnostic step uses entitlement provider contracts to converge +an assignment to the desired state. The host must supply a provider instance +via `Context.Providers[<ProviderAlias>]` that implements: + +- ListEntitlements(identityKey) + +- GrantEntitlement(identityKey, entitlement) + +- RevokeEntitlement(identityKey, entitlement) + +The step is idempotent and only calls Grant/Revoke when the assignment needs +to change. + +Authentication: + +- If With.AuthSessionName is present, the step acquires an auth session via + Context.AcquireAuthSession(Name, Options) and passes it to the provider methods + if the provider supports an AuthSession parameter. + +- With.AuthSessionOptions (optional, hashtable) is passed to the broker for + session selection (e.g., @\{ Role = 'Tier0' \}). + +- ScriptBlocks in AuthSessionOptions are rejected (security boundary). + +## Inputs (With.*) + +| Key | Required | +| --- | --- | +| IdentityKey | Yes | +| Entitlement | Yes | +| State | Yes | diff --git a/docs/reference/steps/step-move-identity.md b/docs/reference/steps/step-move-identity.md new file mode 100644 index 00000000..78432f4a --- /dev/null +++ b/docs/reference/steps/step-move-identity.md @@ -0,0 +1,43 @@ +# MoveIdentity + +> Generated file. Do not edit by hand. +> Source: tools/Generate-IdleStepReference.ps1 + +## Summary + +- **Step Type**: `MoveIdentity` +- **Implementation**: `Invoke-IdleStepMoveIdentity` +- **Idempotent**: `Yes` +- **Contracts**: `Unknown` +- **Events**: Unknown + +## Synopsis + +Moves an identity to a different container/OU in the target system. + +## Description + +This is a provider-agnostic step. The host must supply a provider instance via +Context.Providers[<ProviderAlias>] that implements MoveIdentity(identityKey, targetContainer) +and returns an object with properties 'IdentityKey' and 'Changed'. + +The step is idempotent by design: if the identity is already in the target container, +the provider should return Changed = $false. + +Authentication: + +- If With.AuthSessionName is present, the step acquires an auth session via + Context.AcquireAuthSession(Name, Options) and passes it to the provider method + if the provider supports an AuthSession parameter. + +- With.AuthSessionOptions (optional, hashtable) is passed to the broker for + session selection (e.g., @\{ Role = 'Tier0' \}). + +- ScriptBlocks in AuthSessionOptions are rejected (security boundary). + +## Inputs (With.*) + +| Key | Required | +| --- | --- | +| IdentityKey | Yes | +| TargetContainer | Yes | diff --git a/docs/reference/steps/step-trigger-directory-sync.md b/docs/reference/steps/step-trigger-directory-sync.md new file mode 100644 index 00000000..a8982912 --- /dev/null +++ b/docs/reference/steps/step-trigger-directory-sync.md @@ -0,0 +1,40 @@ +# TriggerDirectorySync + +> Generated file. Do not edit by hand. +> Source: tools/Generate-IdleStepReference.ps1 + +## Summary + +- **Step Type**: `TriggerDirectorySync` +- **Implementation**: `Invoke-IdleStepTriggerDirectorySync` +- **Idempotent**: `Unknown` +- **Contracts**: `Unknown` +- **Events**: Unknown + +## Synopsis + +Triggers a directory sync cycle and optionally waits for completion. + +## Description + +This is a provider-agnostic step. The host must supply a provider instance via +Context.Providers[<ProviderAlias>] that implements: + +- StartSyncCycle(PolicyType, AuthSession) + +- GetSyncCycleState(AuthSession) + +The step is designed for remote execution and requires an elevated auth session +provided by the host's AuthSessionBroker. + +Authentication: + +- With.AuthSessionName (required): routing key for AuthSessionBroker + +- With.AuthSessionOptions (optional, hashtable): forwarded to broker for session selection + +- ScriptBlocks in AuthSessionOptions are rejected (security boundary) + +## Inputs (With.*) + +_Unknown (not detected automatically). Document required With.* keys in the step help and/or use a supported pattern._ From afea484f29895dc9022bfab5afc1d3915c7b562b Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 13:04:37 +0100 Subject: [PATCH 14/28] fixed cmdlet reference generator title for page --- tools/Generate-IdleCmdletReference.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/Generate-IdleCmdletReference.ps1 b/tools/Generate-IdleCmdletReference.ps1 index af3b81c6..992b7cf4 100644 --- a/tools/Generate-IdleCmdletReference.ps1 +++ b/tools/Generate-IdleCmdletReference.ps1 @@ -217,7 +217,7 @@ function New-IdleCmdletIndexMarkdown { } $lines = New-Object System.Collections.Generic.List[string] - $lines.Add('# Cmdlet Reference') + $lines.Add('# Cmdlets') $lines.Add('') $lines.Add('> Generated file. Do not edit by hand.') $lines.Add('> Source: tools/Generate-IdleCmdletReference.ps1') From a7dff705867b77e1fee600dbfc480b49975101a3 Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 13:15:33 +0100 Subject: [PATCH 15/28] update step generator sidebar and generated steps files --- docs/reference/steps.md | 22 ++++---- docs/reference/steps/step-create-identity.md | 1 + docs/reference/steps/step-delete-identity.md | 1 + docs/reference/steps/step-disable-identity.md | 1 + docs/reference/steps/step-emit-event.md | 1 + docs/reference/steps/step-enable-identity.md | 1 + docs/reference/steps/step-ensure-attribute.md | 1 + .../steps/step-ensure-entitlement.md | 1 + docs/reference/steps/step-move-identity.md | 1 + .../steps/step-trigger-directory-sync.md | 1 + tools/Generate-IdleStepReference.ps1 | 56 +++++++++++-------- website/sidebars.js | 18 +++++- 12 files changed, 70 insertions(+), 35 deletions(-) diff --git a/docs/reference/steps.md b/docs/reference/steps.md index 1f43aae8..9b6ddee5 100644 --- a/docs/reference/steps.md +++ b/docs/reference/steps.md @@ -3,14 +3,14 @@ > Generated file. Do not edit by hand. > Source: tools/Generate-IdleStepReference.ps1 -| Step Type | Synopsis | -| --- | --- | -| [CreateIdentity](steps/step-create-identity.md) | Creates a new identity in the target system. | -| [DeleteIdentity](steps/step-delete-identity.md) | Deletes an identity from the target system. | -| [DisableIdentity](steps/step-disable-identity.md) | Disables an identity in the target system. | -| [EmitEvent](steps/step-emit-event.md) | Emits a custom event (demo step). | -| [EnableIdentity](steps/step-enable-identity.md) | Enables an identity in the target system. | -| [EnsureAttribute](steps/step-ensure-attribute.md) | Ensures that an identity attribute matches the desired value. | -| [EnsureEntitlement](steps/step-ensure-entitlement.md) | Ensures that an entitlement assignment is present or absent for an identity. | -| [MoveIdentity](steps/step-move-identity.md) | Moves an identity to a different container/OU in the target system. | -| [TriggerDirectorySync](steps/step-trigger-directory-sync.md) | Triggers a directory sync cycle and optionally waits for completion. | +| Step Type | Module | Synopsis | +| --- | --- | --- | +| [CreateIdentity](steps/step-create-identity.md) | ``IdLE.Steps.Common`` | Creates a new identity in the target system. | +| [DeleteIdentity](steps/step-delete-identity.md) | ``IdLE.Steps.Common`` | Deletes an identity from the target system. | +| [DisableIdentity](steps/step-disable-identity.md) | ``IdLE.Steps.Common`` | Disables an identity in the target system. | +| [EmitEvent](steps/step-emit-event.md) | ``IdLE.Steps.Common`` | Emits a custom event (demo step). | +| [EnableIdentity](steps/step-enable-identity.md) | ``IdLE.Steps.Common`` | Enables an identity in the target system. | +| [EnsureAttribute](steps/step-ensure-attribute.md) | ``IdLE.Steps.Common`` | Ensures that an identity attribute matches the desired value. | +| [EnsureEntitlement](steps/step-ensure-entitlement.md) | ``IdLE.Steps.Common`` | Ensures that an entitlement assignment is present or absent for an identity. | +| [MoveIdentity](steps/step-move-identity.md) | ``IdLE.Steps.Common`` | Moves an identity to a different container/OU in the target system. | +| [TriggerDirectorySync](steps/step-trigger-directory-sync.md) | ``IdLE.Steps.DirectorySync`` | Triggers a directory sync cycle and optionally waits for completion. | diff --git a/docs/reference/steps/step-create-identity.md b/docs/reference/steps/step-create-identity.md index 40da04f5..83cc4ab9 100644 --- a/docs/reference/steps/step-create-identity.md +++ b/docs/reference/steps/step-create-identity.md @@ -6,6 +6,7 @@ ## Summary - **Step Type**: `CreateIdentity` +- **Module**: `IdLE.Steps.Common` - **Implementation**: `Invoke-IdleStepCreateIdentity` - **Idempotent**: `Yes` - **Contracts**: `Unknown` diff --git a/docs/reference/steps/step-delete-identity.md b/docs/reference/steps/step-delete-identity.md index 9b77a9eb..f090ffbc 100644 --- a/docs/reference/steps/step-delete-identity.md +++ b/docs/reference/steps/step-delete-identity.md @@ -6,6 +6,7 @@ ## Summary - **Step Type**: `DeleteIdentity` +- **Module**: `IdLE.Steps.Common` - **Implementation**: `Invoke-IdleStepDeleteIdentity` - **Idempotent**: `Yes` - **Contracts**: `Unknown` diff --git a/docs/reference/steps/step-disable-identity.md b/docs/reference/steps/step-disable-identity.md index b473e462..cf5ee16b 100644 --- a/docs/reference/steps/step-disable-identity.md +++ b/docs/reference/steps/step-disable-identity.md @@ -6,6 +6,7 @@ ## Summary - **Step Type**: `DisableIdentity` +- **Module**: `IdLE.Steps.Common` - **Implementation**: `Invoke-IdleStepDisableIdentity` - **Idempotent**: `Yes` - **Contracts**: `Unknown` diff --git a/docs/reference/steps/step-emit-event.md b/docs/reference/steps/step-emit-event.md index c3a22bef..dcde656f 100644 --- a/docs/reference/steps/step-emit-event.md +++ b/docs/reference/steps/step-emit-event.md @@ -6,6 +6,7 @@ ## Summary - **Step Type**: `EmitEvent` +- **Module**: `IdLE.Steps.Common` - **Implementation**: `Invoke-IdleStepEmitEvent` - **Idempotent**: `Unknown` - **Contracts**: `Unknown` diff --git a/docs/reference/steps/step-enable-identity.md b/docs/reference/steps/step-enable-identity.md index 124377de..771ddcba 100644 --- a/docs/reference/steps/step-enable-identity.md +++ b/docs/reference/steps/step-enable-identity.md @@ -6,6 +6,7 @@ ## Summary - **Step Type**: `EnableIdentity` +- **Module**: `IdLE.Steps.Common` - **Implementation**: `Invoke-IdleStepEnableIdentity` - **Idempotent**: `Yes` - **Contracts**: `Unknown` diff --git a/docs/reference/steps/step-ensure-attribute.md b/docs/reference/steps/step-ensure-attribute.md index 647b1a3d..a569a1e1 100644 --- a/docs/reference/steps/step-ensure-attribute.md +++ b/docs/reference/steps/step-ensure-attribute.md @@ -6,6 +6,7 @@ ## Summary - **Step Type**: `EnsureAttribute` +- **Module**: `IdLE.Steps.Common` - **Implementation**: `Invoke-IdleStepEnsureAttribute` - **Idempotent**: `Yes` - **Contracts**: `Provider must implement method: EnsureAttribute` diff --git a/docs/reference/steps/step-ensure-entitlement.md b/docs/reference/steps/step-ensure-entitlement.md index b5a59d9a..63dbbe96 100644 --- a/docs/reference/steps/step-ensure-entitlement.md +++ b/docs/reference/steps/step-ensure-entitlement.md @@ -6,6 +6,7 @@ ## Summary - **Step Type**: `EnsureEntitlement` +- **Module**: `IdLE.Steps.Common` - **Implementation**: `Invoke-IdleStepEnsureEntitlement` - **Idempotent**: `Yes` - **Contracts**: `Unknown` diff --git a/docs/reference/steps/step-move-identity.md b/docs/reference/steps/step-move-identity.md index 78432f4a..48134535 100644 --- a/docs/reference/steps/step-move-identity.md +++ b/docs/reference/steps/step-move-identity.md @@ -6,6 +6,7 @@ ## Summary - **Step Type**: `MoveIdentity` +- **Module**: `IdLE.Steps.Common` - **Implementation**: `Invoke-IdleStepMoveIdentity` - **Idempotent**: `Yes` - **Contracts**: `Unknown` diff --git a/docs/reference/steps/step-trigger-directory-sync.md b/docs/reference/steps/step-trigger-directory-sync.md index a8982912..8edaa1b7 100644 --- a/docs/reference/steps/step-trigger-directory-sync.md +++ b/docs/reference/steps/step-trigger-directory-sync.md @@ -6,6 +6,7 @@ ## Summary - **Step Type**: `TriggerDirectorySync` +- **Module**: `IdLE.Steps.DirectorySync` - **Implementation**: `Invoke-IdleStepTriggerDirectorySync` - **Idempotent**: `Unknown` - **Contracts**: `Unknown` diff --git a/tools/Generate-IdleStepReference.ps1 b/tools/Generate-IdleStepReference.ps1 index 319aa9b7..78ee6dfc 100644 --- a/tools/Generate-IdleStepReference.ps1 +++ b/tools/Generate-IdleStepReference.ps1 @@ -125,20 +125,9 @@ function Ensure-IdleBlankLineBeforeMarkdownLists { ) # Many markdown linters require a blank line before lists. - # - # Turn: - # Authentication: - # - item - # Into: - # Authentication: - # - # - item - # # Also applies to: "* ", "+ ", and numbered lists "1. ". $t = $Text -replace "`r`n", "`n" -replace "`r", "`n" - # Insert an extra newline when a non-empty line is followed by a list item line. - # We only insert if there is not already an empty line. $t = [regex]::Replace( $t, '(?m)(?<=\S)\n(?=(?:- |\* |\+ |\d+\. ))', @@ -159,20 +148,17 @@ function ConvertTo-IdleMdxSafeText { # NOTE: # We intentionally sanitize ONLY help-derived text (synopsis/description), # not the full generated Markdown structure. - # - # 1) Replace simple angle tokens () that MDX might interpret as JSX. - # 2) Escape braces so MDX does not treat them as expressions. - # 3) Ensure blank line before markdown lists for linting. $t = $Text -replace "`r`n", "`n" -replace "`r", "`n" - # Replace with HTML entities. + # Replace with HTML entities (MDX/JSX safety). $t = $t -replace '<(?[A-Za-z][A-Za-z0-9_-]*)>', '<${tok}>' # Escape braces to avoid MDX expression parsing, e.g. @{ ... } or {Name}. $t = $t -replace '\{', '\{' $t = $t -replace '\}', '\}' + # Lint-friendly markdown lists. $t = Ensure-IdleBlankLineBeforeMarkdownLists -Text $t return $t.Trim() @@ -325,6 +311,27 @@ function ConvertTo-IdleStepSlug { return $slug } +function Get-IdleCommandModuleName { + [CmdletBinding()] + param( + [Parameter(Mandatory)] + [ValidateNotNull()] + [System.Management.Automation.CommandInfo] $CommandInfo + ) + + # Prefer ModuleName (string), then Module.Name, else Unknown. + $moduleName = $CommandInfo.ModuleName + if (-not [string]::IsNullOrWhiteSpace($moduleName)) { + return $moduleName + } + + if ($null -ne $CommandInfo.Module -and -not [string]::IsNullOrWhiteSpace($CommandInfo.Module.Name)) { + return $CommandInfo.Module.Name + } + + return 'Unknown' +} + function New-IdleStepDocModel { [CmdletBinding()] param( @@ -339,6 +346,7 @@ function New-IdleStepDocModel { return $null } + $moduleName = Get-IdleCommandModuleName -CommandInfo $CommandInfo $help = Get-IdleHelpSafe -CommandName $commandName $synopsis = '' @@ -374,6 +382,7 @@ function New-IdleStepDocModel { return [pscustomobject]@{ StepType = $stepType Slug = $slug + ModuleName = $moduleName CommandName = $commandName Synopsis = $synopsis Description = $description @@ -402,6 +411,7 @@ function New-IdleStepDetailPageContent { [void]$sb.AppendLine('## Summary') [void]$sb.AppendLine() [void]$sb.AppendLine(("- **Step Type**: ``{0}``" -f $Model.StepType)) + [void]$sb.AppendLine(("- **Module**: ``{0}``" -f $Model.ModuleName)) [void]$sb.AppendLine(("- **Implementation**: ``{0}``" -f $Model.CommandName)) [void]$sb.AppendLine(("- **Idempotent**: ``{0}``" -f $Model.Idempotent)) [void]$sb.AppendLine(("- **Contracts**: ``{0}``" -f $Model.Contracts)) @@ -455,13 +465,13 @@ function New-IdleStepsIndexPageContent { [void]$sb.AppendLine('> Generated file. Do not edit by hand.') [void]$sb.AppendLine("> $script:GeneratorMarker") [void]$sb.AppendLine() - [void]$sb.AppendLine('| Step Type | Synopsis |') - [void]$sb.AppendLine('| --- | --- |') + [void]$sb.AppendLine('| Step Type | Module | Synopsis |') + [void]$sb.AppendLine('| --- | --- | --- |') foreach ($m in ($Models | Sort-Object -Property StepType)) { # Keep synopsis a single line in the table. $syn = ($m.Synopsis -replace '\s+', ' ').Trim() - [void]$sb.AppendLine(('| [{0}](steps/{1}.md) | {2} |' -f $m.StepType, $m.Slug, $syn)) + [void]$sb.AppendLine(('| [{0}](steps/{1}.md) | ``{2}`` | {3} |' -f $m.StepType, $m.Slug, $m.ModuleName, $syn)) } return ($sb.ToString().TrimEnd()) + "`n" @@ -511,7 +521,7 @@ if (-not $PSBoundParameters.ContainsKey('OutputPath')) { $ModuleManifestPath = Resolve-IdleRepoPath -Path $ModuleManifestPath -# Ensure output directories exist. +# Ensure output directory exists. $outDir = Split-Path -Path $OutputPath -Parent if (-not (Test-Path -Path $outDir)) { New-Item -Path $outDir -ItemType Directory -Force | Out-Null @@ -529,7 +539,7 @@ if (-not (Test-Path -Path $DetailOutputDirectory)) { Remove-Module -Name 'IdLE*' -Force -ErrorAction SilentlyContinue Import-Module -Name $ModuleManifestPath -Force -ErrorAction Stop -# Ensure step modules are loaded (Import-Module by name does NOT load nested step modules automatically). +# Ensure step modules are loaded (Import-Module IdLE.psd1 does NOT load nested step modules automatically). foreach ($m in $StepModules) { if (Get-Module -Name $m) { continue @@ -538,7 +548,6 @@ foreach ($m in $StepModules) { Write-Verbose "Importing step module: $m" try { - # Try by module name first (works if it is already discoverable in PSModulePath). Import-Module -Name $m -Force -ErrorAction Stop continue } @@ -609,4 +618,5 @@ $indexContent = New-IdleStepsIndexPageContent -Models $models Set-Content -Path $OutputPath -Value $indexContent -Encoding utf8 -NoNewline $generatedFile = Get-Item -Path $OutputPath -"Generated`nStep reference index: $($generatedFile.FullName) ($($generatedFile.Length) bytes)`nDetail pages: $($models.Count) in '$DetailOutputDirectory'" +$generatedFile = Get-Item -Path $OutputPath +"Generated`n`tStep reference index: $($generatedFile.FullName) ($($generatedFile.Length) bytes)`n`tDetail pages: $($models.Count) in '$DetailOutputDirectory'" diff --git a/website/sidebars.js b/website/sidebars.js index 52eda437..68016044 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -75,7 +75,22 @@ const sidebars = { ], }, 'reference/steps', - 'reference/capabilities', + { + type: 'category', + label: 'Step Reference', + collapsed: true, + items: [ + 'reference/steps/step-create-identity', + 'reference/steps/step-delete-identity', + 'reference/steps/step-disable-identity', + 'reference/steps/step-enable-identity', + 'reference/steps/step-emit-event', + 'reference/steps/step-ensure-attribute', + 'reference/steps/step-ensure-entitlement', + 'reference/steps/step-move-identity', + 'reference/steps/step-trigger-directory-sync', + ] + }, 'reference/providers', { type: 'category', @@ -86,6 +101,7 @@ const sidebars = { 'reference/providers/provider-entraID', ], }, + 'reference/capabilities', { type: 'category', label: 'Specs', From 2a38b6af4b664cfed6b1d7c030e2f706f8c768ae Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 17:46:34 +0100 Subject: [PATCH 16/28] updated provider references --- docs/reference/providers/provider-ad.md | 72 +++++- .../provider-directorysync-entraconnect.md | 228 ++++++++++++++++++ docs/reference/providers/provider-entraID.md | 93 ++++++- .../providers/provider-exchangeonline.md | 205 ++++++++++++++++ docs/reference/providers/provider-mock.md | 180 ++++++++++++++ website/sidebars.js | 3 + 6 files changed, 779 insertions(+), 2 deletions(-) create mode 100644 docs/reference/providers/provider-directorysync-entraconnect.md create mode 100644 docs/reference/providers/provider-exchangeonline.md create mode 100644 docs/reference/providers/provider-mock.md diff --git a/docs/reference/providers/provider-ad.md b/docs/reference/providers/provider-ad.md index 998654f7..269dbe64 100644 --- a/docs/reference/providers/provider-ad.md +++ b/docs/reference/providers/provider-ad.md @@ -1,4 +1,7 @@ -# IdLE.Provider.AD - Active Directory Provider +--- +title: IdLE.Provider.AD - Active Directory Provider +sidebar_label: Active Directory +--- ## Overview @@ -83,6 +86,73 @@ This makes `New-IdleADIdentityProvider` available in your session. --- + + +## Authentication and session acquisition + +> Providers must not prompt for auth. Use the host-provided broker contract. + +- **Auth session name(s) used by built-in steps:** `ActiveDirectory` +- **Auth session formats supported:** + - `null` (integrated authentication / run-as) + - `PSCredential` (used for AD cmdlets `-Credential`) +- **Session options (data-only):** Any hashtable; commonly `@{ Role = 'Tier0' }` / `@{ Role = 'Admin' }` + +:::warn + +**Security notes** + +- Do not pass secrets in workflow files or provider options. +- Make sure your host does not emit credential objects (or their secure strings) in logs/events. + +:::: + +### Auth examples + +**A) Integrated authentication (no broker)** + +```powershell +# Run the host under an account that already has the required AD permissions. +$providers = @{ + Identity = New-IdleADIdentityProvider +} +``` + +**B) Role-based routing with `New-IdleAuthSession` (typical Tier0/Admin)** + +```powershell +$tier0Credential = Get-Credential -Message 'Enter Tier0 AD admin credentials' +$adminCredential = Get-Credential -Message 'Enter AD admin credentials' + +$broker = New-IdleAuthSession -SessionMap @{ + @{ Role = 'Tier0' } = $tier0Credential + @{ Role = 'Admin' } = $adminCredential +} -DefaultCredential $adminCredential + +$providers = @{ + Identity = New-IdleADIdentityProvider + AuthSessionBroker = $broker +} + +# In the workflow step: +# With.AuthSessionName = 'ActiveDirectory' +# With.AuthSessionOptions = @{ Role = 'Tier0' } +``` + +**C) Multi-forest / multi-domain routing** + +```powershell +$sourceCred = Get-Credential -Message 'Enter credentials for source forest' +$targetCred = Get-Credential -Message 'Enter credentials for target forest' + +$broker = New-IdleAuthSession -SessionMap @{ + @{ Domain = 'SourceForest' } = $sourceCred + @{ Domain = 'TargetForest' } = $targetCred +} + +# Steps use With.AuthSessionOptions = @{ Domain = 'SourceForest' } etc. +``` + ## Usage ### Basic Usage (Integrated Auth) diff --git a/docs/reference/providers/provider-directorysync-entraconnect.md b/docs/reference/providers/provider-directorysync-entraconnect.md new file mode 100644 index 00000000..31644faa --- /dev/null +++ b/docs/reference/providers/provider-directorysync-entraconnect.md @@ -0,0 +1,228 @@ +--- +title: Provider Reference: IdLE.Provider.DirectorySync.EntraConnect +sidebar_label: DirectorySync.EntraConnect +--- + +> **Purpose:** This page is a **reference** for a specific provider implementation. +> Keep it factual and contract-oriented. Put conceptual explanations elsewhere and link to them. + +--- + +## Summary + +- **Provider name:** EntraConnect DirectorySync +- **Module:** `IdLE.Provider.DirectorySync.EntraConnect` +- **Provider kind:** Other +- **Targets:** Entra ID Connect (ADSync) sync scheduler on a Windows server (remote execution) +- **Status:** First-party (bundled) +- **Since:** 0.9.0 +- **Compatibility:** PowerShell 7+ (IdLE requirement) + +--- + +## What this provider does + +- **Primary responsibilities:** + - Trigger an Entra Connect sync cycle (`Delta` or `Initial`). + - Query sync cycle state (whether a cycle is in progress). +- **Out of scope / non-goals:** + - Establishing remote connectivity, authentication, or elevation (handled by the host/broker). + - Installing or configuring Entra Connect / ADSync. + +--- + +## Contracts and capabilities + +### Contracts implemented + +| Contract | Used by steps for | Notes | +| --- | --- | --- | +| Directory sync provider (implicit) | Trigger and monitor directory sync cycles | Exposes `StartSyncCycle(PolicyType, AuthSession)` and `GetSyncCycleState(AuthSession)` as script methods. | + +### Capability advertisement (`GetCapabilities()`) + +- **Implements `GetCapabilities()`**: Yes +- **Capabilities returned (stable identifiers):** + - `IdLE.DirectorySync.Trigger` + - `IdLE.DirectorySync.Status` + +--- + +## Authentication and session acquisition + +> Providers must not prompt for auth. Use the host-provided broker contract. + +This provider expects a host-provided **AuthSession** object that implements: + +- `InvokeCommand(CommandName, Parameters)` + +The provider does not call `Context.AcquireAuthSession(...)` directly; IdLE steps acquire an auth session +and pass it to provider methods. + +- **Auth session name(s) used by built-in steps:** + - `DirectorySync` (see `IdLE.Step.TriggerDirectorySync`) +- **Session options (data-only):** + - Forwarded to the host broker for session selection (provider does not interpret option keys). + +:::warn + +**Security notes** + +- Do not pass secrets in provider options. +- Ensure token/credential objects are not emitted in events. + +::: + +### Auth examples + +**A) Simple WinRM/PowerShell Remoting wrapper (typical)** + +The provider expects an auth session object with an `InvokeCommand(CommandName, Parameters)` method. +Your host can wrap `Invoke-Command` like this: + +```powershell +$syncCred = Get-Credential -Message 'Enter credentials for Entra Connect server' + +$authSession = [pscustomobject]@{ + ComputerName = 'entra-connect-01.contoso.local' + Credential = $syncCred +} +$authSession | Add-Member -MemberType ScriptMethod -Name InvokeCommand -Value { + param([string] $CommandName, [hashtable] $Parameters) + + Invoke-Command -ComputerName $this.ComputerName -Credential $this.Credential -ScriptBlock { + param($cmd, $params) + & $cmd @params + } -ArgumentList $CommandName, $Parameters +} + +$broker = [pscustomobject]@{} +$broker | Add-Member -MemberType ScriptMethod -Name AcquireAuthSession -Value { + param($Name, $Options) + return $authSession +} + +$providers = @{ + DirectorySync = New-IdleEntraConnectDirectorySyncProvider + AuthSessionBroker = $broker +} + +# Steps use With.AuthSessionName = 'DirectorySync' +``` + +**B) Role-based routing (Tier0 vs. Admin)** + +```powershell +$tier0 = New-EntraConnectAuthSession -ComputerName 'entra-connect-01' -Credential (Get-Credential) +$admin = New-EntraConnectAuthSession -ComputerName 'entra-connect-01' -Credential (Get-Credential) + +$broker = [pscustomobject]@{} +$broker | Add-Member -MemberType ScriptMethod -Name AcquireAuthSession -Value { + param($Name, $Options) + if ($Options.Role -eq 'Tier0') { return $tier0 } + return $admin +} +``` + +> Note: if `Start-ADSyncSyncCycle` requires elevation on your server, handle that in the host +> (scheduled task, JEA endpoint, endpoint configuration), not inside the provider. + +--- + +## Configuration + +### Provider constructor / factory + +- **Public constructor cmdlet(s):** + - `New-IdleEntraConnectDirectorySyncProvider` — Creates a provider instance. + +> Do not copy full comment-based help here. Link to the cmdlet reference. + +### Provider bag / alias usage + +```powershell +$providers = @{ + DirectorySync = New-IdleEntraConnectDirectorySyncProvider +} +``` + +- **Recommended alias pattern:** `DirectorySync` +- **Default alias expected by built-in steps (if any):** `DirectorySync` (used by `IdLE.Step.TriggerDirectorySync`) + +--- + +## Provider-specific options reference + +This provider has **no provider-specific option bag**. Runtime behavior depends on the host-provided AuthSession. + +--- + +## Operational behavior + +### Idempotency and consistency + +- **Idempotent operations:** Partial (triggering a sync cycle is an action; the step may optionally wait for completion) +- **Consistency model:** Depends on the directory synchronization runtime +- **Concurrency notes:** + - Triggering a new cycle may fail if a cycle is already in progress. + +### Error mapping and retry behavior + +- **Common error categories:** `PermissionDenied/ElevationRequired`, `Throttled/Busy`, `RemoteExecutionFailed` +- **Retry strategy:** None in the provider; any retries/backoff should be handled by the host or by the calling step. + +--- + +## Observability + +- **Events emitted by provider (if any):** None +- **Sensitive data redaction:** Enforced by IdLE output-boundary redaction; hosts should ensure the AuthSession does not leak secrets. + +--- + +## Examples + +### Minimal host usage + +```powershell +# 1) Create provider instance +$provider = New-IdleEntraConnectDirectorySyncProvider + +# 2) Build provider map +$providers = @{ + DirectorySync = $provider + AuthSessionBroker = $broker # host-provided +} + +# 3) Plan + execute +$plan = New-IdlePlan -WorkflowPath .\workflow.psd1 -Request $request -Providers $providers +$result = Invoke-IdlePlan -Plan $plan -Providers $providers +``` + +### Example workflow snippet + +```powershell +@{ + Steps = @( + @{ + Name = 'Trigger directory sync' + Type = 'IdLE.Step.TriggerDirectorySync' + With = @{ + Provider = 'DirectorySync' + AuthSessionName = 'DirectorySync' + PolicyType = 'Delta' + Wait = $true + TimeoutSeconds = 600 + PollIntervalSeconds = 10 + } + } + ) +} +``` + +--- + +## Limitations and known issues + +- Requires an elevated remote execution context on the Entra Connect server. +- The remote target must have the ADSync cmdlets available (`Start-ADSyncSyncCycle`, `Get-ADSyncScheduler`). diff --git a/docs/reference/providers/provider-entraID.md b/docs/reference/providers/provider-entraID.md index a0b64ed8..8f401676 100644 --- a/docs/reference/providers/provider-entraID.md +++ b/docs/reference/providers/provider-entraID.md @@ -1,4 +1,7 @@ -# IdLE.Provider.EntraID Reference +--- +title: IdLE.Provider.EntraID Reference +sidebar_label: Entra ID +--- Microsoft Entra ID (formerly Azure Active Directory) identity provider for IdLE. @@ -92,6 +95,94 @@ $broker = New-IdleAuthSession -SessionMap @{ # Workflow steps specify: With.AuthSessionOptions = @{ Role = 'Tier0' } ``` + + +> Providers must not prompt for auth. Use the host-provided broker contract. + +- **Auth session name(s) used by built-in steps:** `MicrosoftGraph` +- **Auth session formats supported:** + - `string` Bearer access token + - object with `AccessToken` property + - object with `GetAccessToken()` method + - `PSCredential` (token stored in password field; username is ignored) +- **Session options (data-only):** Any hashtable; common keys: `Role`, `Tenant`, `Environment` + +:::warn + +**Security notes** + +- Do not pass secrets in workflow files or provider options. +- If you use access tokens, ensure your host does not log them (events, transcripts, verbose output). + +:::: + +### Auth examples + +**A) Delegated auth (interactive) – host obtains token, provider consumes token** + +```powershell +# Host responsibility: +# Example with Microsoft Graph PowerShell (interactive sign-in) +Connect-MgGraph -Scopes 'User.ReadWrite.All','Group.ReadWrite.All' | Out-Null +$ctx = Get-MgContext + +# Provide a token supplier object so tokens can refresh +$tokenSupplier = [pscustomobject]@{ Context = $ctx } +$tokenSupplier | Add-Member -MemberType ScriptMethod -Name GetAccessToken -Value { + # NOTE: Replace this with your real token retrieval logic. + # In many hosts you would acquire tokens via MSAL / managed identity. + throw 'Implement token acquisition in the host.' +} + +$broker = [pscustomobject]@{} +$broker | Add-Member -MemberType ScriptMethod -Name AcquireAuthSession -Value { + param($Name, $Options) + return $tokenSupplier +} + +$providers = @{ + Identity = New-IdleEntraIDIdentityProvider + AuthSessionBroker = $broker +} + +# Steps use: +# With.AuthSessionName = 'MicrosoftGraph' +``` + +**B) App-only auth – host supplies a fixed token string (simple demo / lab)** + +```powershell +$accessToken = Get-MyGraphAppOnlyToken # host-managed (MSAL / managed identity / etc.) + +$broker = [pscustomobject]@{} +$broker | Add-Member -MemberType ScriptMethod -Name AcquireAuthSession -Value { + param($Name, $Options) + return $accessToken +} + +$providers = @{ + Identity = New-IdleEntraIDIdentityProvider + AuthSessionBroker = $broker +} +``` + +**C) Multi-tenant routing** + +```powershell +$tokenProd = Get-GraphToken -Tenant 'contoso.onmicrosoft.com' +$tokenLab = Get-GraphToken -Tenant 'contoso-lab.onmicrosoft.com' + +$broker = [pscustomobject]@{} +$broker | Add-Member -MemberType ScriptMethod -Name AcquireAuthSession -Value { + param($Name, $Options) + if ($Options.Tenant -eq 'Prod') { return $tokenProd } + if ($Options.Tenant -eq 'Lab') { return $tokenLab } + throw "Unknown tenant option: $($Options.Tenant)" +} + +# Steps use With.AuthSessionOptions = @{ Tenant = 'Prod' } etc. +``` + ## Required Microsoft Graph Permissions ### Delegated Permissions (User Context) diff --git a/docs/reference/providers/provider-exchangeonline.md b/docs/reference/providers/provider-exchangeonline.md new file mode 100644 index 00000000..e6b82b66 --- /dev/null +++ b/docs/reference/providers/provider-exchangeonline.md @@ -0,0 +1,205 @@ +--- +title: Provider Reference: IdLE.Provider.ExchangeOnline +sidebar_label: ExchangeOnline +--- + +> **Purpose:** This page is a **reference** for a specific provider implementation. +> Keep it factual and contract-oriented. Put conceptual explanations elsewhere and link to them. + +--- + +## Summary + +- **Provider name:** ExchangeOnline +- **Module:** `IdLE.Provider.ExchangeOnline` +- **Provider kind:** Messaging +- **Targets:** Exchange Online (ExchangeOnlineManagement cmdlets) +- **Status:** First-party (bundled) +- **Since:** 0.9.0 +- **Compatibility:** PowerShell 7+ (IdLE requirement) + +--- + +## What this provider does + +- **Primary responsibilities:** + - Read mailbox information (type, primary SMTP, UPN, GUID). + - Converge mailbox type (User/Shared/Room/Equipment). + - Converge Out of Office configuration. +- **Out of scope / non-goals:** + - Establishing an Exchange Online session (handled by the host/broker). + - Managing identity objects (use an identity provider such as AD or EntraID). + +--- + +## Contracts and capabilities + +### Contracts implemented + +| Contract | Used by steps for | Notes | +| --- | --- | --- | +| Mailbox provider (implicit) | Read mailbox info, ensure mailbox type, ensure Out of Office | Methods are exposed as script methods on the provider object. | + +### Capability advertisement (`GetCapabilities()`) + +- **Implements `GetCapabilities()`**: Yes +- **Capabilities returned (stable identifiers):** + - `IdLE.Mailbox.Info.Read` + - `IdLE.Mailbox.Type.Ensure` + - `IdLE.Mailbox.OutOfOffice.Ensure` + +--- + +## Authentication and session acquisition + +> Providers must not prompt for auth. Use the host-provided broker contract. + +- **Auth session name(s) requested via `Context.AcquireAuthSession(...)`:** + - Typically the step passes `With.AuthSessionName` (if present). For built-in mailbox steps, if `With.AuthSessionName` is absent, it defaults to the provider alias (commonly `ExchangeOnline`). +- **Session options (data-only):** + - The provider does not interpret options; they are used by the host/broker to select credentials/route to a tenant/session. + +:::warn + +**Security notes** + +- Do not pass secrets in workflow/provider options. +- Ensure token/credential objects are not emitted in events. + +::: + +### Auth examples + +**A) Delegated auth (interactive) – connect once in the host** + +```powershell +# Host responsibility: +Connect-ExchangeOnline -UserPrincipalName 'admin@contoso.com' + +$providers = @{ + ExchangeOnline = New-IdleExchangeOnlineProvider +} +``` + +**B) App-only (certificate) – connect once in the host** + +```powershell +# Host responsibility: +Connect-ExchangeOnline ` + -AppId '00000000-0000-0000-0000-000000000000' ` + -Organization 'contoso.onmicrosoft.com' ` + -CertificateThumbprint 'THUMBPRINT' + +$providers = @{ + ExchangeOnline = New-IdleExchangeOnlineProvider +} +``` + +**C) Multi-connection routing (advanced)** + +If you need **multiple** Exchange Online sessions (e.g., multiple tenants), implement a custom +`AuthSessionBroker` that returns an **AuthSession** object understood by your host (for example, +an object that selects the right connection context before invoking cmdlets). The provider itself +does not create or own sessions. + +--- + +## Configuration + +### Provider constructor / factory + +- **Public constructor cmdlet(s):** + - `New-IdleExchangeOnlineProvider` — creates an Exchange Online mailbox provider. + +**Parameters (high signal only)** + +- `-Adapter ` — dependency injection hook for tests (optional). + +> Do not copy full comment-based help here. Link to the cmdlet reference. + +### Provider bag / alias usage + +```powershell +$providers = @{ + ExchangeOnline = (New-IdleExchangeOnlineProvider) +} +``` + +- **Recommended alias pattern:** `ExchangeOnline` (or role-based, e.g. `Messaging`) +- **Default alias expected by built-in steps (if any):** `ExchangeOnline` (Mailbox steps default to this when `With.Provider` is not provided) + +--- + +## Provider-specific options reference + +This provider has no dedicated data-only `-Options` surface. Session selection is done via: + +- `With.AuthSessionName` +- `With.AuthSessionOptions` (data-only hashtable, validated by the engine/steps) + +--- + +## Operational behavior + +### Idempotency and consistency + +- **Idempotent operations:** Yes (for `Ensure*` methods; no-op when already in desired state) +- **Consistency model:** Depends on Exchange Online / service latency +- **Concurrency notes:** Exchange Online can throttle; retries are delegated to the host/workflow design. + +### Error mapping and retry behavior + +- **Common error categories:** NotFound, PermissionDenied, Throttled +- **Retry strategy:** None in the provider (delegate retries/backoff to the host if needed) + +--- + +## Observability + +- **Events emitted by provider (if any):** None (steps emit events via the execution context). +- **Sensitive data redaction:** IdLE redacts secrets at output boundaries; providers should avoid returning secret material. + +--- + +## Examples + +### Minimal host usage + +```powershell +# 1) Create provider instance +$provider = New-IdleExchangeOnlineProvider + +# 2) Build provider map +$providers = @{ ExchangeOnline = $provider } + +# 3) Plan + execute +$plan = New-IdlePlan -WorkflowPath -Request -Providers $providers +$result = Invoke-IdlePlan -Plan $plan -Providers $providers +``` + +### Example workflow snippet + +```powershell +@{ + Steps = @( + @{ + Name = 'Ensure mailbox type' + Type = 'IdLE.Step.MailboxType.Ensure' + With = @{ + Provider = 'ExchangeOnline' + IdentityKey = 'user@contoso.com' + Type = 'Shared' + # AuthSessionName is optional; defaults to the provider alias if omitted + # AuthSessionOptions = @{ ... } + } + } + ) +} +``` + +--- + +## Limitations and known issues + +- Requires the `ExchangeOnlineManagement` PowerShell module at runtime. +- The host must establish or broker a usable Exchange Online session; the provider does not connect interactively. diff --git a/docs/reference/providers/provider-mock.md b/docs/reference/providers/provider-mock.md new file mode 100644 index 00000000..5d9eeb06 --- /dev/null +++ b/docs/reference/providers/provider-mock.md @@ -0,0 +1,180 @@ +--- +title: Provider Reference: IdLE.Provider.Mock +sidebar_label: Mock +--- + +> **Purpose:** This page is a **reference** for a specific provider implementation. +> Keep it factual and contract-oriented. Put conceptual explanations elsewhere and link to them. + +--- + +## Summary + +- **Provider name:** MockIdentity +- **Module:** `IdLE.Provider.Mock` +- **Provider kind:** Identity + Entitlement +- **Targets:** In-memory store (tests/demos) +- **Status:** First-party (bundled) +- **Since:** 0.9.0 +- **Compatibility:** PowerShell 7+ (IdLE requirement) + +--- + +## What this provider does + +- **Primary responsibilities:** + - Provide deterministic, in-memory identity operations for tests and examples. + - Converge identity attributes. + - List, grant and revoke entitlements (in-memory). + - Avoid any external dependencies and avoid global state. +- **Out of scope / non-goals:** + - Any live system integration. + - Authentication and session handling. + +--- + +## Contracts and capabilities + +### Contracts implemented + +| Contract | Used by steps for | Notes | +| --- | --- | --- | +| Identity provider (implicit) | Read identities and ensure attributes | Creates missing identities on demand to keep demos frictionless. | +| Entitlement provider (implicit) | List/grant/revoke entitlements | Entitlements are normalized to `{ Kind; Id; DisplayName? }` and compared case-insensitively by `Id`. | + +### Capability advertisement (`GetCapabilities()`) + +- **Implements `GetCapabilities()`**: Yes +- **Capabilities returned (stable identifiers):** + - `IdLE.Identity.Read` + - `IdLE.Identity.Attribute.Ensure` + - `IdLE.Identity.Disable` + - `IdLE.Entitlement.List` + - `IdLE.Entitlement.Grant` + - `IdLE.Entitlement.Revoke` + +--- + +## Authentication and session acquisition + +This provider does not require authentication. + +:::warn + +**Security notes** + +- Even in tests, do not embed real secrets into workflow files or fixtures. + +::: + +### Auth examples + +This provider does not require authentication. + +```powershell +$providers = @{ + Identity = New-IdleMockIdentityProvider +} +``` + +--- + +## Configuration + +### Provider constructor / factory + +- **Public constructor cmdlet(s):** + - `New-IdleMockIdentityProvider` — creates an isolated in-memory provider instance. + +**Parameters (high signal only)** + +- `-InitialStore ` — optional initial content, shallow-copied into the provider store. + +### Provider bag / alias usage + +```powershell +$provider = New-IdleMockIdentityProvider + +$providers = @{ + Identity = $provider +} +``` + +- **Recommended alias pattern:** `Identity` +- **Default alias expected by built-in steps (if any):** `Identity` + +--- + +## Provider-specific options reference + +This provider has no additional data-only option keys beyond its constructor parameters. + +--- + +## Operational behavior + +### Idempotency and consistency + +- **Idempotent operations:** Partial + - `EnsureAttribute` is idempotent (returns `Changed = $false` when already converged). + - `DisableIdentity` is idempotent. + - Entitlement grant/revoke are idempotent by Kind+Id. + - `GetIdentity` creates missing identities on demand (test convenience). +- **Consistency model:** Strong (in-memory) +- **Concurrency notes:** Not designed for concurrent mutation across threads/runspaces. + +### Error mapping and retry behavior + +- **Common error categories:** input validation errors (e.g., missing entitlement id) +- **Retry strategy:** none (deterministic, in-memory) + +--- + +## Observability + +- **Events emitted by provider (if any):** none +- **Sensitive data redaction:** not applicable (no auth material handled) + +--- + +## Examples + +### Minimal host usage + +```powershell +# 1) Create provider instance +$provider = New-IdleMockIdentityProvider + +# 2) Build provider map +$providers = @{ Identity = $provider } + +# 3) Plan + execute +$plan = New-IdlePlan -WorkflowPath -Request -Providers $providers +$result = Invoke-IdlePlan -Plan $plan -Providers $providers +``` + +### Example workflow snippet + +```powershell +@{ + Steps = @( + @{ + Name = 'Ensure department' + Type = 'IdLE.Step.EnsureAttribute' + With = @{ + Provider = 'Identity' + IdentityKey = 'user1' + Name = 'Department' + Value = 'IT' + } + } + ) +} +``` + +--- + +## Limitations and known issues + +- Designed for tests and examples only. +- `GetIdentity` auto-creates missing identities, which may hide "NotFound" scenarios unless tests seed the store explicitly. diff --git a/website/sidebars.js b/website/sidebars.js index 68016044..74caf84b 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -99,6 +99,9 @@ const sidebars = { items: [ 'reference/providers/provider-ad', 'reference/providers/provider-entraID', + 'reference/providers/provider-directorysync-entraconnect', + 'reference/providers/provider-exchangeonline', + 'reference/providers/provider-mock', ], }, 'reference/capabilities', From edc069ed34b645213a895d83f122a9f251f600d5 Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 17:49:17 +0100 Subject: [PATCH 17/28] fixed links in provider reference index --- docs/reference/providers.md | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/docs/reference/providers.md b/docs/reference/providers.md index 5916fc83..48429742 100644 --- a/docs/reference/providers.md +++ b/docs/reference/providers.md @@ -12,7 +12,7 @@ sidebar_label: Providers - **[Active Directory (AD)](providers/provider-ad.md)** — Identity operations against on-prem AD via the AD provider module - **[Entra ID](providers/provider-entraID.md)** — Identity operations against Microsoft Entra ID via Microsoft Graph - **[Exchange Online](providers/provider-exchangeonline.md)** — Messaging / mailbox related operations against Exchange Online -- **[DirectorySync.EntraConnect](providers/provider-directorysync-EntraConnect.md)** — Directory synchronization provider for Entra Connect / sync-cycle related operations +- **[DirectorySync.EntraConnect](providers/provider-directorysync-entraconnect.md)** — Directory synchronization provider for Entra Connect / sync-cycle related operations - **[Mock Provider](providers/provider-mock.md)** — In-memory / file-backed provider for tests and local development without live systems --- @@ -25,9 +25,9 @@ sidebar_label: Providers Related: -- [Capabilities Reference](../capabilities.md) -- [Provider fundamentals (concept)](../../about/concepts.md#providers) -- [Use Providers](../../use/providers.md) +- [Capabilities Reference](capabilities.md) +- [Provider fundamentals (concept)](../about/concepts.md#providers) +- [Use Providers](../use/providers.md) --- @@ -38,9 +38,3 @@ Related: - Advertise deterministic capabilities (`GetCapabilities()`) - Acquire sessions via host context (no prompts inside providers) - Add unit tests + contract tests (no live calls in CI) - -Related: - -- [Extensibility](../../extend/extensibility.md) -- Testing: `../advanced/testing.md` -- [Security considerations](../../about/security.md) From 0bd9cd6bce291f049bf2a13446cd9ad33d65347f Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 17:51:58 +0100 Subject: [PATCH 18/28] removed duplicate entry --- tools/Generate-IdleStepReference.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/Generate-IdleStepReference.ps1 b/tools/Generate-IdleStepReference.ps1 index 78ee6dfc..6a999277 100644 --- a/tools/Generate-IdleStepReference.ps1 +++ b/tools/Generate-IdleStepReference.ps1 @@ -617,6 +617,5 @@ if ($CleanObsoleteDetailPages) { $indexContent = New-IdleStepsIndexPageContent -Models $models Set-Content -Path $OutputPath -Value $indexContent -Encoding utf8 -NoNewline -$generatedFile = Get-Item -Path $OutputPath $generatedFile = Get-Item -Path $OutputPath "Generated`n`tStep reference index: $($generatedFile.FullName) ($($generatedFile.Length) bytes)`n`tDetail pages: $($models.Count) in '$DetailOutputDirectory'" From b3cb6ca7ae2143a234e25f04d51e681b411d7af1 Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 17:54:25 +0100 Subject: [PATCH 19/28] fixed titles --- docs/reference/providers/provider-ad.md | 2 +- docs/reference/providers/provider-directorysync-entraconnect.md | 2 +- docs/reference/providers/provider-entraID.md | 2 +- docs/reference/providers/provider-exchangeonline.md | 2 +- docs/reference/providers/provider-mock.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/reference/providers/provider-ad.md b/docs/reference/providers/provider-ad.md index 269dbe64..e1e065d6 100644 --- a/docs/reference/providers/provider-ad.md +++ b/docs/reference/providers/provider-ad.md @@ -1,5 +1,5 @@ --- -title: IdLE.Provider.AD - Active Directory Provider +title: Provider Reference - IdLE.Provider.AD (Active Directory) sidebar_label: Active Directory --- diff --git a/docs/reference/providers/provider-directorysync-entraconnect.md b/docs/reference/providers/provider-directorysync-entraconnect.md index 31644faa..78a7f3b9 100644 --- a/docs/reference/providers/provider-directorysync-entraconnect.md +++ b/docs/reference/providers/provider-directorysync-entraconnect.md @@ -1,5 +1,5 @@ --- -title: Provider Reference: IdLE.Provider.DirectorySync.EntraConnect +title: Provider Reference - IdLE.Provider.DirectorySync.EntraConnect sidebar_label: DirectorySync.EntraConnect --- diff --git a/docs/reference/providers/provider-entraID.md b/docs/reference/providers/provider-entraID.md index 8f401676..1676fbd9 100644 --- a/docs/reference/providers/provider-entraID.md +++ b/docs/reference/providers/provider-entraID.md @@ -1,5 +1,5 @@ --- -title: IdLE.Provider.EntraID Reference +title: Provider Reference - IdLE.Provider.EntraID sidebar_label: Entra ID --- diff --git a/docs/reference/providers/provider-exchangeonline.md b/docs/reference/providers/provider-exchangeonline.md index e6b82b66..c2657b43 100644 --- a/docs/reference/providers/provider-exchangeonline.md +++ b/docs/reference/providers/provider-exchangeonline.md @@ -1,5 +1,5 @@ --- -title: Provider Reference: IdLE.Provider.ExchangeOnline +title: Provider Reference - IdLE.Provider.ExchangeOnline sidebar_label: ExchangeOnline --- diff --git a/docs/reference/providers/provider-mock.md b/docs/reference/providers/provider-mock.md index 5d9eeb06..837ab11a 100644 --- a/docs/reference/providers/provider-mock.md +++ b/docs/reference/providers/provider-mock.md @@ -1,5 +1,5 @@ --- -title: Provider Reference: IdLE.Provider.Mock +title: Provider Reference . IdLE.Provider.Mock sidebar_label: Mock --- From b485ff505a76a1ed3b10ded33e31ef9bc7305281 Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 17:54:32 +0100 Subject: [PATCH 20/28] removed de locale generation --- website/docusaurus.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 3be5a9bd..34604909 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -41,7 +41,7 @@ const config = { // may want to replace "en" with "zh-Hans". i18n: { defaultLocale: 'en', - locales: ['en','de'], + locales: ['en'], }, presets: [ From ca609bf3ec6d19c729815ec55c294c1d9a525b0c Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 17:57:44 +0100 Subject: [PATCH 21/28] fixed warning typo for callout --- docs/reference/providers/_provider-name_template.md | 2 +- docs/reference/providers/provider-ad.md | 4 +--- .../providers/provider-directorysync-entraconnect.md | 2 +- docs/reference/providers/provider-entraID.md | 2 +- docs/reference/providers/provider-exchangeonline.md | 2 +- docs/reference/providers/provider-mock.md | 2 +- 6 files changed, 6 insertions(+), 8 deletions(-) diff --git a/docs/reference/providers/_provider-name_template.md b/docs/reference/providers/_provider-name_template.md index 57def241..9b119a30 100644 --- a/docs/reference/providers/_provider-name_template.md +++ b/docs/reference/providers/_provider-name_template.md @@ -60,7 +60,7 @@ List the IdLE provider contracts this provider implements and what they mean at - **Session options (data-only):** - ``: `` — `` (optional default: `<...>`) -:::warn +:::warning **Security notes** diff --git a/docs/reference/providers/provider-ad.md b/docs/reference/providers/provider-ad.md index e1e065d6..bc525e16 100644 --- a/docs/reference/providers/provider-ad.md +++ b/docs/reference/providers/provider-ad.md @@ -86,8 +86,6 @@ This makes `New-IdleADIdentityProvider` available in your session. --- - - ## Authentication and session acquisition > Providers must not prompt for auth. Use the host-provided broker contract. @@ -98,7 +96,7 @@ This makes `New-IdleADIdentityProvider` available in your session. - `PSCredential` (used for AD cmdlets `-Credential`) - **Session options (data-only):** Any hashtable; commonly `@{ Role = 'Tier0' }` / `@{ Role = 'Admin' }` -:::warn +:::warning **Security notes** diff --git a/docs/reference/providers/provider-directorysync-entraconnect.md b/docs/reference/providers/provider-directorysync-entraconnect.md index 78a7f3b9..0d42b067 100644 --- a/docs/reference/providers/provider-directorysync-entraconnect.md +++ b/docs/reference/providers/provider-directorysync-entraconnect.md @@ -64,7 +64,7 @@ and pass it to provider methods. - **Session options (data-only):** - Forwarded to the host broker for session selection (provider does not interpret option keys). -:::warn +:::warning **Security notes** diff --git a/docs/reference/providers/provider-entraID.md b/docs/reference/providers/provider-entraID.md index 1676fbd9..a12a80be 100644 --- a/docs/reference/providers/provider-entraID.md +++ b/docs/reference/providers/provider-entraID.md @@ -107,7 +107,7 @@ $broker = New-IdleAuthSession -SessionMap @{ - `PSCredential` (token stored in password field; username is ignored) - **Session options (data-only):** Any hashtable; common keys: `Role`, `Tenant`, `Environment` -:::warn +:::warning **Security notes** diff --git a/docs/reference/providers/provider-exchangeonline.md b/docs/reference/providers/provider-exchangeonline.md index c2657b43..82f6eb48 100644 --- a/docs/reference/providers/provider-exchangeonline.md +++ b/docs/reference/providers/provider-exchangeonline.md @@ -59,7 +59,7 @@ sidebar_label: ExchangeOnline - **Session options (data-only):** - The provider does not interpret options; they are used by the host/broker to select credentials/route to a tenant/session. -:::warn +:::warning **Security notes** diff --git a/docs/reference/providers/provider-mock.md b/docs/reference/providers/provider-mock.md index 837ab11a..3692023b 100644 --- a/docs/reference/providers/provider-mock.md +++ b/docs/reference/providers/provider-mock.md @@ -59,7 +59,7 @@ sidebar_label: Mock This provider does not require authentication. -:::warn +:::warning **Security notes** From cdc4d978b097f98927c69fe32fdc775ac705d761 Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 17:59:46 +0100 Subject: [PATCH 22/28] removed pages to be revised for extend section --- docs/extend/intro.md | 7 ------- website/sidebars.js | 6 +++--- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/docs/extend/intro.md b/docs/extend/intro.md index b137164e..b38f401c 100644 --- a/docs/extend/intro.md +++ b/docs/extend/intro.md @@ -22,13 +22,6 @@ It is written for people who want to add or customize functionality, for example - Authentication and session handling - Testing approaches (unit tests, contract tests) -## Where to continue? - -1. [Extensibility](extensibility.md) -2. [Providers](providers.md) -3. [Steps](steps.md) -4. [Events](events.md) - ## Not the right section? If you want to run workflows as an operator/admin, go to [Use Idle](../use/intro.md) instead. diff --git a/website/sidebars.js b/website/sidebars.js index 74caf84b..5d79ddf8 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -46,10 +46,10 @@ const sidebars = { items: [ 'extend/intro', 'extend/extensibility', - 'extend/providers', - 'extend/steps', - 'extend/events', // Add later if/when you create them: + // 'extend/providers', + // 'extend/steps', + // 'extend/events', // 'extend/auth-sessions', // 'extend/testing', ], From 568ca0009f16325736915710f52dbc89d674a55a Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 18:04:47 +0100 Subject: [PATCH 23/28] fixed warning on onBrokenMarkdownLinks - moved to "markdown" section --- website/docusaurus.config.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 34604909..04764a74 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -34,8 +34,7 @@ const config = { projectName: repoName, // Usually your repo name. onBrokenLinks: 'warn', - onBrokenMarkdownLinks: 'warn', - + // Even if you don't use internationalization, you can use this field to set // useful metadata like html lang. For example, if your site is Chinese, you // may want to replace "en" with "zh-Hans". @@ -184,6 +183,12 @@ const config = { // If you enable Mermaid theme above, also enable markdown mermaid: // markdown: { mermaid: true }, + markdown: { + hooks: { + onBrokenMarkdownLinks: 'warn', + onBrokenMarkdownImages: 'warn', + } + }, }; module.exports = config; From af9fb91a822fa7045538308fee1a3403a3e8c5a1 Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 18:05:38 +0100 Subject: [PATCH 24/28] fixed callout box end typo --- docs/reference/providers/provider-ad.md | 2 +- docs/reference/providers/provider-entraID.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/reference/providers/provider-ad.md b/docs/reference/providers/provider-ad.md index bc525e16..7b23467a 100644 --- a/docs/reference/providers/provider-ad.md +++ b/docs/reference/providers/provider-ad.md @@ -103,7 +103,7 @@ This makes `New-IdleADIdentityProvider` available in your session. - Do not pass secrets in workflow files or provider options. - Make sure your host does not emit credential objects (or their secure strings) in logs/events. -:::: +::: ### Auth examples diff --git a/docs/reference/providers/provider-entraID.md b/docs/reference/providers/provider-entraID.md index a12a80be..cc064b27 100644 --- a/docs/reference/providers/provider-entraID.md +++ b/docs/reference/providers/provider-entraID.md @@ -114,7 +114,7 @@ $broker = New-IdleAuthSession -SessionMap @{ - Do not pass secrets in workflow files or provider options. - If you use access tokens, ensure your host does not log them (events, transcripts, verbose output). -:::: +::: ### Auth examples From 1582a3eb327e13a43e7dc382227ddfdef8743821 Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 18:09:58 +0100 Subject: [PATCH 25/28] excluded template page from docusaurus --- website/docusaurus.config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 04764a74..f21ea565 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -58,6 +58,7 @@ const config = { editUrl: `https://github.com/${repoOwner}/${repoName}/edit/main/`, exclude: [ '**/develop/**', + '_*template.md', '**/index.md', 'index.md'], }, From 4431a1477d51f153e9d17ea9578d6389be1c559e Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 18:11:50 +0100 Subject: [PATCH 26/28] fixed auth session handling in providers index description --- docs/reference/providers.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/reference/providers.md b/docs/reference/providers.md index 48429742..894d95ba 100644 --- a/docs/reference/providers.md +++ b/docs/reference/providers.md @@ -20,7 +20,7 @@ sidebar_label: Providers ## Choosing a provider - Match the **capabilities required by your steps** to the provider’s `GetCapabilities()` output. -- Providers handle authentication/session acquisition via `Context.AcquireAuthSession(...)` (host-controlled). +- Steps acquire auth sessions via `Context.AcquireAuthSession(...)` and pass them to provider methods that accept an optional `AuthSession` parameter (host-controlled). - In workflows, steps select a provider by **alias** (defaults to `Identity` if omitted). Related: @@ -33,8 +33,9 @@ Related: ## Authoring a provider (for developers) -- Minimal checklist: - - Implement provider contracts (only what you need) - - Advertise deterministic capabilities (`GetCapabilities()`) - - Acquire sessions via host context (no prompts inside providers) - - Add unit tests + contract tests (no live calls in CI) +Minimal checklist: + +- Implement provider contracts (only what you need) +- Advertise deterministic capabilities (`GetCapabilities()`) +- Accept optional `AuthSession` parameter in methods that require authentication (sessions acquired by steps via host context; no prompts inside providers) +- Add unit tests + contract tests (no live calls in CI) From 190e0981e72ed1ca1653114e22f970c2aade012c Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 18:15:59 +0100 Subject: [PATCH 27/28] fixed title typo --- docs/reference/providers/provider-mock.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/providers/provider-mock.md b/docs/reference/providers/provider-mock.md index 3692023b..2bfe82a5 100644 --- a/docs/reference/providers/provider-mock.md +++ b/docs/reference/providers/provider-mock.md @@ -1,5 +1,5 @@ --- -title: Provider Reference . IdLE.Provider.Mock +title: Provider Reference - IdLE.Provider.Mock sidebar_label: Mock --- From c5f9e42254aa714a3fc228fdbff864632133a301 Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sun, 1 Feb 2026 18:17:54 +0100 Subject: [PATCH 28/28] changed intro names to avoid duplication issues --- README.md | 4 ++-- docs/extend/{intro.md => intro-extend.md} | 2 +- docs/index.md | 6 +++--- docs/reference/{intro.md => intro-reference.md} | 4 ++-- docs/use/{intro.md => intro-use.md} | 2 +- website/sidebars.js | 6 +++--- 6 files changed, 12 insertions(+), 12 deletions(-) rename docs/extend/{intro.md => intro-extend.md} (95%) rename docs/reference/{intro.md => intro-reference.md} (87%) rename docs/use/{intro.md => intro-use.md} (92%) diff --git a/README.md b/README.md index f243b90d..ad6680e1 100644 --- a/README.md +++ b/README.md @@ -90,8 +90,8 @@ Start here: - [docs/index.md](docs/index.md) – Documentation map - [docs/about/intro.md](docs/about/intro.md) – About IdLE -- [docs/use/intro.md](docs/use/intro.md) – How to use IdLE -- [docs/reference/intro.md](docs/reference/intro.md) - The authoritative IdLE reference +- [docs/use/intro-use.md](docs/use/intro-use.md) – How to use IdLE +- [docs/reference/intro-reference.md](docs/reference/intro-reference.md) - The authoritative IdLE reference --- diff --git a/docs/extend/intro.md b/docs/extend/intro-extend.md similarity index 95% rename from docs/extend/intro.md rename to docs/extend/intro-extend.md index b38f401c..3f162cae 100644 --- a/docs/extend/intro.md +++ b/docs/extend/intro-extend.md @@ -24,4 +24,4 @@ It is written for people who want to add or customize functionality, for example ## Not the right section? -If you want to run workflows as an operator/admin, go to [Use Idle](../use/intro.md) instead. +If you want to run workflows as an operator/admin, go to [Use Idle](../use/intro-use.md) instead. diff --git a/docs/index.md b/docs/index.md index a0427157..4180ec71 100644 --- a/docs/index.md +++ b/docs/index.md @@ -20,7 +20,7 @@ Learn the basics [about IdLE](about/intro.md) ## Use IdLE -Learn how to [use IdLE](use/intro.md) as an operator or admin, e.g. for workflow authoring. +Learn how to [use IdLE](use/intro-use.md) as an operator or admin, e.g. for workflow authoring. - [Quickstart](use/quickstart.md) - Run the demo and understand Plan → Execute flow - [Installation](use/installation.md) - Install and import guide (requirements, import options) @@ -30,7 +30,7 @@ Learn how to [use IdLE](use/intro.md) as an operator or admin, e.g. for workflow ## Extend IdLE -Learn how to [extend IdLE](extend/intro.md) as a developer. +Learn how to [extend IdLE](extend/intro-extend.md) as a developer. - [Extensibility](extend/extensibility.md) - General extensibility concept of IdLE - [Events](extend/events.md) - Eventing at IdLE to be used in your extensions @@ -38,7 +38,7 @@ Learn how to [extend IdLE](extend/intro.md) as a developer. ## Reference -The [authoritative reference](reference/intro.md) for IdLE components. +The [authoritative reference](reference/intro-reference.md) for IdLE components. - [Cmdlet Reference](reference/cmdlets.md) - [Provider Reference](reference/providers.md) diff --git a/docs/reference/intro.md b/docs/reference/intro-reference.md similarity index 87% rename from docs/reference/intro.md rename to docs/reference/intro-reference.md index 2655ed46..8f1ecd23 100644 --- a/docs/reference/intro.md +++ b/docs/reference/intro-reference.md @@ -6,8 +6,8 @@ sidebar_label: Reference This section is the **authoritative reference** for IdLE. It contains precise, stable and normative information intended for lookup and verification. -Content here is not tutorial-style and usually assumes prior knowledge from the **[Use](../use/intro.md)** or -**[Extend](../extend/intro.md)** sections. +Content here is not tutorial-style and usually assumes prior knowledge from the **[Use](../use/intro-use.md)** or +**[Extend](../extend/intro-extend.md)** sections. ## How to use this section diff --git a/docs/use/intro.md b/docs/use/intro-use.md similarity index 92% rename from docs/use/intro.md rename to docs/use/intro-use.md index a3719add..4b25fb08 100644 --- a/docs/use/intro.md +++ b/docs/use/intro-use.md @@ -18,4 +18,4 @@ with one or more providers. - Executing workflow plans - Troubleshooting common issues -If you want to extend IdLE and implement providers or steps, go to [Extend](../extend/intro.md) instead. +If you want to extend IdLE and implement providers or steps, go to [Extend](../extend/intro-extend.md) instead. diff --git a/website/sidebars.js b/website/sidebars.js index 5d79ddf8..d29c613f 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -31,7 +31,7 @@ const sidebars = { label: 'Use IdLE', collapsed: false, items: [ - 'use/intro', + 'use/intro-use', 'use/installation', 'use/quickstart', 'use/workflows', @@ -44,7 +44,7 @@ const sidebars = { label: 'Extend IdLE', collapsed: false, items: [ - 'extend/intro', + 'extend/intro-extend', 'extend/extensibility', // Add later if/when you create them: // 'extend/providers', @@ -59,7 +59,7 @@ const sidebars = { label: 'Reference', collapsed: true, items: [ - 'reference/intro', + 'reference/intro-reference', 'reference/cmdlets', { type: 'category',