This guide covers how to create and validate lessons for the SPE interactive tutorial.
Each lesson is a YAML file with metadata and a tasks array. Each task has:
- instruction: | # What the user should do (markdown, required) hint: | # Full answer shown after 4 failed attempts (required) nudge: | # Gentle hint shown after 2 failed attempts (optional) starterCode: | # Pre-filled editor content for ise/builder mode (optional) validation: # How completion is determined (required) successMessage: | # Explanation shown on success (optional) builderConfig: # Visual builder config, builder mode only (optional)
Checks cmdlet name, resolved path (by node ID), and switches. Best for single-cmdlet tasks teaching navigation.
validation: type: structural cmdlet: get-item requirePath: - "master:\\content\\Home" - "master:/content/Home" - "master:\\Content\\Home" requireSwitches: - recurse requireParams: Name: "Contact Us" ItemType: "Sample/Sample Item"
Fields:
cmdlet(required) — lowercase cmdlet name (e.g.get-childitem)requirePath(optional) — array of path variants; resolved to node IDs for comparisonrequireSwitches(optional) — array of switch names without the dash prefixrequireParams(optional) — map of parameter name → expected value (case-insensitive key lookup, exact value match)
Path arrays should include multiple format variants (backslash, forward-slash, lowercase) since the validator resolves them to node IDs.
Error cascade: wrong cmdlet → invalid path → wrong path → missing switch → missing/wrong param
Checks that required cmdlets appear anywhere in the pipeline (alias-aware), then optionally runs the script to verify output.
validation: type: pipeline stages: - get-childitem - where-object - select-object outputContains: "Sample Item" outputNotContains: "Folder"
# With parameter checking across multi-command scripts validation: type: pipeline stages: - new-item - get-childitem requireParams: Name: "Contact Us" ItemType: "Sample/Sample Item" outputContains: "Contact Us"
Fields:
stages(required) — array of lowercase cmdlet names checked across ALL statementsrequireParams(optional) — map of parameter name → expected value; matched against ANY stage across all statements (case-insensitive key lookup, exact value match)outputContains(optional) — string that must appear in execution outputoutputNotContains(optional) — string that must NOT appear in execution output
Aliases are accepted: gci matches get-childitem, ? matches where-object, etc.
Error cascade: missing stage → missing/wrong param → wrong output → filter too broad
Runs the script and checks output strings. Best for run-and-observe tasks where the starterCode is complete.
validation: type: output outputContains: "Report" outputNotContains: "Error"
Fields:
outputContains(optional) — string that must appear in execution outputoutputNotContains(optional) — string that must NOT appear in execution output
Use for: Tasks with complete starterCode where the user runs pre-written code to observe behavior.
Error cascade: output mismatch
Set via the lesson-level mode field:
repl(default) — Single-line console. No starterCode. User types commands from scratch.ise— Multi-line editor. StarterCode can be partial (user completes it) or complete (user runs and observes).builder— Visual drag-and-drop pipeline builder. UsesbuilderConfigfor available cmdlets and locked prefilled stages.
| Scenario | Message |
|---|---|
| Wrong cmdlet | "Try using Get-Item for this task." |
| Invalid path | "The path you specified doesn't resolve to a valid item. Check your path." |
| Wrong path | "Your command resolved to the wrong item. Check your path." |
| Missing switch | "Don't forget the -Recurse switch." |
| Missing param (structural) | "Don't forget the -Name parameter." |
| Wrong param value (structural) | "The -Name parameter value doesn't match what's expected." |
| Missing pipeline stage | "Your script should include Where-Object." |
| Missing param (pipeline) | "Your script should include -Name "Contact Us"." |
| Wrong output (pipeline) | "Your script runs, but the output doesn't match what's expected. Check your filter criteria." |
| Filter too broad | "Your filter isn't specific enough — unwanted items are getting through." |
| Wrong output (output) | "Your script runs, but the output doesn't match what's expected. Check your code." |
| User Attempts | UI Behavior |
|---|---|
| 0–1 | No hints available |
| 2–3 | "Show Hint" button → displays nudge (gentle guidance) |
| 4+ | "Show Answer" button → displays hint (full solution as code block) |
- Accept equivalent input — paths compared by node ID, cmdlets accept aliases, extra params ignored
- Progressive feedback —
partial[]shows checkmarks for correct parts - Guide without revealing — error messages point to the problem area, never show the answer
- Validate intent, not syntax — "did they use the right tool on the right target?"
- Every task has
instruction,hint, andvalidation - Path arrays include multiple format variants (backslash, forward-slash, lowercase)
-
outputContainsuses a string unique to the correct output -
outputNotContainscatches the most common wrong answer -
successMessageexplains the "why" or teaches a concept - ISE tasks have
starterCode(partial for learning, complete for observation) - Builder tasks have
builderConfigwithavailableCmdletsand anyprefilledlocked stages -
nudgeprovides directional guidance without giving the answer -
hintprovides the complete working command/script