{"owner":"PowerShell","repo":"powershell","hasSkills":true,"totalSkillsCount":25,"totalTokensCount":13859,"categories":["anthropic-skill","subagent-persona","plugin-manifest"],"hasMcp":false,"mcpConfig":null,"found":[".github/skills/analyze-pester-failures/SKILL.md","test/tools/TestMetadata.json","tools/metadata.json","tools/install-powershell.sh-README.md","tools/findMissingNotices.targets.json",".github/agents/SplitADOPipelines.agent.md","tools/guardian/tsaconfig-apiscan.json","tools/credScan/suppress.json","tools/guardian/tsaconfig-others.json","tools/AttackSurfaceAnalyzer/README.md","tools/install-powershell.ps1-README.md","tools/clearlyDefined/readme.md","tools/packages.microsoft.com/mapping.json","tools/performance/README.md","test/perf/dotnet-tools/README.md","test/tools/CodeCoverageAutomation/README.md","test/tools/WebListener/README.md","test/tools/WebListener/appsettings.Development.json","test/tools/WebListener/appsettings.json","tools/cgmanifest/main/cgmanifest.json","tools/cgmanifest/tpn/cgmanifest.json",".github/skills/analyze-pester-failures/references/stack-trace-parsing.md","test/perf/dotnet-tools/ResultsComparer/README.md","test/tools/Modules/UnixSocket/README.md","test/tools/Modules/WebListener/README.md"],"skills":{".github/skills/analyze-pester-failures/SKILL.md":"---\nname: analyze-pester-failures\ndescription: Troubleshooting guide for analyzing and investigating Pester test failures in PowerShell CI jobs. Help agents understand why tests are failing, interpret test output, navigate test result artifacts, and provide actionable recommendations for fixing test issues.\n---\n\n# Analyze Pester Test Failures\n\nInvestigate and troubleshoot Pester test failures in GitHub Actions workflows. Understand what tests are failing, why they're failing, and provide recommendations for test fixes.\n\n| Skill | When to Use |\n|-------|-----------|\n| analyze-pester-failures | When investigating why Pester tests are failing in a CI job. Use when a test job shows failures and you need to understand what test failed, why it failed, what the error message means, and what might need to be fixed. Also use when asked: \"why did this test fail?\", \"what's the test error?\", \"test is broken\", \"test failure analysis\", \"debug test failure\", or given test failure logs and stack traces. |\n\n## When to Use This Skill\n\nUse this skill when you need to:\n\n- Understand why a specific Pester test is failing  \n- Interpret test failure messages and error output\n- Analyze test result data from CI workflow runs (XML, logs, stack traces)\n- Identify the root cause of test failures (test logic, assertion failure, exception, timeout, skip/ignore reason)\n- Provide recommendations for fixing failing tests\n- Compare expected vs. actual test behavior\n- Debug test environment issues (missing dependencies, configuration problems)\n- Understand test skip/ignored/inconclusive status reasons\n\n**Do not use this skill for:**\n- General PowerShell debugging unrelated to tests\n- Test infrastructure/CI setup issues (except as they affect test failure interpretation)\n- Performance analysis or benchmarking (that's a different investigation)\n\n## Quick Start\n\n### ⚠️ CRITICAL: The Workflow Must Be Followed IN ORDER\n\nThis skill describes a **sequential 6-step analysis workflow**. Skipping steps or jumping around leads to **incomplete analysis and incorrect conclusions**.\n\n**The Problem**: It's easy to skip to Step 4 or 5 without doing Steps 1-2, resulting in missing data and bad conclusions.\n\n**The Solution**: Use the automated analysis script to enforce the workflow:\n\n```powershell\n# Automatically runs Steps 1-6 in order, preventing skipping\n./.github/skills/analyze-pester-failures/scripts/analyze-pr-test-failures.ps1 -PR <PR_NUMBER>\n\n# Example:\n./.github/skills/analyze-pester-failures/scripts/analyze-pr-test-failures.ps1 -PR 26800\n```\n\nThis script:\n1. ✓ Fetches PR status automatically\n2. ✓ Downloads artifacts (can't skip, depends on Step 1)\n3. ✓ Extracts failures (can't skip, depends on Step 2)\n4. ✓ Analyzes error messages\n5. ✓ Documents context\n6. ✓ Generates recommendations\n\n**Only use the manual commands below if you fully understand the workflow.**\n\n### Manual Workflow (for reference)\n\n```powershell\n# Step 1: Identify the failing job\ngh pr view <PR_NUMBER> --json 'statusCheckRollup' | ConvertFrom-Json | Where-Object { $_.conclusion -eq 'FAILURE' }\n\n# Step 2: Download artifacts (extract RUN_ID from Step 1)\ngh run download <RUN_ID> --dir ./artifacts\ngh run view <RUN_ID> --log > test-logs.txt\n\n# Step 3-6: Extract, analyze, and interpret\n# (See Analysis Workflow section below)\n```\n\n## Common Test Failure Analysis Approaches\n\n### 1. **Interpreting Assertion Failures**\nThe most common test failure is when an assertion doesn't match expectations.\n\n**Example:**\n```\nExpected $true but got $false at /path/to/test.ps1:42\nAssertion failed: Should -Be \"expected\" but was \"actual\"  \n```\n\n**How to analyze:**\n- Read the assertion message: what was expected vs. what was actual?\n- Check the test logic: is the expectation correct?\n- Look for mock/stub issues: are dependencies configured correctly?\n- Check parameter values: what inputs were passed to the function under test?\n\n### 2. **Exception Failures**\nTests fail when PowerShell throws an exception instead of successful completion.\n\n**Example:**\n```\nCommand: Write-Host $null\nError: Cannot bind argument to parameter 'Object' because it is null.\n```\n\n**How to analyze:**\n- Read the exception message: what operation failed?\n- Check the stack trace: where in the test or tested code did it throw?\n- Verify preconditions: does the test setup provide required values/mocks?\n- Look for environmental issues: missing modules, permissions, file system state?\n\n### 3. **Timeout Failures**\nA test takes longer than the allowed timeout to complete.\n\n**Example:**\n```\nTest 'Should complete in reasonable time' timed out after 30 seconds\n```\n\n**How to analyze:**\n- Is the timeout appropriate for this test type? (network tests need more time)\n- Is there an infinite loop in the test or tested code?\n- Are there resource contention issues on the CI runner?\n- Does the test hang waiting for something (file lock, network, process)?\n\n### 4. **Skip/Ignored Reason Analysis**\nTests marked as skipped or ignored provide clues about test environment.\n\n**Example:**\n```\nTest marked [Skip(\"Only runs on Windows\")] - running on Linux\nTest marked [Ignore(\"Known issue #12345\")]\n```\n\n**How to analyze:**\n- Read the skip/ignore reason: is it still valid?\n- Check if environment has changed: platform, module versions, etc.\n- Verify issue status: is the known issue still open? Has it been fixed?\n- Determine if skip should be removed or if test needs environment changes\n\n### 5. **Flaky/Intermittent Failures**\nTests that sometimes pass, sometimes fail indicate race conditions or environment sensitivity.\n\n**Example:**\n- Test passes locally but fails on CI\n- Test passes first run of suite, fails on second run\n- Test passes on Windows but fails on Linux\n\n**How to analyze:**\n- Look for timeout races: is timing involved in the test?\n- Check for test isolation issues: does one test affect another?\n- Verify environment differences: CI vs. local paths, permissions, versions\n- Look for external dependencies: network calls, file I/O, process interactions\n\n## Key Artifacts and Locations\n\n| Item | Purpose | Location |\n|------|---------|----------|\n| Test result XML | Pester output with test cases, failures, errors | Workflow artifacts: `junit-pester-*.xml` |\n| Job logs | Full job output including test execution and errors | GitHub Actions run logs or `gh run download` |\n| Stack traces | Error location information from failed assertions | Within job logs and XML failure messages |\n| Test files | The actual Pester test code (`.ps1` files) | `test/` directory in repository |\n\n## Analysis Workflow\n\n### ⚠️ Important: These Steps MUST Be Followed In Order\n\nEach step depends on the previous one. Skipping or re-ordering steps causes incomplete analysis:\n\n- **Step 1** (identify jobs) → You get the RUN_ID needed for Step 2\n- **Step 2** (download) → You get the artifacts needed for Step 3  \n- **Step 3** (extract) → You discover what failures exist for Step 4\n- **Step 4** (read messages) → You understand the errors to analyze in Step 5\n- **Step 5** (context) → You gather information to make recommendations in Step 6\n- **Step 6** (interpret) → You use all above to recommend fixes\n\n**Real Problem We Had**:\n- ❌ Jumped to Step 3 without Step 1-2\n- ❌ Used random test data from context instead of downloading PR artifacts\n- ❌ Skipped Steps 5-6 entirely\n- ❌ Made recommendations without full context\n\n**Result**: Wrong analysis and recommendations that didn't actually fix the problem.\n\n### Recommended: Use the Automated Script\n\n```powershell\n./.github/skills/analyze-pester-failures/scripts/analyze-pr-test-failures.ps1 -PR <PR_NUMBER>\n```\n\nThis enforces the workflow and prevents skipping.\n\n### Step 2: Get Test Results\n\nFetch the test result artifacts and job logs:\n\n```powershell\n# Download artifacts including test XML results\ngh run download <RUN_ID> --dir ./artifacts\n\n# Get job logs\ngh run view <RUN_ID> --log > test-logs.txt\n\n# Inspect test XML\n$xml = [xml](Get-Content ./artifacts/junit-pester-*.xml)\n$xml.'test-results' | Select-Object total, failures, errors, ignored, inconclusive\n```\n\n### Step 3: Extract Specific Failures\n\nFind the failing test cases in the XML:\n\n```powershell\n# Get all failed test cases\n$xml = [xml](Get-Content ./artifacts/junit-pester-*.xml)\n$failures = $xml.SelectNodes('.//test-case[@result = \"Failure\"]')\n\n# For each failure, display key info\n$failures | ForEach-Object {\n    [PSCustomObject]@{\n        Name = $_.name\n        Description = $_.description\n        Message = $_.failure.message\n        StackTrace = $_.failure.'stack-trace'\n    }\n}\n```\n\n### Step 4: Read the Error Message\n\nThe error message tells you what went wrong:\n\n**Assertion failures:**\n```\nExpected $true but got $false\nExpected \"value1\" but got \"value2\"\nExpression should have failed with exception, but didn't\n```\n\n**Exceptions:**\n```\nCannot find a parameter with name 'Name'\nProperty 'Property' does not exist on 'Object'\nCannot bind argument to parameter because it is null\n```\n\n**Timeouts:**\n```\nTest timed out after 30 seconds\nTest is taking too long to complete\n```\n\n### Step 5: Understand the Context\n\nLook at the test file to understand what was being tested:\n\n```powershell\n# Find the test file mentioned in the stack trace\n# Example: /path/to/test/Feature.Tests.ps1:42\n\n# Read the test code around that line\ncode <test-file-path>:<line-number>\n\n# Understand:  \n# - What assertion is on that line?\n# - What is the test trying to verify?\n# - What are the setup/mock/before conditions?\n# - Are there recent changes to the function being tested?\n```\n\n### Step 6: Interpret the Failure\n\nDetermine the root cause category:\n\n**Test issue (needs code fix):**\n- Assertion logic is wrong\n- Test expectations don't match actual behavior\n- Test setup is incomplete\n- Mock/stub configuration missing\n\n**Environmental issue (needs environment change):**\n- Test assumes a specific file or registry entry exists\n- Test requires Windows/Linux specifically\n- Test requires specific PowerShell version\n- Test requires specific module version\n- Timing-sensitive test affected by CI load\n\n**Data issue (needs input data change):**\n- Test data no longer valid\n- External API changed format\n- Configuration file has changed structure\n\n**Flakiness (needs test hardening):**\n- Race condition in test\n- Timing assumptions too tight\n- Resource contention on CI runner\n- Non-deterministic behavior in tested code\n\n## Common Test Failure Patterns\n\n| Pattern | What It Means | Example | Next Step |\n|---------|---------------|---------|-----------|\n| `Expected $true but got $false` | Assertion on boolean result failed | Test expects function returns true, but it returns false | Check function logic for bug or test logic for wrong expectation |\n| `Cannot find path` | File or directory doesn't exist | Test tries to read config file that's not present | Verify file path, check test setup, ensure CI environment has file |\n| `Cannot bind argument to parameter 'X'` | Required parameter value is null or wrong type | Function called with $null where object expected | Check test mock setup, verify parameter types |\n| `Test timed out after X seconds` | Test exceeded time limit | Network call or loop takes too long | Increase timeout for slow test, find infinite loop, mock network calls |\n| `Expression should have failed but didn't` | Exception wasn't thrown when expected | Test expects error but function succeeds | Check if function behavior changed, update test expectation |\n| `Could not find parameter 'X'` | Function doesn't have parameter | Test calls function with parameter that doesn't exist | Check PowerShell version, verify function signature, update test |\n| `This platform is not supported` | Test skipped on current OS | Windows-only test running on Linux | Add platform check, update test environment, or mark as platform-specific |\n| `Test marked [Ignore]` | Test explicitly disabled | Test has `[Ignore(\"reason\")]` attribute | Check if reason still valid, remove if issue fixed |\n\n## Interpreting Test Results\n\n### Test Result Counts\n\nPester test outcomes are categorized as:\n\n| Count | Meaning | Notes |\n|-------|---------|-------|\n| `total` | Total number of test cases executed | Should match: passed + failed + errors + skipped + ignored |\n| `failures` | Test assertions that failed | `Expected X but got Y` type failures |\n| `errors` | Tests that threw exceptions | Unhandled PowerShell exceptions during test |\n| `skipped` | Tests explicitly skipped (marked with `-Skip`) | Test code recognizes condition and skips |\n| `ignored` | Tests marked as ignored (marked with `-Ignore`) | Test disabled intentionally, usually notes reason |\n| `inconclusive` | Tests with unclear result | Rare; usually means test framework issue |\n| `passed` | Tests with passing assertions | `total - failures - errors - skipped - ignored` |\n\n### Stack Trace Interpretation\n\nA stack trace shows where the failure occurred:\n\n```\nat /home/runner/work/PowerShell/test/Feature.Tests.ps1:42\n\nMeans:\n- File: /home/runner/work/PowerShell/test/Feature.Tests.ps1\n- Line: 42\n- Look at that line to see which assertion failed\n```\n\n### Understanding Skipped Tests\n\nWhen XML shows `result=\"Ignored\"` or `result=\"Skipped\"`:\n\n```xml\n<test-case name=\"Test Name\" result=\"Ignored\">\n  <reason>Only runs on Windows</reason>\n</test-case>\n```\n\nThe reason explains why test didn't run. Not a failure, but important for understanding test coverage.\n\n## Providing Test Failure Analysis\n\n### Investigation Questions\n\nAfter gathering test output, ask yourself:\n\n1. **Is the test code correct?**\n   - Does the test assertion match the expected behavior?\n   - Are test expectations still valid?\n   - Has the function being tested changed?\n\n2. **Is the test setup correct?**\n   - Are mocks/stubs configured properly?\n   - Does the test environment have required files/configuration?\n   - Are preconditions (database, files, services) met?\n\n3. **Is this a code bug or test issue?**\n   - Does the tested function have a logic error?\n   - Or does the test have incorrect expectations?\n\n4. **Is this environment-specific?**\n   - Only fails on Windows/Linux?\n   - Only fails on CI but passes locally?\n   - Timing-dependent or resource-dependent?\n\n5. **Is this a known/expected failure?**\n   - Is there already an issue tracking this failure?\n   - Is the test marked as flaky or expected to fail?\n   - Does the skip/ignore reason still apply?\n\n### Recommendation Framework\n\nBased on your analysis:\n\n| Finding | Recommendation |\n|---------|-----------------|\n| Test logic is wrong | \"Test assertion on line X is incorrect. Test expects Y but function correctly returns Z. Update test expectation.\" |\n| Tested code has bug | \"Function at file.ps1#L42 has logic error. When X happens, returns Y instead of Z. Fix the condition.\" |\n| Missing test setup | \"Test setup incomplete. Mock for dependency Y is not configured. Add `Mock Get-Y -MockWith { ... }`\" |\n| Environment issue | \"Test is Windows-specific but running on Linux. Either add platform check or skip on non-Windows.\" |\n| Flaky test | \"Test is timing-sensitive (sleep 1 second). Increase timeout or use better synchronization.\" |\n| Test should be skipped | \"Test is marked Ignored for good reason. Keep it disabled until issue #12345 is fixed.\" |\n\n### Tone and Structure\n\nProvide analysis as:\n\n1. **Summary** (1 sentence): What test is failing and general category  \n2. **Failure Details** (2-3 sentences): What the test output says  \n3. **Root Cause** (1-2 sentences): Why it's failing (test bug vs. code bug vs. environment)\n4. **Recommendation** (actionable): What should be done to fix it  \n5. **Context** (optional): Link to related code, issues, or recent changes\n\n## Examples\n\n### Example 1: Assertion Failure Due to Code Bug\n\n**Test Output:**\n```\nExpected 5 but got 3 at /path/to/Test.ps1:42\n```\n\n**Investigation:**\n1. Look at line 42: `$result | Should -Be 5`\n2. Check the test: It expects function to return 5 items\n3. Check the function: It returns `$items | Where-Object {$_.Status -eq \"Active\"}` but the filter is wrong\n4. Root cause: Function has logic error, not test error\n\n**Recommendation:**\n```\nTest failure is due to a code bug:\n\nThe test Set-Configuration should return 5 items but returns 3.\n\nLooking at the tested function at [module.ps1#L42](module.ps1#L42):\n  $activeItems = $items | Where-Object {$_.Status -eq \"Active\"}\n\nThe issue is the filter condition. It's currently filtering by \"Active\" status,\nbut should include \"Pending\" status as well. \n\nFix: Change line 42 to:\n  $activeItems = $items | Where-Object {$_.Status -ne \"Disabled\"}\n\nThen re-run the test to verify it now returns 5 items as expected.\n```\n\n### Example 2: Test Setup Issue\n\n**Test Output:**\n```\nCannot find path '/expected/config.json' because it does not exist at /path/to/Test.ps1:15\n```\n\n**Investigation:**\n1. Line 15 tries to read a config file\n2. The test setup doesn't create this file\n3. Works locally but fails on CI because CI doesn't have the same file\n\n**Recommendation:**\n```\nTest setup is incomplete:\n\nThe test Initialize-Config fails because it expects /expected/config.json but the test doesn't create this file.\n\nThe test needs to ensure the config file exists. Currently line 12-14 doesn't set up the file:\n\n  # Before:\n  # (no setup of config file)\n\n  # After:\n  @{ setting1 = \"value1\"; setting2 = \"value2\" } | ConvertTo-Json | \n    Out-File $testConfigPath\n\nAlternatively, the test function should accept a parameter for the config path and use a temporary file:\n  param([string]$ConfigPath = (New-TemporaryFile))\n\nRe-run the test to verify the config file is properly available.\n```\n\n### Example 3: Platform-Specific Test Failure\n\n**Test Output:**\n```\nTest 'should read Windows Registry' failed on Linux runner\nCannot find path 'HKEY_LOCAL_MACHINE:\\...'\n```\n\n**Investigation:**\n1. Test assumes Windows Registry exists (Windows-only)\n2. Running on Linux runner doesn't have Registry\n3. Test should skip on non-Windows platforms\n\n**Recommendation:**\n```\nTest is platform-specific but running on wrong platform:\n\nThe test \"should read Windows Registry\" assumes Windows Registry exists but is running on Linux.\n\nAdd a platform check to skip this test on non-Windows systems:\n\n  It \"should read Windows Registry\" -Skip:$(-not $IsWindows) {\n    # test code here\n  }\n\nOr group Windows-only tests in a separate Describe block with platform check:\n\n  Describe \"Windows Registry Tests\" -Skip:$(-not $IsWindows) {\n    # all Windows-specific tests here\n  }\n\nThis allows the test to be skipped on Linux/Mac while still running on Windows CI.\n```\n\n## References\n\n- [Pester Testing Framework](https://pester.dev/) — Official documentation, best practices for test writing\n- [Test Files](../../../test/) — PowerShell test suite in repository\n- [GitHub Actions Documentation](https://docs.github.com/en/actions) — Understanding workflow runs and logs\n- [PowerShell Documentation](https://learn.microsoft.com/en-us/powershell/) — Language reference for understanding test code\n\n## Tips\n\n1. **Read the error message first:** The error message is usually the most direct clue to the problem\n2. **Check test vs. code blame:** Is the test wrong or is the code wrong? Look at both sides\n3. **Verify test isolation:** Does one test failure affect others? Check for shared state or test ordering dependencies\n4. **Test locally first:** Try running the failing test locally to reproduce and understand it better\n5. **Check for environmental assumptions:** Windows-specific paths, module versions, file locations may differ on CI\n6. **Look for skip/ignore patterns:** If a test is consistently ignored, check if the reason is still valid\n7. **Compare passing vs. failing:** If test passes locally but fails on CI, the difference is usually environment-related\n8. **Check recent changes:** Did a recent PR change the tested code or test itself?\n9. **Understand Pester output format:** Different Pester versions, different `-ErrorAction`, `-WarningAction` produce different test results\n10. **Don't assume CI is wrong:** Failures on CI often reveal real issues that local testing missed (network, file permissions, parallelization, etc.)\n\n## Additional Links\n\n- [PowerShell Repository](https://github.com/PowerShell/PowerShell)\n- [GitHub Actions Documentation](https://docs.github.com/en/actions)\n- [Pester Testing Framework](https://github.com/Pester/Pester)\n","test/tools/TestMetadata.json":"{\n  \"ExperimentalFeatures\": {\n    \"ExpTest.FeatureOne\": [ \"test/powershell/engine/ExperimentalFeature/ExperimentalFeature.Basic.Tests.ps1\" ],\n    \"PSSerializeJSONLongEnumAsNumber\": [ \"test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertTo-Json.PSSerializeJSONLongEnumAsNumber.Tests.ps1\" ]\n  }\n}\n","tools/metadata.json":"{\n  \"StableReleaseTag\": \"v7.6.9\",\n  \"PreviewReleaseTag\": \"v7.7.0-preview.5\",\n  \"ServicingReleaseTag\": \"v7.0.13\",\n  \"ReleaseTag\": \"v7.6.9\",\n  \"LTSReleaseTag\": [\"v7.4.22\", \"v7.6.9\"],\n  \"NextReleaseTag\": \"v7.7.0-preview.6\",\n  \"LTSRelease\": { \"PublishToChannels\": false, \"Package\": false },\n  \"StableRelease\":  { \"PublishToChannels\": false, \"Package\": false }\n}\n","tools/install-powershell.sh-README.md":"# install-powershell.sh\n\n## Features of install-powershell.sh\n\n* Can be called directly from git\n* Optionally installs vs code and vs powershell extension (aka PowerShell IDE) using optional `-includeide` switch\n* Defaults to completely automated operation (if appropriate permissions are available)\n* Automatically looks up latest version via git tags\n* Automatic selection of appropriate install sub-script\n* Configures software installs for repositories when repositories are in place, otherwise pulls files from git releases.  As repository versions are made available, script will be updated to take advantage.\n* User permission checking\n* Sub-installers called from local file system if they exist, otherwise pulled from git\n* Sub-installers can be called directly if auto-selection is not needed\n\n## Minimum Requirements for install-powershell.sh\n\n* bash shell\n* `sed`\n* native package manager available\n* `curl` (auto-installed if missing)\n* `tr`\n\n## Parameters\n\n* -includeide - installs VSCode and VSCode PowerShell extension (only relevant to machines with a desktop environment)\n* -interactivetesting - do a quick launch test of VSCode (only relevant when used with -includeide)\n* -skip-sudo-check - use sudo without verifying its availability (hard to accurately do on some distros)\n* -preview - installs the latest preview release of PowerShell core side-by-side with any existing production releases\n\n## Usage\n\n### Direct from Github\n\n```bash\nbash <(wget -O - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.sh) <ARGUMENTS>\n\nwget -O - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.sh | bash -s <ARGUMENTS>\n```\n\n### Local Copy\n\n```bash\nbash install-powershell.sh <ARGUMENTS>\n```\n\n## Examples\n\n### Only Install PowerShell Core\n\n```bash\nbash <(wget -O - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.sh)\n```\n\n### Install PowerShell Core with IDE\n\n```bash\nbash <(wget -O - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.sh) -includeide\n```\n\n### Install PowerShell Core with IDE and do tests that require a human to interact with the installation process\n\n```bash\nbash <(wget -O - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.sh) -includeide -interactivetesting\n```\n\n### Installation To do list\n\n* Detect and wait when package manager is busy/locked? - at least Ubuntu (CentOS does this internally)\n","tools/findMissingNotices.targets.json":"{\n  \"dotnetTargetName\": \"net11.0\",\n  \"windowsTargetNames\": [\n  ]\n}\n",".github/agents/SplitADOPipelines.agent.md":"---\nname: SplitADOPipelines\ndescription: This agent will implement and restructure the repository's existing ADO pipelines into Official and NonOfficial pipelines.\ntools: ['vscode', 'execute', 'read', 'agent', 'edit', 'search', 'todo']\n---\n\nThis agent will implement and restructure the repository's existing ADO pipelines into Official and NonOfficial pipelines. \n\nA repository will have under the .pipelines directory a series of yaml files that define the ADO pipelines for the repository.\n\nFirst confirm if the pipelines are using a toggle switch for Official and NonOfficial. This will look something like this\n\n```yaml\nparameters:\n  - name: templateFile\n    value: ${{ iif ( parameters.OfficialBuild, 'v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates', 'v2/OneBranch.NonOfficial.CrossPlat.yml@onebranchTemplates' ) }}\n```\n\nFollowed by:\n\n```yaml\nextends:\n  template: ${{ variables.templateFile }}\n```\n\nThis is an indicator that this work needs to be done. This toggle switch is no longer allowed and the templates need to be hard coded.\n\n## Template Reference Convention (MUST follow)\n\nAll `- template:` references to files **inside this repo** must use the **absolute** form anchored at the repo root, with the `@self` suffix:\n\n```yaml\n- template: /.pipelines/templates/<path>/<file>.yml@self\n```\n\nDo **not** use relative paths such as `templates/...`, `../templates/...`, or bare filenames. Rationale:\n\n- Absolute paths resolve identically regardless of where the referring file lives, so moving a pipeline file between directories (for example, into `.pipelines/NonOfficial/`) does not silently break includes.\n- Relative paths are resolved by Azure DevOps against the directory of the referring file, which has caused real outages in this repo when a relative include was composed into a nonexistent nested path like `.pipelines/templates/stages/.pipelines/templates/...`.\n- The majority of existing includes already use the absolute form; keeping new work consistent reduces review burden.\n\nThe only acceptable non-absolute references are to external repositories resolved via the `resources.repositories` block, for example `v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates`.\n\n## Refactoring Steps\n\n### Step 1: Extract Shared Templates\n\nFor each pipeline file that uses the toggle switch pattern (e.g., `PowerShell-Packages-Official.yml`):\n\n1. Create the `.pipelines/templates/variables` and `.pipelines/templates/stages` directories if they don't exist\n2. Extract the **variables section** into `.pipelines/templates/variables/PowerShell-Packages-Variables.yml`\n3. Extract the **stages section** into `.pipelines/templates/stages/PowerShell-Packages-Stages.yml`\n\n**IMPORTANT**: Only extract the `variables:` and `stages:` sections. All other sections (parameters, resources, extends, etc.) remain in the pipeline files.\n\n### Step 2: Create Official Pipeline (In-Place Refactoring)\n\nThe original toggle-based file becomes the Official pipeline:\n\n1. **Keep the file in its original location** (e.g., `.pipelines/PowerShell-Packages-Official.yml` stays where it is)\n2. Remove the toggle switch parameter (`templateFile` parameter)\n3. Hard-code the Official template reference:\n   ```yaml\n   extends:\n     template: v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates\n   ```\n4. Replace the `variables:` section with a template reference:\n   ```yaml\n   variables:\n     - template: /.pipelines/templates/variables/PowerShell-Packages-Variables.yml@self\n   ```\n5. Replace the `stages:` section with a template reference:\n   ```yaml\n   stages:\n     - template: /.pipelines/templates/stages/PowerShell-Packages-Stages.yml@self\n   ```\n\n### Step 3: Create NonOfficial Pipeline\n\n1. Create `.pipelines/NonOfficial` directory if it doesn't exist\n2. Create the NonOfficial pipeline file (e.g., `.pipelines/NonOfficial/PowerShell-Packages-NonOfficial.yml`)\n3. Copy the structure from the refactored Official pipeline\n4. Hard-code the NonOfficial template reference:\n   ```yaml\n   extends:\n     template: v2/OneBranch.NonOfficial.CrossPlat.yml@onebranchTemplates\n   ```\n5. Reference the same shared templates:\n   ```yaml\n   variables:\n     - template: /.pipelines/templates/variables/PowerShell-Packages-Variables.yml@self\n   \n   stages:\n     - template: /.pipelines/templates/stages/PowerShell-Packages-Stages.yml@self\n   ```\n\n**Note**: Always use **absolute** template paths of the form `/.pipelines/templates/...@self`. Do not use relative paths like `templates/...` or `../templates/...`. Absolute paths are anchored at the repo root and resolve consistently from any referring file, preventing breakage when files are moved between directories.\n\n### Step 4: Link NonOfficial Pipelines to NonOfficial Dependencies\n\nAfter creating NonOfficial pipelines, ensure they consume artifacts from other **NonOfficial** pipelines, not Official ones.\n\n1. **Check the `resources:` section** in each NonOfficial pipeline for `pipelines:` dependencies\n2. **Identify Official pipeline references** that need to be changed to NonOfficial\n3. **Update the `source:` field** to point to the NonOfficial version\n\n**Example Problem:** NonOfficial pipeline pointing to Official dependency\n```yaml\nresources:\n  pipelines:\n    - pipeline: CoOrdinatedBuildPipeline\n      source: 'PowerShell-Coordinated Binaries-Official'  # ❌ Wrong - Official!\n```\n\n**Solution:** Update to NonOfficial dependency\n```yaml\nresources:\n  pipelines:\n    - pipeline: CoOrdinatedBuildPipeline\n      source: 'PowerShell-Coordinated Binaries-NonOfficial'  # ✅ Correct - NonOfficial!\n```\n\n**IMPORTANT**: The `source:` field must match the **exact ADO pipeline definition name** as it appears in Azure DevOps, not necessarily the file name.\n\n### Step 5: Configure Release Environment Parameters (NonAzure Only)\n\n**This step only applies if the pipeline uses `category: NonAzure` in the release configuration.**\n\nIf you detect this pattern in the original pipeline:\n\n```yaml\nextends:\n  template: v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates  # or NonOfficial\n  parameters:\n    release:\n      category: NonAzure\n```\n\nThen you must configure the `ob_release_environment` parameter when referencing the stages template.\n\n#### Official Pipeline Configuration\n\nIn the Official pipeline (e.g., `.pipelines/PowerShell-Packages-Official.yml`):\n\n```yaml\nstages:\n  - template: /.pipelines/templates/stages/PowerShell-Packages-Stages.yml@self\n    parameters:\n      ob_release_environment: Production\n```\n\n#### NonOfficial Pipeline Configuration\n\nIn the NonOfficial pipeline (e.g., `.pipelines/NonOfficial/PowerShell-Packages-NonOfficial.yml`):\n\n```yaml\nstages:\n  - template: /.pipelines/templates/stages/PowerShell-Packages-Stages.yml@self\n    parameters:\n      ob_release_environment: Test\n```\n\n#### Update Stages Template to Accept Parameter\n\nThe extracted stages template (e.g., `.pipelines/templates/stages/PowerShell-Packages-Stages.yml`) must declare the parameter at the top:\n\n```yaml\nparameters:\n  - name: ob_release_environment\n    type: string\n\nstages:\n  # ... rest of stages configuration using ${{ parameters.ob_release_environment }}\n```\n\n**IMPORTANT**: \n- Only configure this for pipelines with `category: NonAzure`\n- Official pipelines always use `ob_release_environment: Production`\n- NonOfficial pipelines always use `ob_release_environment: Test`\n- The stages template must accept this parameter and use it in the appropriate stage configurations\n","tools/guardian/tsaconfig-apiscan.json":"{\n  \"codebaseName\": \"PowerShellCore_201906\",\n  \"tools\": [\n      \"APIScan\"\n  ]\n}\n","tools/credScan/suppress.json":"{\n    \"tool\": \"Credential Scanner\",\n    \"suppressions\": [\n      {\n       \"file\": \"\\\\test\\\\tools\\\\Modules\\\\WebListener\\\\ClientCert.pfx\",\n        \"_justification\": \"Test certificate with private key\"\n      },\n      {\n        \"file\": \"\\\\test\\\\tools\\\\Modules\\\\WebListener\\\\ServerCert.pfx\",\n         \"_justification\": \"Test certificate with private key\"\n       },\n       {\n         \"file\": \"\\\\test\\\\powershell\\\\Modules\\\\Microsoft.PowerShell.Security\\\\certificateCommon.psm1\",\n          \"_justification\": \"Test certificate with private key and inline suppression isn't working\"\n        }\n     ]\n}\n","tools/guardian/tsaconfig-others.json":"{\n  \"codebaseName\": \"PowerShellCore_201906\",\n  \"tools\": [\n      \"CredScan\",\n      \"PoliCheck\"\n  ]\n}\n","tools/AttackSurfaceAnalyzer/README.md":"# Attack Surface Analyzer Testing\n\nThis directory contains tools for running Attack Surface Analyzer (ASA) tests on PowerShell MSI installations using Docker.\n\n## Overview\n\nAttack Surface Analyzer is a Microsoft tool that helps analyze changes to a system's attack surface. These scripts allow you to run ASA tests locally in a clean Windows container to analyze what changes when PowerShell is installed.\n\n## Files\n\n- **Run-AttackSurfaceAnalyzer.ps1** - PowerShell script to run ASA tests with official MSIs\n- **Summarize-AsaResults.ps1** - PowerShell script to analyze and summarize ASA results\n- **docker/Dockerfile** - Multi-stage Dockerfile for building a container image with ASA pre-installed\n- **README.md** - This documentation file\n\n## Docker Architecture\n\nThe Docker implementation uses a multi-stage build to optimize the testing and result extraction process:\n\n### Multi-Stage Build Stages\n\n1. **asa-runner**: Main execution environment\n   - Base: `mcr.microsoft.com/dotnet/sdk:9.0-windowsservercore-ltsc2022`\n   - Contains Attack Surface Analyzer CLI tools\n   - Runs the complete test workflow\n   - Generates reports in both `C:\\work` and `C:\\reports` directories\n\n1. **asa-reports**: Minimal results layer\n   - Base: `mcr.microsoft.com/windows/nanoserver:ltsc2022`\n   - Contains only the test reports from the runner stage\n   - Enables clean extraction of results without container internals\n\n1. **final**: Default stage (inherits from asa-runner)\n   - Provides backward compatibility\n   - Used when no specific build target is specified\n\n### Benefits\n\n- **Clean Result Extraction**: Reports are isolated in a dedicated layer\n- **Efficient Transfer**: Only test results are copied, not the entire container filesystem\n- **Fallback Support**: Script includes fallback to volume-based extraction if needed\n- **Minimal Footprint**: Final results layer contains only the necessary output files\n\n## Prerequisites\n\n- Windows 10/11 or Windows Server\n- Docker Desktop with Windows containers enabled\n- PowerShell 5.1 or later\n- **An official signed PowerShell MSI file** from a released build\n\n### MSI Requirements\n\n**Important:** This tool now requires an official, digitally signed PowerShell MSI from Microsoft releases:\n\n- **Must be signed** by Microsoft Corporation\n- **Must be from an official release** (downloaded from [PowerShell Releases](https://github.com/PowerShell/PowerShell/releases))\n- **Local builds are not supported** - unsigned or development MSIs will be rejected\n- The script automatically verifies the digital signature before proceeding\n\n**Where to get official MSIs:**\n\n- Download from: https://github.com/PowerShell/PowerShell/releases\n- Look for files like: `PowerShell-7.x.x-win-x64.msi`\n\n## Quick Start\n\n### Option 1: Using the PowerShell Script (Recommended)\n\nThe script requires an official signed PowerShell MSI file:\n\n```powershell\n# Run ASA test with official MSI (MsiPath is required)\n.\\tools\\AttackSurfaceAnalyzer\\Run-AttackSurfaceAnalyzer.ps1 -MsiPath \"C:\\path\\to\\PowerShell-7.4.0-win-x64.msi\"\n\n# Specify custom output directory for results\n.\\tools\\AttackSurfaceAnalyzer\\Run-AttackSurfaceAnalyzer.ps1 -MsiPath \".\\PowerShell-7.4.0-win-x64.msi\" -OutputPath \"C:\\asa-results\"\n\n# Keep the temporary work directory for debugging\n.\\tools\\AttackSurfaceAnalyzer\\Run-AttackSurfaceAnalyzer.ps1 -MsiPath \".\\PowerShell-7.4.0-win-x64.msi\" -KeepWorkDirectory\n```\n\nThe script will:\n\n1. **Verify MSI signature** - Ensures the MSI is officially signed by Microsoft Corporation\n1. Create a temporary work directory\n1. Build a custom Docker container from the static Dockerfile\n1. Start the Windows container with Attack Surface Analyzer\n1. Take a baseline snapshot\n1. Install the PowerShell MSI\n1. Take a post-installation snapshot\n1. Export comparison results\n1. Copy results back to your specified output directory\n\n**Security Note:** The script will reject any MSI that is not digitally signed by Microsoft Corporation to ensure analysis is performed only on official releases.\n\n### Option 2: Using the Dockerfile\n\nIf you prefer to build and use the container image directly:\n\n```powershell\n# Build the Docker image (Dockerfile is in docker subfolder with clean context)\ndocker build -f tools\\AttackSurfaceAnalyzer\\docker\\Dockerfile -t powershell-asa-test tools\\AttackSurfaceAnalyzer\\docker\\\n\n# Run the container with your MSI (script is built into the container)\ndocker run --rm --isolation process `\n  -v \"C:\\path\\to\\msi\\directory:C:\\work\" `\n  powershell-asa-test\n```\n\n## Output Files\n\nThe test will generate output files in the `./asa-results/` directory (or your specified `-OutputPath`):\n\n- **`asa.sqlite`** - SQLite database with full analysis data (primary result file)\n- **`install.log`** - MSI installation log file\n- **`*_summary.json.txt`** - Summary of detected changes (if generated)\n- **`*_results.json.txt`** - Detailed results in JSON format (if generated)\n- **`*.sarif`** - SARIF format results (if generated, can be viewed in VS Code)\n\n## Analyzing Results\n\n### Using the Summary Script (Recommended)\n\nUse the included summary script to get a comprehensive analysis:\n\n```powershell\n# Basic summary of ASA results\n.\\tools\\AttackSurfaceAnalyzer\\Summarize-AsaResults.ps1\n\n# Detailed analysis with rule breakdowns\n.\\tools\\AttackSurfaceAnalyzer\\Summarize-AsaResults.ps1 -ShowDetails\n\n# Analyze results from a specific location\n.\\tools\\AttackSurfaceAnalyzer\\Summarize-AsaResults.ps1 -Path \"C:\\custom\\path\\asa-results.json\" -ShowDetails\n```\n\nThe summary script provides:\n\n- **Overall statistics** - Total findings, analysis levels, category breakdowns\n- **Rule analysis** - Which security rules were triggered and how often\n- **File analysis** - Detailed breakdown of file-related security issues by rule type\n- **Category cross-reference** - Shows which rules affect which categories\n\n### Using VS Code\n\nThe SARIF files can be opened directly in VS Code with the SARIF Viewer extension to see a formatted view of the findings.\n\n### Using PowerShell\n\n```powershell\n# Read the JSON results directly\n$results = Get-Content \"asa-results\\asa-results.json\" | ConvertFrom-Json\n$results.Results.FILE_CREATED.Count  # Number of files created\n\n# Query the SQLite database (requires SQLite tools)\n# Example: List all file changes\n# sqlite3 asa.sqlite \"SELECT * FROM file_system WHERE change_type != 'NONE'\"\n```\n\n## Troubleshooting\n\n### Docker Not Available\n\nThe script automatically handles Docker Desktop installation and startup:\n\n**If Docker Desktop is installed but not running:**\n\n- The script will automatically start Docker Desktop for you\n- It waits up to 60 seconds for Docker to become available\n- You'll be prompted for confirmation (supports `-Confirm` and `-WhatIf`)\n\n**If Docker Desktop is not installed:**\n\n- The script will prompt you to install it automatically using winget\n- After installation completes, start Docker Desktop and run the script again\n\n**Manual Installation:**\n\n1. Install Docker Desktop from https://www.docker.com/products/docker-desktop\n1. Ensure Docker is running\n1. Switch to Windows containers (right-click Docker tray icon → \"Switch to Windows containers\")\n\n### Container Fails to Start\n\n- Ensure you have enough disk space (containers can be large)\n- Check that Windows containers are enabled in Docker settings\n- Try pulling the base image manually: `docker pull mcr.microsoft.com/dotnet/sdk:9.0-windowsservercore-ltsc2022`\n\n### MSI Signature Verification Fails\n\nIf you get signature verification errors:\n\n- **Ensure you're using an official MSI** from [PowerShell Releases](https://github.com/PowerShell/PowerShell/releases)\n- **Do not use local builds** - only signed release MSIs are supported  \n- **Check certificate validity** - very old MSIs may have expired certificates\n- **Verify file integrity** - redownload the MSI if it may be corrupted\n\n### No Results Generated\n\n- Check the install.log file for MSI installation errors\n- Run with `-KeepWorkDirectory` to inspect the temporary work directory\n- Verify the MSI file is valid and not corrupted\n\n## Advanced Usage\n\n### Parameters\n\nThe `Run-AttackSurfaceAnalyzer.ps1` script supports these parameters:\n\n- **`-MsiPath`** (Required) - Path to the official signed PowerShell MSI file\n- **`-OutputPath`** (Optional) - Directory for results (defaults to `./asa-results`)\n- **`-ContainerImage`** (Optional) - Custom container base image\n- **`-KeepWorkDirectory`** (Optional) - Keep temp directory for debugging\n\nExample with custom container image:\n\n```powershell\n.\\tools\\AttackSurfaceAnalyzer\\Run-AttackSurfaceAnalyzer.ps1 `\n  -MsiPath \".\\PowerShell-7.4.0-win-x64.msi\" `\n  -ContainerImage \"mcr.microsoft.com/dotnet/sdk:8.0-windowsservercore-ltsc2022\"\n```\n\n### Debugging\n\nTo debug issues, keep the work directory and examine the files:\n\n```powershell\n.\\tools\\AttackSurfaceAnalyzer\\Run-AttackSurfaceAnalyzer.ps1 -KeepWorkDirectory\n\n# The script will print the work directory path\n# You can then examine:\n# - run-asa.ps1 - The script that runs in the container\n# - install.log - MSI installation log\n# - Any other generated files\n```\n\n## Integration with CI/CD\n\nThese tools were extracted from the GitHub Actions workflow to allow local testing. If you need to integrate ASA testing back into a CI/CD pipeline, you can:\n\n1. Use the PowerShell script directly in your pipeline\n1. Build and push the Docker image to a registry\n1. Use the Dockerfile as a base for custom testing scenarios\n\n## More Information\n\n- [Attack Surface Analyzer on GitHub](https://github.com/microsoft/AttackSurfaceAnalyzer)\n- [Docker for Windows Documentation](https://docs.docker.com/desktop/windows/)\n- [SARIF Documentation](https://sarifweb.azurewebsites.net/)\n","tools/install-powershell.ps1-README.md":"# install-powershell.ps1\n\n## Features of install-powershell.ps1\n\n- Can be called directly from Git\n- Optionally allows install of the latest Preview build\n- Optionally installs using the latest MSI\n- Automatically looks up latest version via Git tags\n- Optionally installs silently\n- Optionally adds the install location to Path environment variable\n\n## Examples\n\n### Install PowerShell Preview Build\n\n```PowerShell\nInvoke-Expression \"& { $(Invoke-RestMethod 'https://aka.ms/install-powershell.ps1') } -Preview\"\n```\n\n### Install PowerShell using the MSI installer\n\n```PowerShell\nInvoke-Expression \"& { $(Invoke-RestMethod 'https://aka.ms/install-powershell.ps1') } -UseMSI\"\n```\n","tools/clearlyDefined/readme.md":"# ClearlyDefined\n\n## Purpose\n\nThis tool is intended to test if all the license data in [ClearlyDefined](https://clearlydefined.io) is present to generate the PowerShell license.\nIf the data is not present, it can request that ClearlyDefined gather (called Harvest in their terminology) the data.\n\n## Use\n\n### Testing\n\nRun `./ClearlyDefined.ps1 -test`.\n\nIf there is any missing data, the script should write verbose messages about the missing data and throw.\nIf there is no missing data, the script should not throw.\n\n### Harvesting\n\nRun `./ClearlyDefined.ps1 -Harvest`.\nThe script will trigger the harvest and output the result from ClearlyDefined.\n**Give ClearlyDefined 24 hours to harvest the data.**\nYou can use the `-Test` switch without the `-Harvest` switch to test if Harvesting is done.\n\n## Caching\n\nIf you run in the same PowerShell session, the script will be faster due to caching.\n\nThe module will cache any results from ClearlyDefined that indicate the package is Harvested for 60 minutes.\nNo caching is done for packages that are not yet harvested.\nTo clear the cache, run with the `-ForceModuleReload` switch.\n","tools/packages.microsoft.com/mapping.json":"# Packages.microsoft.com Skill\n\nPath: `tools/packages.microsoft.com/mapping.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/packages.microsoft.com/mapping.json)","tools/performance/README.md":"# performance Documentation\n\nPath: `tools/performance/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/performance/README.md)","test/perf/dotnet-tools/README.md":"# dotnet-tools Documentation\n\nPath: `test/perf/dotnet-tools/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/perf/dotnet-tools/README.md)","test/tools/CodeCoverageAutomation/README.md":"# CodeCoverageAutomation Documentation\n\nPath: `test/tools/CodeCoverageAutomation/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/CodeCoverageAutomation/README.md)","test/tools/WebListener/README.md":"# WebListener Documentation\n\nPath: `test/tools/WebListener/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/WebListener/README.md)","test/tools/WebListener/appsettings.Development.json":"# WebListener Skill\n\nPath: `test/tools/WebListener/appsettings.Development.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/WebListener/appsettings.Development.json)","test/tools/WebListener/appsettings.json":"# WebListener Skill\n\nPath: `test/tools/WebListener/appsettings.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/WebListener/appsettings.json)","tools/cgmanifest/main/cgmanifest.json":"# Main Skill\n\nPath: `tools/cgmanifest/main/cgmanifest.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/cgmanifest/main/cgmanifest.json)","tools/cgmanifest/tpn/cgmanifest.json":"# Tpn Skill\n\nPath: `tools/cgmanifest/tpn/cgmanifest.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/cgmanifest/tpn/cgmanifest.json)",".github/skills/analyze-pester-failures/references/stack-trace-parsing.md":"# References Skill\n\nPath: `.github/skills/analyze-pester-failures/references/stack-trace-parsing.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/.github/skills/analyze-pester-failures/references/stack-trace-parsing.md)","test/perf/dotnet-tools/ResultsComparer/README.md":"# ResultsComparer Documentation\n\nPath: `test/perf/dotnet-tools/ResultsComparer/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/perf/dotnet-tools/ResultsComparer/README.md)","test/tools/Modules/UnixSocket/README.md":"# UnixSocket Documentation\n\nPath: `test/tools/Modules/UnixSocket/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/Modules/UnixSocket/README.md)","test/tools/Modules/WebListener/README.md":"# WebListener Documentation\n\nPath: `test/tools/Modules/WebListener/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/Modules/WebListener/README.md)"},"files":{".github/skills/analyze-pester-failures/SKILL.md":"---\nname: analyze-pester-failures\ndescription: Troubleshooting guide for analyzing and investigating Pester test failures in PowerShell CI jobs. Help agents understand why tests are failing, interpret test output, navigate test result artifacts, and provide actionable recommendations for fixing test issues.\n---\n\n# Analyze Pester Test Failures\n\nInvestigate and troubleshoot Pester test failures in GitHub Actions workflows. Understand what tests are failing, why they're failing, and provide recommendations for test fixes.\n\n| Skill | When to Use |\n|-------|-----------|\n| analyze-pester-failures | When investigating why Pester tests are failing in a CI job. Use when a test job shows failures and you need to understand what test failed, why it failed, what the error message means, and what might need to be fixed. Also use when asked: \"why did this test fail?\", \"what's the test error?\", \"test is broken\", \"test failure analysis\", \"debug test failure\", or given test failure logs and stack traces. |\n\n## When to Use This Skill\n\nUse this skill when you need to:\n\n- Understand why a specific Pester test is failing  \n- Interpret test failure messages and error output\n- Analyze test result data from CI workflow runs (XML, logs, stack traces)\n- Identify the root cause of test failures (test logic, assertion failure, exception, timeout, skip/ignore reason)\n- Provide recommendations for fixing failing tests\n- Compare expected vs. actual test behavior\n- Debug test environment issues (missing dependencies, configuration problems)\n- Understand test skip/ignored/inconclusive status reasons\n\n**Do not use this skill for:**\n- General PowerShell debugging unrelated to tests\n- Test infrastructure/CI setup issues (except as they affect test failure interpretation)\n- Performance analysis or benchmarking (that's a different investigation)\n\n## Quick Start\n\n### ⚠️ CRITICAL: The Workflow Must Be Followed IN ORDER\n\nThis skill describes a **sequential 6-step analysis workflow**. Skipping steps or jumping around leads to **incomplete analysis and incorrect conclusions**.\n\n**The Problem**: It's easy to skip to Step 4 or 5 without doing Steps 1-2, resulting in missing data and bad conclusions.\n\n**The Solution**: Use the automated analysis script to enforce the workflow:\n\n```powershell\n# Automatically runs Steps 1-6 in order, preventing skipping\n./.github/skills/analyze-pester-failures/scripts/analyze-pr-test-failures.ps1 -PR <PR_NUMBER>\n\n# Example:\n./.github/skills/analyze-pester-failures/scripts/analyze-pr-test-failures.ps1 -PR 26800\n```\n\nThis script:\n1. ✓ Fetches PR status automatically\n2. ✓ Downloads artifacts (can't skip, depends on Step 1)\n3. ✓ Extracts failures (can't skip, depends on Step 2)\n4. ✓ Analyzes error messages\n5. ✓ Documents context\n6. ✓ Generates recommendations\n\n**Only use the manual commands below if you fully understand the workflow.**\n\n### Manual Workflow (for reference)\n\n```powershell\n# Step 1: Identify the failing job\ngh pr view <PR_NUMBER> --json 'statusCheckRollup' | ConvertFrom-Json | Where-Object { $_.conclusion -eq 'FAILURE' }\n\n# Step 2: Download artifacts (extract RUN_ID from Step 1)\ngh run download <RUN_ID> --dir ./artifacts\ngh run view <RUN_ID> --log > test-logs.txt\n\n# Step 3-6: Extract, analyze, and interpret\n# (See Analysis Workflow section below)\n```\n\n## Common Test Failure Analysis Approaches\n\n### 1. **Interpreting Assertion Failures**\nThe most common test failure is when an assertion doesn't match expectations.\n\n**Example:**\n```\nExpected $true but got $false at /path/to/test.ps1:42\nAssertion failed: Should -Be \"expected\" but was \"actual\"  \n```\n\n**How to analyze:**\n- Read the assertion message: what was expected vs. what was actual?\n- Check the test logic: is the expectation correct?\n- Look for mock/stub issues: are dependencies configured correctly?\n- Check parameter values: what inputs were passed to the function under test?\n\n### 2. **Exception Failures**\nTests fail when PowerShell throws an exception instead of successful completion.\n\n**Example:**\n```\nCommand: Write-Host $null\nError: Cannot bind argument to parameter 'Object' because it is null.\n```\n\n**How to analyze:**\n- Read the exception message: what operation failed?\n- Check the stack trace: where in the test or tested code did it throw?\n- Verify preconditions: does the test setup provide required values/mocks?\n- Look for environmental issues: missing modules, permissions, file system state?\n\n### 3. **Timeout Failures**\nA test takes longer than the allowed timeout to complete.\n\n**Example:**\n```\nTest 'Should complete in reasonable time' timed out after 30 seconds\n```\n\n**How to analyze:**\n- Is the timeout appropriate for this test type? (network tests need more time)\n- Is there an infinite loop in the test or tested code?\n- Are there resource contention issues on the CI runner?\n- Does the test hang waiting for something (file lock, network, process)?\n\n### 4. **Skip/Ignored Reason Analysis**\nTests marked as skipped or ignored provide clues about test environment.\n\n**Example:**\n```\nTest marked [Skip(\"Only runs on Windows\")] - running on Linux\nTest marked [Ignore(\"Known issue #12345\")]\n```\n\n**How to analyze:**\n- Read the skip/ignore reason: is it still valid?\n- Check if environment has changed: platform, module versions, etc.\n- Verify issue status: is the known issue still open? Has it been fixed?\n- Determine if skip should be removed or if test needs environment changes\n\n### 5. **Flaky/Intermittent Failures**\nTests that sometimes pass, sometimes fail indicate race conditions or environment sensitivity.\n\n**Example:**\n- Test passes locally but fails on CI\n- Test passes first run of suite, fails on second run\n- Test passes on Windows but fails on Linux\n\n**How to analyze:**\n- Look for timeout races: is timing involved in the test?\n- Check for test isolation issues: does one test affect another?\n- Verify environment differences: CI vs. local paths, permissions, versions\n- Look for external dependencies: network calls, file I/O, process interactions\n\n## Key Artifacts and Locations\n\n| Item | Purpose | Location |\n|------|---------|----------|\n| Test result XML | Pester output with test cases, failures, errors | Workflow artifacts: `junit-pester-*.xml` |\n| Job logs | Full job output including test execution and errors | GitHub Actions run logs or `gh run download` |\n| Stack traces | Error location information from failed assertions | Within job logs and XML failure messages |\n| Test files | The actual Pester test code (`.ps1` files) | `test/` directory in repository |\n\n## Analysis Workflow\n\n### ⚠️ Important: These Steps MUST Be Followed In Order\n\nEach step depends on the previous one. Skipping or re-ordering steps causes incomplete analysis:\n\n- **Step 1** (identify jobs) → You get the RUN_ID needed for Step 2\n- **Step 2** (download) → You get the artifacts needed for Step 3  \n- **Step 3** (extract) → You discover what failures exist for Step 4\n- **Step 4** (read messages) → You understand the errors to analyze in Step 5\n- **Step 5** (context) → You gather information to make recommendations in Step 6\n- **Step 6** (interpret) → You use all above to recommend fixes\n\n**Real Problem We Had**:\n- ❌ Jumped to Step 3 without Step 1-2\n- ❌ Used random test data from context instead of downloading PR artifacts\n- ❌ Skipped Steps 5-6 entirely\n- ❌ Made recommendations without full context\n\n**Result**: Wrong analysis and recommendations that didn't actually fix the problem.\n\n### Recommended: Use the Automated Script\n\n```powershell\n./.github/skills/analyze-pester-failures/scripts/analyze-pr-test-failures.ps1 -PR <PR_NUMBER>\n```\n\nThis enforces the workflow and prevents skipping.\n\n### Step 2: Get Test Results\n\nFetch the test result artifacts and job logs:\n\n```powershell\n# Download artifacts including test XML results\ngh run download <RUN_ID> --dir ./artifacts\n\n# Get job logs\ngh run view <RUN_ID> --log > test-logs.txt\n\n# Inspect test XML\n$xml = [xml](Get-Content ./artifacts/junit-pester-*.xml)\n$xml.'test-results' | Select-Object total, failures, errors, ignored, inconclusive\n```\n\n### Step 3: Extract Specific Failures\n\nFind the failing test cases in the XML:\n\n```powershell\n# Get all failed test cases\n$xml = [xml](Get-Content ./artifacts/junit-pester-*.xml)\n$failures = $xml.SelectNodes('.//test-case[@result = \"Failure\"]')\n\n# For each failure, display key info\n$failures | ForEach-Object {\n    [PSCustomObject]@{\n        Name = $_.name\n        Description = $_.description\n        Message = $_.failure.message\n        StackTrace = $_.failure.'stack-trace'\n    }\n}\n```\n\n### Step 4: Read the Error Message\n\nThe error message tells you what went wrong:\n\n**Assertion failures:**\n```\nExpected $true but got $false\nExpected \"value1\" but got \"value2\"\nExpression should have failed with exception, but didn't\n```\n\n**Exceptions:**\n```\nCannot find a parameter with name 'Name'\nProperty 'Property' does not exist on 'Object'\nCannot bind argument to parameter because it is null\n```\n\n**Timeouts:**\n```\nTest timed out after 30 seconds\nTest is taking too long to complete\n```\n\n### Step 5: Understand the Context\n\nLook at the test file to understand what was being tested:\n\n```powershell\n# Find the test file mentioned in the stack trace\n# Example: /path/to/test/Feature.Tests.ps1:42\n\n# Read the test code around that line\ncode <test-file-path>:<line-number>\n\n# Understand:  \n# - What assertion is on that line?\n# - What is the test trying to verify?\n# - What are the setup/mock/before conditions?\n# - Are there recent changes to the function being tested?\n```\n\n### Step 6: Interpret the Failure\n\nDetermine the root cause category:\n\n**Test issue (needs code fix):**\n- Assertion logic is wrong\n- Test expectations don't match actual behavior\n- Test setup is incomplete\n- Mock/stub configuration missing\n\n**Environmental issue (needs environment change):**\n- Test assumes a specific file or registry entry exists\n- Test requires Windows/Linux specifically\n- Test requires specific PowerShell version\n- Test requires specific module version\n- Timing-sensitive test affected by CI load\n\n**Data issue (needs input data change):**\n- Test data no longer valid\n- External API changed format\n- Configuration file has changed structure\n\n**Flakiness (needs test hardening):**\n- Race condition in test\n- Timing assumptions too tight\n- Resource contention on CI runner\n- Non-deterministic behavior in tested code\n\n## Common Test Failure Patterns\n\n| Pattern | What It Means | Example | Next Step |\n|---------|---------------|---------|-----------|\n| `Expected $true but got $false` | Assertion on boolean result failed | Test expects function returns true, but it returns false | Check function logic for bug or test logic for wrong expectation |\n| `Cannot find path` | File or directory doesn't exist | Test tries to read config file that's not present | Verify file path, check test setup, ensure CI environment has file |\n| `Cannot bind argument to parameter 'X'` | Required parameter value is null or wrong type | Function called with $null where object expected | Check test mock setup, verify parameter types |\n| `Test timed out after X seconds` | Test exceeded time limit | Network call or loop takes too long | Increase timeout for slow test, find infinite loop, mock network calls |\n| `Expression should have failed but didn't` | Exception wasn't thrown when expected | Test expects error but function succeeds | Check if function behavior changed, update test expectation |\n| `Could not find parameter 'X'` | Function doesn't have parameter | Test calls function with parameter that doesn't exist | Check PowerShell version, verify function signature, update test |\n| `This platform is not supported` | Test skipped on current OS | Windows-only test running on Linux | Add platform check, update test environment, or mark as platform-specific |\n| `Test marked [Ignore]` | Test explicitly disabled | Test has `[Ignore(\"reason\")]` attribute | Check if reason still valid, remove if issue fixed |\n\n## Interpreting Test Results\n\n### Test Result Counts\n\nPester test outcomes are categorized as:\n\n| Count | Meaning | Notes |\n|-------|---------|-------|\n| `total` | Total number of test cases executed | Should match: passed + failed + errors + skipped + ignored |\n| `failures` | Test assertions that failed | `Expected X but got Y` type failures |\n| `errors` | Tests that threw exceptions | Unhandled PowerShell exceptions during test |\n| `skipped` | Tests explicitly skipped (marked with `-Skip`) | Test code recognizes condition and skips |\n| `ignored` | Tests marked as ignored (marked with `-Ignore`) | Test disabled intentionally, usually notes reason |\n| `inconclusive` | Tests with unclear result | Rare; usually means test framework issue |\n| `passed` | Tests with passing assertions | `total - failures - errors - skipped - ignored` |\n\n### Stack Trace Interpretation\n\nA stack trace shows where the failure occurred:\n\n```\nat /home/runner/work/PowerShell/test/Feature.Tests.ps1:42\n\nMeans:\n- File: /home/runner/work/PowerShell/test/Feature.Tests.ps1\n- Line: 42\n- Look at that line to see which assertion failed\n```\n\n### Understanding Skipped Tests\n\nWhen XML shows `result=\"Ignored\"` or `result=\"Skipped\"`:\n\n```xml\n<test-case name=\"Test Name\" result=\"Ignored\">\n  <reason>Only runs on Windows</reason>\n</test-case>\n```\n\nThe reason explains why test didn't run. Not a failure, but important for understanding test coverage.\n\n## Providing Test Failure Analysis\n\n### Investigation Questions\n\nAfter gathering test output, ask yourself:\n\n1. **Is the test code correct?**\n   - Does the test assertion match the expected behavior?\n   - Are test expectations still valid?\n   - Has the function being tested changed?\n\n2. **Is the test setup correct?**\n   - Are mocks/stubs configured properly?\n   - Does the test environment have required files/configuration?\n   - Are preconditions (database, files, services) met?\n\n3. **Is this a code bug or test issue?**\n   - Does the tested function have a logic error?\n   - Or does the test have incorrect expectations?\n\n4. **Is this environment-specific?**\n   - Only fails on Windows/Linux?\n   - Only fails on CI but passes locally?\n   - Timing-dependent or resource-dependent?\n\n5. **Is this a known/expected failure?**\n   - Is there already an issue tracking this failure?\n   - Is the test marked as flaky or expected to fail?\n   - Does the skip/ignore reason still apply?\n\n### Recommendation Framework\n\nBased on your analysis:\n\n| Finding | Recommendation |\n|---------|-----------------|\n| Test logic is wrong | \"Test assertion on line X is incorrect. Test expects Y but function correctly returns Z. Update test expectation.\" |\n| Tested code has bug | \"Function at file.ps1#L42 has logic error. When X happens, returns Y instead of Z. Fix the condition.\" |\n| Missing test setup | \"Test setup incomplete. Mock for dependency Y is not configured. Add `Mock Get-Y -MockWith { ... }`\" |\n| Environment issue | \"Test is Windows-specific but running on Linux. Either add platform check or skip on non-Windows.\" |\n| Flaky test | \"Test is timing-sensitive (sleep 1 second). Increase timeout or use better synchronization.\" |\n| Test should be skipped | \"Test is marked Ignored for good reason. Keep it disabled until issue #12345 is fixed.\" |\n\n### Tone and Structure\n\nProvide analysis as:\n\n1. **Summary** (1 sentence): What test is failing and general category  \n2. **Failure Details** (2-3 sentences): What the test output says  \n3. **Root Cause** (1-2 sentences): Why it's failing (test bug vs. code bug vs. environment)\n4. **Recommendation** (actionable): What should be done to fix it  \n5. **Context** (optional): Link to related code, issues, or recent changes\n\n## Examples\n\n### Example 1: Assertion Failure Due to Code Bug\n\n**Test Output:**\n```\nExpected 5 but got 3 at /path/to/Test.ps1:42\n```\n\n**Investigation:**\n1. Look at line 42: `$result | Should -Be 5`\n2. Check the test: It expects function to return 5 items\n3. Check the function: It returns `$items | Where-Object {$_.Status -eq \"Active\"}` but the filter is wrong\n4. Root cause: Function has logic error, not test error\n\n**Recommendation:**\n```\nTest failure is due to a code bug:\n\nThe test Set-Configuration should return 5 items but returns 3.\n\nLooking at the tested function at [module.ps1#L42](module.ps1#L42):\n  $activeItems = $items | Where-Object {$_.Status -eq \"Active\"}\n\nThe issue is the filter condition. It's currently filtering by \"Active\" status,\nbut should include \"Pending\" status as well. \n\nFix: Change line 42 to:\n  $activeItems = $items | Where-Object {$_.Status -ne \"Disabled\"}\n\nThen re-run the test to verify it now returns 5 items as expected.\n```\n\n### Example 2: Test Setup Issue\n\n**Test Output:**\n```\nCannot find path '/expected/config.json' because it does not exist at /path/to/Test.ps1:15\n```\n\n**Investigation:**\n1. Line 15 tries to read a config file\n2. The test setup doesn't create this file\n3. Works locally but fails on CI because CI doesn't have the same file\n\n**Recommendation:**\n```\nTest setup is incomplete:\n\nThe test Initialize-Config fails because it expects /expected/config.json but the test doesn't create this file.\n\nThe test needs to ensure the config file exists. Currently line 12-14 doesn't set up the file:\n\n  # Before:\n  # (no setup of config file)\n\n  # After:\n  @{ setting1 = \"value1\"; setting2 = \"value2\" } | ConvertTo-Json | \n    Out-File $testConfigPath\n\nAlternatively, the test function should accept a parameter for the config path and use a temporary file:\n  param([string]$ConfigPath = (New-TemporaryFile))\n\nRe-run the test to verify the config file is properly available.\n```\n\n### Example 3: Platform-Specific Test Failure\n\n**Test Output:**\n```\nTest 'should read Windows Registry' failed on Linux runner\nCannot find path 'HKEY_LOCAL_MACHINE:\\...'\n```\n\n**Investigation:**\n1. Test assumes Windows Registry exists (Windows-only)\n2. Running on Linux runner doesn't have Registry\n3. Test should skip on non-Windows platforms\n\n**Recommendation:**\n```\nTest is platform-specific but running on wrong platform:\n\nThe test \"should read Windows Registry\" assumes Windows Registry exists but is running on Linux.\n\nAdd a platform check to skip this test on non-Windows systems:\n\n  It \"should read Windows Registry\" -Skip:$(-not $IsWindows) {\n    # test code here\n  }\n\nOr group Windows-only tests in a separate Describe block with platform check:\n\n  Describe \"Windows Registry Tests\" -Skip:$(-not $IsWindows) {\n    # all Windows-specific tests here\n  }\n\nThis allows the test to be skipped on Linux/Mac while still running on Windows CI.\n```\n\n## References\n\n- [Pester Testing Framework](https://pester.dev/) — Official documentation, best practices for test writing\n- [Test Files](../../../test/) — PowerShell test suite in repository\n- [GitHub Actions Documentation](https://docs.github.com/en/actions) — Understanding workflow runs and logs\n- [PowerShell Documentation](https://learn.microsoft.com/en-us/powershell/) — Language reference for understanding test code\n\n## Tips\n\n1. **Read the error message first:** The error message is usually the most direct clue to the problem\n2. **Check test vs. code blame:** Is the test wrong or is the code wrong? Look at both sides\n3. **Verify test isolation:** Does one test failure affect others? Check for shared state or test ordering dependencies\n4. **Test locally first:** Try running the failing test locally to reproduce and understand it better\n5. **Check for environmental assumptions:** Windows-specific paths, module versions, file locations may differ on CI\n6. **Look for skip/ignore patterns:** If a test is consistently ignored, check if the reason is still valid\n7. **Compare passing vs. failing:** If test passes locally but fails on CI, the difference is usually environment-related\n8. **Check recent changes:** Did a recent PR change the tested code or test itself?\n9. **Understand Pester output format:** Different Pester versions, different `-ErrorAction`, `-WarningAction` produce different test results\n10. **Don't assume CI is wrong:** Failures on CI often reveal real issues that local testing missed (network, file permissions, parallelization, etc.)\n\n## Additional Links\n\n- [PowerShell Repository](https://github.com/PowerShell/PowerShell)\n- [GitHub Actions Documentation](https://docs.github.com/en/actions)\n- [Pester Testing Framework](https://github.com/Pester/Pester)\n","test/tools/TestMetadata.json":"{\n  \"ExperimentalFeatures\": {\n    \"ExpTest.FeatureOne\": [ \"test/powershell/engine/ExperimentalFeature/ExperimentalFeature.Basic.Tests.ps1\" ],\n    \"PSSerializeJSONLongEnumAsNumber\": [ \"test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertTo-Json.PSSerializeJSONLongEnumAsNumber.Tests.ps1\" ]\n  }\n}\n","tools/metadata.json":"{\n  \"StableReleaseTag\": \"v7.6.9\",\n  \"PreviewReleaseTag\": \"v7.7.0-preview.5\",\n  \"ServicingReleaseTag\": \"v7.0.13\",\n  \"ReleaseTag\": \"v7.6.9\",\n  \"LTSReleaseTag\": [\"v7.4.22\", \"v7.6.9\"],\n  \"NextReleaseTag\": \"v7.7.0-preview.6\",\n  \"LTSRelease\": { \"PublishToChannels\": false, \"Package\": false },\n  \"StableRelease\":  { \"PublishToChannels\": false, \"Package\": false }\n}\n","tools/install-powershell.sh-README.md":"# install-powershell.sh\n\n## Features of install-powershell.sh\n\n* Can be called directly from git\n* Optionally installs vs code and vs powershell extension (aka PowerShell IDE) using optional `-includeide` switch\n* Defaults to completely automated operation (if appropriate permissions are available)\n* Automatically looks up latest version via git tags\n* Automatic selection of appropriate install sub-script\n* Configures software installs for repositories when repositories are in place, otherwise pulls files from git releases.  As repository versions are made available, script will be updated to take advantage.\n* User permission checking\n* Sub-installers called from local file system if they exist, otherwise pulled from git\n* Sub-installers can be called directly if auto-selection is not needed\n\n## Minimum Requirements for install-powershell.sh\n\n* bash shell\n* `sed`\n* native package manager available\n* `curl` (auto-installed if missing)\n* `tr`\n\n## Parameters\n\n* -includeide - installs VSCode and VSCode PowerShell extension (only relevant to machines with a desktop environment)\n* -interactivetesting - do a quick launch test of VSCode (only relevant when used with -includeide)\n* -skip-sudo-check - use sudo without verifying its availability (hard to accurately do on some distros)\n* -preview - installs the latest preview release of PowerShell core side-by-side with any existing production releases\n\n## Usage\n\n### Direct from Github\n\n```bash\nbash <(wget -O - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.sh) <ARGUMENTS>\n\nwget -O - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.sh | bash -s <ARGUMENTS>\n```\n\n### Local Copy\n\n```bash\nbash install-powershell.sh <ARGUMENTS>\n```\n\n## Examples\n\n### Only Install PowerShell Core\n\n```bash\nbash <(wget -O - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.sh)\n```\n\n### Install PowerShell Core with IDE\n\n```bash\nbash <(wget -O - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.sh) -includeide\n```\n\n### Install PowerShell Core with IDE and do tests that require a human to interact with the installation process\n\n```bash\nbash <(wget -O - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.sh) -includeide -interactivetesting\n```\n\n### Installation To do list\n\n* Detect and wait when package manager is busy/locked? - at least Ubuntu (CentOS does this internally)\n","tools/findMissingNotices.targets.json":"{\n  \"dotnetTargetName\": \"net11.0\",\n  \"windowsTargetNames\": [\n  ]\n}\n",".github/agents/SplitADOPipelines.agent.md":"---\nname: SplitADOPipelines\ndescription: This agent will implement and restructure the repository's existing ADO pipelines into Official and NonOfficial pipelines.\ntools: ['vscode', 'execute', 'read', 'agent', 'edit', 'search', 'todo']\n---\n\nThis agent will implement and restructure the repository's existing ADO pipelines into Official and NonOfficial pipelines. \n\nA repository will have under the .pipelines directory a series of yaml files that define the ADO pipelines for the repository.\n\nFirst confirm if the pipelines are using a toggle switch for Official and NonOfficial. This will look something like this\n\n```yaml\nparameters:\n  - name: templateFile\n    value: ${{ iif ( parameters.OfficialBuild, 'v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates', 'v2/OneBranch.NonOfficial.CrossPlat.yml@onebranchTemplates' ) }}\n```\n\nFollowed by:\n\n```yaml\nextends:\n  template: ${{ variables.templateFile }}\n```\n\nThis is an indicator that this work needs to be done. This toggle switch is no longer allowed and the templates need to be hard coded.\n\n## Template Reference Convention (MUST follow)\n\nAll `- template:` references to files **inside this repo** must use the **absolute** form anchored at the repo root, with the `@self` suffix:\n\n```yaml\n- template: /.pipelines/templates/<path>/<file>.yml@self\n```\n\nDo **not** use relative paths such as `templates/...`, `../templates/...`, or bare filenames. Rationale:\n\n- Absolute paths resolve identically regardless of where the referring file lives, so moving a pipeline file between directories (for example, into `.pipelines/NonOfficial/`) does not silently break includes.\n- Relative paths are resolved by Azure DevOps against the directory of the referring file, which has caused real outages in this repo when a relative include was composed into a nonexistent nested path like `.pipelines/templates/stages/.pipelines/templates/...`.\n- The majority of existing includes already use the absolute form; keeping new work consistent reduces review burden.\n\nThe only acceptable non-absolute references are to external repositories resolved via the `resources.repositories` block, for example `v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates`.\n\n## Refactoring Steps\n\n### Step 1: Extract Shared Templates\n\nFor each pipeline file that uses the toggle switch pattern (e.g., `PowerShell-Packages-Official.yml`):\n\n1. Create the `.pipelines/templates/variables` and `.pipelines/templates/stages` directories if they don't exist\n2. Extract the **variables section** into `.pipelines/templates/variables/PowerShell-Packages-Variables.yml`\n3. Extract the **stages section** into `.pipelines/templates/stages/PowerShell-Packages-Stages.yml`\n\n**IMPORTANT**: Only extract the `variables:` and `stages:` sections. All other sections (parameters, resources, extends, etc.) remain in the pipeline files.\n\n### Step 2: Create Official Pipeline (In-Place Refactoring)\n\nThe original toggle-based file becomes the Official pipeline:\n\n1. **Keep the file in its original location** (e.g., `.pipelines/PowerShell-Packages-Official.yml` stays where it is)\n2. Remove the toggle switch parameter (`templateFile` parameter)\n3. Hard-code the Official template reference:\n   ```yaml\n   extends:\n     template: v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates\n   ```\n4. Replace the `variables:` section with a template reference:\n   ```yaml\n   variables:\n     - template: /.pipelines/templates/variables/PowerShell-Packages-Variables.yml@self\n   ```\n5. Replace the `stages:` section with a template reference:\n   ```yaml\n   stages:\n     - template: /.pipelines/templates/stages/PowerShell-Packages-Stages.yml@self\n   ```\n\n### Step 3: Create NonOfficial Pipeline\n\n1. Create `.pipelines/NonOfficial` directory if it doesn't exist\n2. Create the NonOfficial pipeline file (e.g., `.pipelines/NonOfficial/PowerShell-Packages-NonOfficial.yml`)\n3. Copy the structure from the refactored Official pipeline\n4. Hard-code the NonOfficial template reference:\n   ```yaml\n   extends:\n     template: v2/OneBranch.NonOfficial.CrossPlat.yml@onebranchTemplates\n   ```\n5. Reference the same shared templates:\n   ```yaml\n   variables:\n     - template: /.pipelines/templates/variables/PowerShell-Packages-Variables.yml@self\n   \n   stages:\n     - template: /.pipelines/templates/stages/PowerShell-Packages-Stages.yml@self\n   ```\n\n**Note**: Always use **absolute** template paths of the form `/.pipelines/templates/...@self`. Do not use relative paths like `templates/...` or `../templates/...`. Absolute paths are anchored at the repo root and resolve consistently from any referring file, preventing breakage when files are moved between directories.\n\n### Step 4: Link NonOfficial Pipelines to NonOfficial Dependencies\n\nAfter creating NonOfficial pipelines, ensure they consume artifacts from other **NonOfficial** pipelines, not Official ones.\n\n1. **Check the `resources:` section** in each NonOfficial pipeline for `pipelines:` dependencies\n2. **Identify Official pipeline references** that need to be changed to NonOfficial\n3. **Update the `source:` field** to point to the NonOfficial version\n\n**Example Problem:** NonOfficial pipeline pointing to Official dependency\n```yaml\nresources:\n  pipelines:\n    - pipeline: CoOrdinatedBuildPipeline\n      source: 'PowerShell-Coordinated Binaries-Official'  # ❌ Wrong - Official!\n```\n\n**Solution:** Update to NonOfficial dependency\n```yaml\nresources:\n  pipelines:\n    - pipeline: CoOrdinatedBuildPipeline\n      source: 'PowerShell-Coordinated Binaries-NonOfficial'  # ✅ Correct - NonOfficial!\n```\n\n**IMPORTANT**: The `source:` field must match the **exact ADO pipeline definition name** as it appears in Azure DevOps, not necessarily the file name.\n\n### Step 5: Configure Release Environment Parameters (NonAzure Only)\n\n**This step only applies if the pipeline uses `category: NonAzure` in the release configuration.**\n\nIf you detect this pattern in the original pipeline:\n\n```yaml\nextends:\n  template: v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates  # or NonOfficial\n  parameters:\n    release:\n      category: NonAzure\n```\n\nThen you must configure the `ob_release_environment` parameter when referencing the stages template.\n\n#### Official Pipeline Configuration\n\nIn the Official pipeline (e.g., `.pipelines/PowerShell-Packages-Official.yml`):\n\n```yaml\nstages:\n  - template: /.pipelines/templates/stages/PowerShell-Packages-Stages.yml@self\n    parameters:\n      ob_release_environment: Production\n```\n\n#### NonOfficial Pipeline Configuration\n\nIn the NonOfficial pipeline (e.g., `.pipelines/NonOfficial/PowerShell-Packages-NonOfficial.yml`):\n\n```yaml\nstages:\n  - template: /.pipelines/templates/stages/PowerShell-Packages-Stages.yml@self\n    parameters:\n      ob_release_environment: Test\n```\n\n#### Update Stages Template to Accept Parameter\n\nThe extracted stages template (e.g., `.pipelines/templates/stages/PowerShell-Packages-Stages.yml`) must declare the parameter at the top:\n\n```yaml\nparameters:\n  - name: ob_release_environment\n    type: string\n\nstages:\n  # ... rest of stages configuration using ${{ parameters.ob_release_environment }}\n```\n\n**IMPORTANT**: \n- Only configure this for pipelines with `category: NonAzure`\n- Official pipelines always use `ob_release_environment: Production`\n- NonOfficial pipelines always use `ob_release_environment: Test`\n- The stages template must accept this parameter and use it in the appropriate stage configurations\n","tools/guardian/tsaconfig-apiscan.json":"{\n  \"codebaseName\": \"PowerShellCore_201906\",\n  \"tools\": [\n      \"APIScan\"\n  ]\n}\n","tools/credScan/suppress.json":"{\n    \"tool\": \"Credential Scanner\",\n    \"suppressions\": [\n      {\n       \"file\": \"\\\\test\\\\tools\\\\Modules\\\\WebListener\\\\ClientCert.pfx\",\n        \"_justification\": \"Test certificate with private key\"\n      },\n      {\n        \"file\": \"\\\\test\\\\tools\\\\Modules\\\\WebListener\\\\ServerCert.pfx\",\n         \"_justification\": \"Test certificate with private key\"\n       },\n       {\n         \"file\": \"\\\\test\\\\powershell\\\\Modules\\\\Microsoft.PowerShell.Security\\\\certificateCommon.psm1\",\n          \"_justification\": \"Test certificate with private key and inline suppression isn't working\"\n        }\n     ]\n}\n","tools/guardian/tsaconfig-others.json":"{\n  \"codebaseName\": \"PowerShellCore_201906\",\n  \"tools\": [\n      \"CredScan\",\n      \"PoliCheck\"\n  ]\n}\n","tools/AttackSurfaceAnalyzer/README.md":"# Attack Surface Analyzer Testing\n\nThis directory contains tools for running Attack Surface Analyzer (ASA) tests on PowerShell MSI installations using Docker.\n\n## Overview\n\nAttack Surface Analyzer is a Microsoft tool that helps analyze changes to a system's attack surface. These scripts allow you to run ASA tests locally in a clean Windows container to analyze what changes when PowerShell is installed.\n\n## Files\n\n- **Run-AttackSurfaceAnalyzer.ps1** - PowerShell script to run ASA tests with official MSIs\n- **Summarize-AsaResults.ps1** - PowerShell script to analyze and summarize ASA results\n- **docker/Dockerfile** - Multi-stage Dockerfile for building a container image with ASA pre-installed\n- **README.md** - This documentation file\n\n## Docker Architecture\n\nThe Docker implementation uses a multi-stage build to optimize the testing and result extraction process:\n\n### Multi-Stage Build Stages\n\n1. **asa-runner**: Main execution environment\n   - Base: `mcr.microsoft.com/dotnet/sdk:9.0-windowsservercore-ltsc2022`\n   - Contains Attack Surface Analyzer CLI tools\n   - Runs the complete test workflow\n   - Generates reports in both `C:\\work` and `C:\\reports` directories\n\n1. **asa-reports**: Minimal results layer\n   - Base: `mcr.microsoft.com/windows/nanoserver:ltsc2022`\n   - Contains only the test reports from the runner stage\n   - Enables clean extraction of results without container internals\n\n1. **final**: Default stage (inherits from asa-runner)\n   - Provides backward compatibility\n   - Used when no specific build target is specified\n\n### Benefits\n\n- **Clean Result Extraction**: Reports are isolated in a dedicated layer\n- **Efficient Transfer**: Only test results are copied, not the entire container filesystem\n- **Fallback Support**: Script includes fallback to volume-based extraction if needed\n- **Minimal Footprint**: Final results layer contains only the necessary output files\n\n## Prerequisites\n\n- Windows 10/11 or Windows Server\n- Docker Desktop with Windows containers enabled\n- PowerShell 5.1 or later\n- **An official signed PowerShell MSI file** from a released build\n\n### MSI Requirements\n\n**Important:** This tool now requires an official, digitally signed PowerShell MSI from Microsoft releases:\n\n- **Must be signed** by Microsoft Corporation\n- **Must be from an official release** (downloaded from [PowerShell Releases](https://github.com/PowerShell/PowerShell/releases))\n- **Local builds are not supported** - unsigned or development MSIs will be rejected\n- The script automatically verifies the digital signature before proceeding\n\n**Where to get official MSIs:**\n\n- Download from: https://github.com/PowerShell/PowerShell/releases\n- Look for files like: `PowerShell-7.x.x-win-x64.msi`\n\n## Quick Start\n\n### Option 1: Using the PowerShell Script (Recommended)\n\nThe script requires an official signed PowerShell MSI file:\n\n```powershell\n# Run ASA test with official MSI (MsiPath is required)\n.\\tools\\AttackSurfaceAnalyzer\\Run-AttackSurfaceAnalyzer.ps1 -MsiPath \"C:\\path\\to\\PowerShell-7.4.0-win-x64.msi\"\n\n# Specify custom output directory for results\n.\\tools\\AttackSurfaceAnalyzer\\Run-AttackSurfaceAnalyzer.ps1 -MsiPath \".\\PowerShell-7.4.0-win-x64.msi\" -OutputPath \"C:\\asa-results\"\n\n# Keep the temporary work directory for debugging\n.\\tools\\AttackSurfaceAnalyzer\\Run-AttackSurfaceAnalyzer.ps1 -MsiPath \".\\PowerShell-7.4.0-win-x64.msi\" -KeepWorkDirectory\n```\n\nThe script will:\n\n1. **Verify MSI signature** - Ensures the MSI is officially signed by Microsoft Corporation\n1. Create a temporary work directory\n1. Build a custom Docker container from the static Dockerfile\n1. Start the Windows container with Attack Surface Analyzer\n1. Take a baseline snapshot\n1. Install the PowerShell MSI\n1. Take a post-installation snapshot\n1. Export comparison results\n1. Copy results back to your specified output directory\n\n**Security Note:** The script will reject any MSI that is not digitally signed by Microsoft Corporation to ensure analysis is performed only on official releases.\n\n### Option 2: Using the Dockerfile\n\nIf you prefer to build and use the container image directly:\n\n```powershell\n# Build the Docker image (Dockerfile is in docker subfolder with clean context)\ndocker build -f tools\\AttackSurfaceAnalyzer\\docker\\Dockerfile -t powershell-asa-test tools\\AttackSurfaceAnalyzer\\docker\\\n\n# Run the container with your MSI (script is built into the container)\ndocker run --rm --isolation process `\n  -v \"C:\\path\\to\\msi\\directory:C:\\work\" `\n  powershell-asa-test\n```\n\n## Output Files\n\nThe test will generate output files in the `./asa-results/` directory (or your specified `-OutputPath`):\n\n- **`asa.sqlite`** - SQLite database with full analysis data (primary result file)\n- **`install.log`** - MSI installation log file\n- **`*_summary.json.txt`** - Summary of detected changes (if generated)\n- **`*_results.json.txt`** - Detailed results in JSON format (if generated)\n- **`*.sarif`** - SARIF format results (if generated, can be viewed in VS Code)\n\n## Analyzing Results\n\n### Using the Summary Script (Recommended)\n\nUse the included summary script to get a comprehensive analysis:\n\n```powershell\n# Basic summary of ASA results\n.\\tools\\AttackSurfaceAnalyzer\\Summarize-AsaResults.ps1\n\n# Detailed analysis with rule breakdowns\n.\\tools\\AttackSurfaceAnalyzer\\Summarize-AsaResults.ps1 -ShowDetails\n\n# Analyze results from a specific location\n.\\tools\\AttackSurfaceAnalyzer\\Summarize-AsaResults.ps1 -Path \"C:\\custom\\path\\asa-results.json\" -ShowDetails\n```\n\nThe summary script provides:\n\n- **Overall statistics** - Total findings, analysis levels, category breakdowns\n- **Rule analysis** - Which security rules were triggered and how often\n- **File analysis** - Detailed breakdown of file-related security issues by rule type\n- **Category cross-reference** - Shows which rules affect which categories\n\n### Using VS Code\n\nThe SARIF files can be opened directly in VS Code with the SARIF Viewer extension to see a formatted view of the findings.\n\n### Using PowerShell\n\n```powershell\n# Read the JSON results directly\n$results = Get-Content \"asa-results\\asa-results.json\" | ConvertFrom-Json\n$results.Results.FILE_CREATED.Count  # Number of files created\n\n# Query the SQLite database (requires SQLite tools)\n# Example: List all file changes\n# sqlite3 asa.sqlite \"SELECT * FROM file_system WHERE change_type != 'NONE'\"\n```\n\n## Troubleshooting\n\n### Docker Not Available\n\nThe script automatically handles Docker Desktop installation and startup:\n\n**If Docker Desktop is installed but not running:**\n\n- The script will automatically start Docker Desktop for you\n- It waits up to 60 seconds for Docker to become available\n- You'll be prompted for confirmation (supports `-Confirm` and `-WhatIf`)\n\n**If Docker Desktop is not installed:**\n\n- The script will prompt you to install it automatically using winget\n- After installation completes, start Docker Desktop and run the script again\n\n**Manual Installation:**\n\n1. Install Docker Desktop from https://www.docker.com/products/docker-desktop\n1. Ensure Docker is running\n1. Switch to Windows containers (right-click Docker tray icon → \"Switch to Windows containers\")\n\n### Container Fails to Start\n\n- Ensure you have enough disk space (containers can be large)\n- Check that Windows containers are enabled in Docker settings\n- Try pulling the base image manually: `docker pull mcr.microsoft.com/dotnet/sdk:9.0-windowsservercore-ltsc2022`\n\n### MSI Signature Verification Fails\n\nIf you get signature verification errors:\n\n- **Ensure you're using an official MSI** from [PowerShell Releases](https://github.com/PowerShell/PowerShell/releases)\n- **Do not use local builds** - only signed release MSIs are supported  \n- **Check certificate validity** - very old MSIs may have expired certificates\n- **Verify file integrity** - redownload the MSI if it may be corrupted\n\n### No Results Generated\n\n- Check the install.log file for MSI installation errors\n- Run with `-KeepWorkDirectory` to inspect the temporary work directory\n- Verify the MSI file is valid and not corrupted\n\n## Advanced Usage\n\n### Parameters\n\nThe `Run-AttackSurfaceAnalyzer.ps1` script supports these parameters:\n\n- **`-MsiPath`** (Required) - Path to the official signed PowerShell MSI file\n- **`-OutputPath`** (Optional) - Directory for results (defaults to `./asa-results`)\n- **`-ContainerImage`** (Optional) - Custom container base image\n- **`-KeepWorkDirectory`** (Optional) - Keep temp directory for debugging\n\nExample with custom container image:\n\n```powershell\n.\\tools\\AttackSurfaceAnalyzer\\Run-AttackSurfaceAnalyzer.ps1 `\n  -MsiPath \".\\PowerShell-7.4.0-win-x64.msi\" `\n  -ContainerImage \"mcr.microsoft.com/dotnet/sdk:8.0-windowsservercore-ltsc2022\"\n```\n\n### Debugging\n\nTo debug issues, keep the work directory and examine the files:\n\n```powershell\n.\\tools\\AttackSurfaceAnalyzer\\Run-AttackSurfaceAnalyzer.ps1 -KeepWorkDirectory\n\n# The script will print the work directory path\n# You can then examine:\n# - run-asa.ps1 - The script that runs in the container\n# - install.log - MSI installation log\n# - Any other generated files\n```\n\n## Integration with CI/CD\n\nThese tools were extracted from the GitHub Actions workflow to allow local testing. If you need to integrate ASA testing back into a CI/CD pipeline, you can:\n\n1. Use the PowerShell script directly in your pipeline\n1. Build and push the Docker image to a registry\n1. Use the Dockerfile as a base for custom testing scenarios\n\n## More Information\n\n- [Attack Surface Analyzer on GitHub](https://github.com/microsoft/AttackSurfaceAnalyzer)\n- [Docker for Windows Documentation](https://docs.docker.com/desktop/windows/)\n- [SARIF Documentation](https://sarifweb.azurewebsites.net/)\n","tools/install-powershell.ps1-README.md":"# install-powershell.ps1\n\n## Features of install-powershell.ps1\n\n- Can be called directly from Git\n- Optionally allows install of the latest Preview build\n- Optionally installs using the latest MSI\n- Automatically looks up latest version via Git tags\n- Optionally installs silently\n- Optionally adds the install location to Path environment variable\n\n## Examples\n\n### Install PowerShell Preview Build\n\n```PowerShell\nInvoke-Expression \"& { $(Invoke-RestMethod 'https://aka.ms/install-powershell.ps1') } -Preview\"\n```\n\n### Install PowerShell using the MSI installer\n\n```PowerShell\nInvoke-Expression \"& { $(Invoke-RestMethod 'https://aka.ms/install-powershell.ps1') } -UseMSI\"\n```\n","tools/clearlyDefined/readme.md":"# ClearlyDefined\n\n## Purpose\n\nThis tool is intended to test if all the license data in [ClearlyDefined](https://clearlydefined.io) is present to generate the PowerShell license.\nIf the data is not present, it can request that ClearlyDefined gather (called Harvest in their terminology) the data.\n\n## Use\n\n### Testing\n\nRun `./ClearlyDefined.ps1 -test`.\n\nIf there is any missing data, the script should write verbose messages about the missing data and throw.\nIf there is no missing data, the script should not throw.\n\n### Harvesting\n\nRun `./ClearlyDefined.ps1 -Harvest`.\nThe script will trigger the harvest and output the result from ClearlyDefined.\n**Give ClearlyDefined 24 hours to harvest the data.**\nYou can use the `-Test` switch without the `-Harvest` switch to test if Harvesting is done.\n\n## Caching\n\nIf you run in the same PowerShell session, the script will be faster due to caching.\n\nThe module will cache any results from ClearlyDefined that indicate the package is Harvested for 60 minutes.\nNo caching is done for packages that are not yet harvested.\nTo clear the cache, run with the `-ForceModuleReload` switch.\n","tools/packages.microsoft.com/mapping.json":"# Packages.microsoft.com Skill\n\nPath: `tools/packages.microsoft.com/mapping.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/packages.microsoft.com/mapping.json)","tools/performance/README.md":"# performance Documentation\n\nPath: `tools/performance/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/performance/README.md)","test/perf/dotnet-tools/README.md":"# dotnet-tools Documentation\n\nPath: `test/perf/dotnet-tools/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/perf/dotnet-tools/README.md)","test/tools/CodeCoverageAutomation/README.md":"# CodeCoverageAutomation Documentation\n\nPath: `test/tools/CodeCoverageAutomation/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/CodeCoverageAutomation/README.md)","test/tools/WebListener/README.md":"# WebListener Documentation\n\nPath: `test/tools/WebListener/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/WebListener/README.md)","test/tools/WebListener/appsettings.Development.json":"# WebListener Skill\n\nPath: `test/tools/WebListener/appsettings.Development.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/WebListener/appsettings.Development.json)","test/tools/WebListener/appsettings.json":"# WebListener Skill\n\nPath: `test/tools/WebListener/appsettings.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/WebListener/appsettings.json)","tools/cgmanifest/main/cgmanifest.json":"# Main Skill\n\nPath: `tools/cgmanifest/main/cgmanifest.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/cgmanifest/main/cgmanifest.json)","tools/cgmanifest/tpn/cgmanifest.json":"# Tpn Skill\n\nPath: `tools/cgmanifest/tpn/cgmanifest.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/cgmanifest/tpn/cgmanifest.json)",".github/skills/analyze-pester-failures/references/stack-trace-parsing.md":"# References Skill\n\nPath: `.github/skills/analyze-pester-failures/references/stack-trace-parsing.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/.github/skills/analyze-pester-failures/references/stack-trace-parsing.md)","test/perf/dotnet-tools/ResultsComparer/README.md":"# ResultsComparer Documentation\n\nPath: `test/perf/dotnet-tools/ResultsComparer/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/perf/dotnet-tools/ResultsComparer/README.md)","test/tools/Modules/UnixSocket/README.md":"# UnixSocket Documentation\n\nPath: `test/tools/Modules/UnixSocket/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/Modules/UnixSocket/README.md)","test/tools/Modules/WebListener/README.md":"# WebListener Documentation\n\nPath: `test/tools/Modules/WebListener/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/Modules/WebListener/README.md)"},"items":[{"name":"stack-trace-parsing.md","path":".github/skills/analyze-pester-failures/references/stack-trace-parsing.md","rawUrl":"https://raw.githubusercontent.com/PowerShell/powershell/HEAD/.github/skills/analyze-pester-failures/references/stack-trace-parsing.md","title":"References Skill","category":"anthropic-skill","format":"markdown","content":"# References Skill\n\nPath: `.github/skills/analyze-pester-failures/references/stack-trace-parsing.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/.github/skills/analyze-pester-failures/references/stack-trace-parsing.md)","tokens":300,"sizeBytes":265},{"name":"SKILL.md","path":".github/skills/analyze-pester-failures/SKILL.md","rawUrl":"https://raw.githubusercontent.com/PowerShell/powershell/HEAD/.github/skills/analyze-pester-failures/SKILL.md","title":"analyze-pester-failures","category":"anthropic-skill","format":"markdown","content":"---\nname: analyze-pester-failures\ndescription: Troubleshooting guide for analyzing and investigating Pester test failures in PowerShell CI jobs. Help agents understand why tests are failing, interpret test output, navigate test result artifacts, and provide actionable recommendations for fixing test issues.\n---\n\n# Analyze Pester Test Failures\n\nInvestigate and troubleshoot Pester test failures in GitHub Actions workflows. Understand what tests are failing, why they're failing, and provide recommendations for test fixes.\n\n| Skill | When to Use |\n|-------|-----------|\n| analyze-pester-failures | When investigating why Pester tests are failing in a CI job. Use when a test job shows failures and you need to understand what test failed, why it failed, what the error message means, and what might need to be fixed. Also use when asked: \"why did this test fail?\", \"what's the test error?\", \"test is broken\", \"test failure analysis\", \"debug test failure\", or given test failure logs and stack traces. |\n\n## When to Use This Skill\n\nUse this skill when you need to:\n\n- Understand why a specific Pester test is failing  \n- Interpret test failure messages and error output\n- Analyze test result data from CI workflow runs (XML, logs, stack traces)\n- Identify the root cause of test failures (test logic, assertion failure, exception, timeout, skip/ignore reason)\n- Provide recommendations for fixing failing tests\n- Compare expected vs. actual test behavior\n- Debug test environment issues (missing dependencies, configuration problems)\n- Understand test skip/ignored/inconclusive status reasons\n\n**Do not use this skill for:**\n- General PowerShell debugging unrelated to tests\n- Test infrastructure/CI setup issues (except as they affect test failure interpretation)\n- Performance analysis or benchmarking (that's a different investigation)\n\n## Quick Start\n\n### ⚠️ CRITICAL: The Workflow Must Be Followed IN ORDER\n\nThis skill describes a **sequential 6-step analysis workflow**. Skipping steps or jumping around leads to **incomplete analysis and incorrect conclusions**.\n\n**The Problem**: It's easy to skip to Step 4 or 5 without doing Steps 1-2, resulting in missing data and bad conclusions.\n\n**The Solution**: Use the automated analysis script to enforce the workflow:\n\n```powershell\n# Automatically runs Steps 1-6 in order, preventing skipping\n./.github/skills/analyze-pester-failures/scripts/analyze-pr-test-failures.ps1 -PR <PR_NUMBER>\n\n# Example:\n./.github/skills/analyze-pester-failures/scripts/analyze-pr-test-failures.ps1 -PR 26800\n```\n\nThis script:\n1. ✓ Fetches PR status automatically\n2. ✓ Downloads artifacts (can't skip, depends on Step 1)\n3. ✓ Extracts failures (can't skip, depends on Step 2)\n4. ✓ Analyzes error messages\n5. ✓ Documents context\n6. ✓ Generates recommendations\n\n**Only use the manual commands below if you fully understand the workflow.**\n\n### Manual Workflow (for reference)\n\n```powershell\n# Step 1: Identify the failing job\ngh pr view <PR_NUMBER> --json 'statusCheckRollup' | ConvertFrom-Json | Where-Object { $_.conclusion -eq 'FAILURE' }\n\n# Step 2: Download artifacts (extract RUN_ID from Step 1)\ngh run download <RUN_ID> --dir ./artifacts\ngh run view <RUN_ID> --log > test-logs.txt\n\n# Step 3-6: Extract, analyze, and interpret\n# (See Analysis Workflow section below)\n```\n\n## Common Test Failure Analysis Approaches\n\n### 1. **Interpreting Assertion Failures**\nThe most common test failure is when an assertion doesn't match expectations.\n\n**Example:**\n```\nExpected $true but got $false at /path/to/test.ps1:42\nAssertion failed: Should -Be \"expected\" but was \"actual\"  \n```\n\n**How to analyze:**\n- Read the assertion message: what was expected vs. what was actual?\n- Check the test logic: is the expectation correct?\n- Look for mock/stub issues: are dependencies configured correctly?\n- Check parameter values: what inputs were passed to the function under test?\n\n### 2. **Exception Failures**\nTests fail when PowerShell throws an exception instead of successful completion.\n\n**Example:**\n```\nCommand: Write-Host $null\nError: Cannot bind argument to parameter 'Object' because it is null.\n```\n\n**How to analyze:**\n- Read the exception message: what operation failed?\n- Check the stack trace: where in the test or tested code did it throw?\n- Verify preconditions: does the test setup provide required values/mocks?\n- Look for environmental issues: missing modules, permissions, file system state?\n\n### 3. **Timeout Failures**\nA test takes longer than the allowed timeout to complete.\n\n**Example:**\n```\nTest 'Should complete in reasonable time' timed out after 30 seconds\n```\n\n**How to analyze:**\n- Is the timeout appropriate for this test type? (network tests need more time)\n- Is there an infinite loop in the test or tested code?\n- Are there resource contention issues on the CI runner?\n- Does the test hang waiting for something (file lock, network, process)?\n\n### 4. **Skip/Ignored Reason Analysis**\nTests marked as skipped or ignored provide clues about test environment.\n\n**Example:**\n```\nTest marked [Skip(\"Only runs on Windows\")] - running on Linux\nTest marked [Ignore(\"Known issue #12345\")]\n```\n\n**How to analyze:**\n- Read the skip/ignore reason: is it still valid?\n- Check if environment has changed: platform, module versions, etc.\n- Verify issue status: is the known issue still open? Has it been fixed?\n- Determine if skip should be removed or if test needs environment changes\n\n### 5. **Flaky/Intermittent Failures**\nTests that sometimes pass, sometimes fail indicate race conditions or environment sensitivity.\n\n**Example:**\n- Test passes locally but fails on CI\n- Test passes first run of suite, fails on second run\n- Test passes on Windows but fails on Linux\n\n**How to analyze:**\n- Look for timeout races: is timing involved in the test?\n- Check for test isolation issues: does one test affect another?\n- Verify environment differences: CI vs. local paths, permissions, versions\n- Look for external dependencies: network calls, file I/O, process interactions\n\n## Key Artifacts and Locations\n\n| Item | Purpose | Location |\n|------|---------|----------|\n| Test result XML | Pester output with test cases, failures, errors | Workflow artifacts: `junit-pester-*.xml` |\n| Job logs | Full job output including test execution and errors | GitHub Actions run logs or `gh run download` |\n| Stack traces | Error location information from failed assertions | Within job logs and XML failure messages |\n| Test files | The actual Pester test code (`.ps1` files) | `test/` directory in repository |\n\n## Analysis Workflow\n\n### ⚠️ Important: These Steps MUST Be Followed In Order\n\nEach step depends on the previous one. Skipping or re-ordering steps causes incomplete analysis:\n\n- **Step 1** (identify jobs) → You get the RUN_ID needed for Step 2\n- **Step 2** (download) → You get the artifacts needed for Step 3  \n- **Step 3** (extract) → You discover what failures exist for Step 4\n- **Step 4** (read messages) → You understand the errors to analyze in Step 5\n- **Step 5** (context) → You gather information to make recommendations in Step 6\n- **Step 6** (interpret) → You use all above to recommend fixes\n\n**Real Problem We Had**:\n- ❌ Jumped to Step 3 without Step 1-2\n- ❌ Used random test data from context instead of downloading PR artifacts\n- ❌ Skipped Steps 5-6 entirely\n- ❌ Made recommendations without full context\n\n**Result**: Wrong analysis and recommendations that didn't actually fix the problem.\n\n### Recommended: Use the Automated Script\n\n```powershell\n./.github/skills/analyze-pester-failures/scripts/analyze-pr-test-failures.ps1 -PR <PR_NUMBER>\n```\n\nThis enforces the workflow and prevents skipping.\n\n### Step 2: Get Test Results\n\nFetch the test result artifacts and job logs:\n\n```powershell\n# Download artifacts including test XML results\ngh run download <RUN_ID> --dir ./artifacts\n\n# Get job logs\ngh run view <RUN_ID> --log > test-logs.txt\n\n# Inspect test XML\n$xml = [xml](Get-Content ./artifacts/junit-pester-*.xml)\n$xml.'test-results' | Select-Object total, failures, errors, ignored, inconclusive\n```\n\n### Step 3: Extract Specific Failures\n\nFind the failing test cases in the XML:\n\n```powershell\n# Get all failed test cases\n$xml = [xml](Get-Content ./artifacts/junit-pester-*.xml)\n$failures = $xml.SelectNodes('.//test-case[@result = \"Failure\"]')\n\n# For each failure, display key info\n$failures | ForEach-Object {\n    [PSCustomObject]@{\n        Name = $_.name\n        Description = $_.description\n        Message = $_.failure.message\n        StackTrace = $_.failure.'stack-trace'\n    }\n}\n```\n\n### Step 4: Read the Error Message\n\nThe error message tells you what went wrong:\n\n**Assertion failures:**\n```\nExpected $true but got $false\nExpected \"value1\" but got \"value2\"\nExpression should have failed with exception, but didn't\n```\n\n**Exceptions:**\n```\nCannot find a parameter with name 'Name'\nProperty 'Property' does not exist on 'Object'\nCannot bind argument to parameter because it is null\n```\n\n**Timeouts:**\n```\nTest timed out after 30 seconds\nTest is taking too long to complete\n```\n\n### Step 5: Understand the Context\n\nLook at the test file to understand what was being tested:\n\n```powershell\n# Find the test file mentioned in the stack trace\n# Example: /path/to/test/Feature.Tests.ps1:42\n\n# Read the test code around that line\ncode <test-file-path>:<line-number>\n\n# Understand:  \n# - What assertion is on that line?\n# - What is the test trying to verify?\n# - What are the setup/mock/before conditions?\n# - Are there recent changes to the function being tested?\n```\n\n### Step 6: Interpret the Failure\n\nDetermine the root cause category:\n\n**Test issue (needs code fix):**\n- Assertion logic is wrong\n- Test expectations don't match actual behavior\n- Test setup is incomplete\n- Mock/stub configuration missing\n\n**Environmental issue (needs environment change):**\n- Test assumes a specific file or registry entry exists\n- Test requires Windows/Linux specifically\n- Test requires specific PowerShell version\n- Test requires specific module version\n- Timing-sensitive test affected by CI load\n\n**Data issue (needs input data change):**\n- Test data no longer valid\n- External API changed format\n- Configuration file has changed structure\n\n**Flakiness (needs test hardening):**\n- Race condition in test\n- Timing assumptions too tight\n- Resource contention on CI runner\n- Non-deterministic behavior in tested code\n\n## Common Test Failure Patterns\n\n| Pattern | What It Means | Example | Next Step |\n|---------|---------------|---------|-----------|\n| `Expected $true but got $false` | Assertion on boolean result failed | Test expects function returns true, but it returns false | Check function logic for bug or test logic for wrong expectation |\n| `Cannot find path` | File or directory doesn't exist | Test tries to read config file that's not present | Verify file path, check test setup, ensure CI environment has file |\n| `Cannot bind argument to parameter 'X'` | Required parameter value is null or wrong type | Function called with $null where object expected | Check test mock setup, verify parameter types |\n| `Test timed out after X seconds` | Test exceeded time limit | Network call or loop takes too long | Increase timeout for slow test, find infinite loop, mock network calls |\n| `Expression should have failed but didn't` | Exception wasn't thrown when expected | Test expects error but function succeeds | Check if function behavior changed, update test expectation |\n| `Could not find parameter 'X'` | Function doesn't have parameter | Test calls function with parameter that doesn't exist | Check PowerShell version, verify function signature, update test |\n| `This platform is not supported` | Test skipped on current OS | Windows-only test running on Linux | Add platform check, update test environment, or mark as platform-specific |\n| `Test marked [Ignore]` | Test explicitly disabled | Test has `[Ignore(\"reason\")]` attribute | Check if reason still valid, remove if issue fixed |\n\n## Interpreting Test Results\n\n### Test Result Counts\n\nPester test outcomes are categorized as:\n\n| Count | Meaning | Notes |\n|-------|---------|-------|\n| `total` | Total number of test cases executed | Should match: passed + failed + errors + skipped + ignored |\n| `failures` | Test assertions that failed | `Expected X but got Y` type failures |\n| `errors` | Tests that threw exceptions | Unhandled PowerShell exceptions during test |\n| `skipped` | Tests explicitly skipped (marked with `-Skip`) | Test code recognizes condition and skips |\n| `ignored` | Tests marked as ignored (marked with `-Ignore`) | Test disabled intentionally, usually notes reason |\n| `inconclusive` | Tests with unclear result | Rare; usually means test framework issue |\n| `passed` | Tests with passing assertions | `total - failures - errors - skipped - ignored` |\n\n### Stack Trace Interpretation\n\nA stack trace shows where the failure occurred:\n\n```\nat /home/runner/work/PowerShell/test/Feature.Tests.ps1:42\n\nMeans:\n- File: /home/runner/work/PowerShell/test/Feature.Tests.ps1\n- Line: 42\n- Look at that line to see which assertion failed\n```\n\n### Understanding Skipped Tests\n\nWhen XML shows `result=\"Ignored\"` or `result=\"Skipped\"`:\n\n```xml\n<test-case name=\"Test Name\" result=\"Ignored\">\n  <reason>Only runs on Windows</reason>\n</test-case>\n```\n\nThe reason explains why test didn't run. Not a failure, but important for understanding test coverage.\n\n## Providing Test Failure Analysis\n\n### Investigation Questions\n\nAfter gathering test output, ask yourself:\n\n1. **Is the test code correct?**\n   - Does the test assertion match the expected behavior?\n   - Are test expectations still valid?\n   - Has the function being tested changed?\n\n2. **Is the test setup correct?**\n   - Are mocks/stubs configured properly?\n   - Does the test environment have required files/configuration?\n   - Are preconditions (database, files, services) met?\n\n3. **Is this a code bug or test issue?**\n   - Does the tested function have a logic error?\n   - Or does the test have incorrect expectations?\n\n4. **Is this environment-specific?**\n   - Only fails on Windows/Linux?\n   - Only fails on CI but passes locally?\n   - Timing-dependent or resource-dependent?\n\n5. **Is this a known/expected failure?**\n   - Is there already an issue tracking this failure?\n   - Is the test marked as flaky or expected to fail?\n   - Does the skip/ignore reason still apply?\n\n### Recommendation Framework\n\nBased on your analysis:\n\n| Finding | Recommendation |\n|---------|-----------------|\n| Test logic is wrong | \"Test assertion on line X is incorrect. Test expects Y but function correctly returns Z. Update test expectation.\" |\n| Tested code has bug | \"Function at file.ps1#L42 has logic error. When X happens, returns Y instead of Z. Fix the condition.\" |\n| Missing test setup | \"Test setup incomplete. Mock for dependency Y is not configured. Add `Mock Get-Y -MockWith { ... }`\" |\n| Environment issue | \"Test is Windows-specific but running on Linux. Either add platform check or skip on non-Windows.\" |\n| Flaky test | \"Test is timing-sensitive (sleep 1 second). Increase timeout or use better synchronization.\" |\n| Test should be skipped | \"Test is marked Ignored for good reason. Keep it disabled until issue #12345 is fixed.\" |\n\n### Tone and Structure\n\nProvide analysis as:\n\n1. **Summary** (1 sentence): What test is failing and general category  \n2. **Failure Details** (2-3 sentences): What the test output says  \n3. **Root Cause** (1-2 sentences): Why it's failing (test bug vs. code bug vs. environment)\n4. **Recommendation** (actionable): What should be done to fix it  \n5. **Context** (optional): Link to related code, issues, or recent changes\n\n## Examples\n\n### Example 1: Assertion Failure Due to Code Bug\n\n**Test Output:**\n```\nExpected 5 but got 3 at /path/to/Test.ps1:42\n```\n\n**Investigation:**\n1. Look at line 42: `$result | Should -Be 5`\n2. Check the test: It expects function to return 5 items\n3. Check the function: It returns `$items | Where-Object {$_.Status -eq \"Active\"}` but the filter is wrong\n4. Root cause: Function has logic error, not test error\n\n**Recommendation:**\n```\nTest failure is due to a code bug:\n\nThe test Set-Configuration should return 5 items but returns 3.\n\nLooking at the tested function at [module.ps1#L42](module.ps1#L42):\n  $activeItems = $items | Where-Object {$_.Status -eq \"Active\"}\n\nThe issue is the filter condition. It's currently filtering by \"Active\" status,\nbut should include \"Pending\" status as well. \n\nFix: Change line 42 to:\n  $activeItems = $items | Where-Object {$_.Status -ne \"Disabled\"}\n\nThen re-run the test to verify it now returns 5 items as expected.\n```\n\n### Example 2: Test Setup Issue\n\n**Test Output:**\n```\nCannot find path '/expected/config.json' because it does not exist at /path/to/Test.ps1:15\n```\n\n**Investigation:**\n1. Line 15 tries to read a config file\n2. The test setup doesn't create this file\n3. Works locally but fails on CI because CI doesn't have the same file\n\n**Recommendation:**\n```\nTest setup is incomplete:\n\nThe test Initialize-Config fails because it expects /expected/config.json but the test doesn't create this file.\n\nThe test needs to ensure the config file exists. Currently line 12-14 doesn't set up the file:\n\n  # Before:\n  # (no setup of config file)\n\n  # After:\n  @{ setting1 = \"value1\"; setting2 = \"value2\" } | ConvertTo-Json | \n    Out-File $testConfigPath\n\nAlternatively, the test function should accept a parameter for the config path and use a temporary file:\n  param([string]$ConfigPath = (New-TemporaryFile))\n\nRe-run the test to verify the config file is properly available.\n```\n\n### Example 3: Platform-Specific Test Failure\n\n**Test Output:**\n```\nTest 'should read Windows Registry' failed on Linux runner\nCannot find path 'HKEY_LOCAL_MACHINE:\\...'\n```\n\n**Investigation:**\n1. Test assumes Windows Registry exists (Windows-only)\n2. Running on Linux runner doesn't have Registry\n3. Test should skip on non-Windows platforms\n\n**Recommendation:**\n```\nTest is platform-specific but running on wrong platform:\n\nThe test \"should read Windows Registry\" assumes Windows Registry exists but is running on Linux.\n\nAdd a platform check to skip this test on non-Windows systems:\n\n  It \"should read Windows Registry\" -Skip:$(-not $IsWindows) {\n    # test code here\n  }\n\nOr group Windows-only tests in a separate Describe block with platform check:\n\n  Describe \"Windows Registry Tests\" -Skip:$(-not $IsWindows) {\n    # all Windows-specific tests here\n  }\n\nThis allows the test to be skipped on Linux/Mac while still running on Windows CI.\n```\n\n## References\n\n- [Pester Testing Framework](https://pester.dev/) — Official documentation, best practices for test writing\n- [Test Files](../../../test/) — PowerShell test suite in repository\n- [GitHub Actions Documentation](https://docs.github.com/en/actions) — Understanding workflow runs and logs\n- [PowerShell Documentation](https://learn.microsoft.com/en-us/powershell/) — Language reference for understanding test code\n\n## Tips\n\n1. **Read the error message first:** The error message is usually the most direct clue to the problem\n2. **Check test vs. code blame:** Is the test wrong or is the code wrong? Look at both sides\n3. **Verify test isolation:** Does one test failure affect others? Check for shared state or test ordering dependencies\n4. **Test locally first:** Try running the failing test locally to reproduce and understand it better\n5. **Check for environmental assumptions:** Windows-specific paths, module versions, file locations may differ on CI\n6. **Look for skip/ignore patterns:** If a test is consistently ignored, check if the reason is still valid\n7. **Compare passing vs. failing:** If test passes locally but fails on CI, the difference is usually environment-related\n8. **Check recent changes:** Did a recent PR change the tested code or test itself?\n9. **Understand Pester output format:** Different Pester versions, different `-ErrorAction`, `-WarningAction` produce different test results\n10. **Don't assume CI is wrong:** Failures on CI often reveal real issues that local testing missed (network, file permissions, parallelization, etc.)\n\n## Additional Links\n\n- [PowerShell Repository](https://github.com/PowerShell/PowerShell)\n- [GitHub Actions Documentation](https://docs.github.com/en/actions)\n- [Pester Testing Framework](https://github.com/Pester/Pester)\n","frontmatter":{"name":"analyze-pester-failures","description":"Troubleshooting guide for analyzing and investigating Pester test failures in PowerShell CI jobs. Help agents understand why tests are failing, interpret test output, navigate test result artifacts, and provide actionable recommendations for fixing test issues."},"isInternal":false,"tokens":4701,"sizeBytes":20373},{"name":"TestMetadata.json","path":"test/tools/TestMetadata.json","rawUrl":"https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/TestMetadata.json","title":"Tools Skill","category":"anthropic-skill","format":"json","content":"{\n  \"ExperimentalFeatures\": {\n    \"ExpTest.FeatureOne\": [ \"test/powershell/engine/ExperimentalFeature/ExperimentalFeature.Basic.Tests.ps1\" ],\n    \"PSSerializeJSONLongEnumAsNumber\": [ \"test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertTo-Json.PSSerializeJSONLongEnumAsNumber.Tests.ps1\" ]\n  }\n}\n","frontmatter":{"ExperimentalFeatures":{"ExpTest.FeatureOne":["test/powershell/engine/ExperimentalFeature/ExperimentalFeature.Basic.Tests.ps1"],"PSSerializeJSONLongEnumAsNumber":["test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertTo-Json.PSSerializeJSONLongEnumAsNumber.Tests.ps1"]}},"isInternal":false,"tokens":78,"sizeBytes":303},{"name":"appsettings.Development.json","path":"test/tools/WebListener/appsettings.Development.json","rawUrl":"https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/WebListener/appsettings.Development.json","title":"WebListener Skill","category":"anthropic-skill","format":"json","content":"# WebListener Skill\n\nPath: `test/tools/WebListener/appsettings.Development.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/WebListener/appsettings.Development.json)","tokens":300,"sizeBytes":224},{"name":"appsettings.json","path":"test/tools/WebListener/appsettings.json","rawUrl":"https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/WebListener/appsettings.json","title":"WebListener Skill","category":"anthropic-skill","format":"json","content":"# WebListener Skill\n\nPath: `test/tools/WebListener/appsettings.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/WebListener/appsettings.json)","tokens":300,"sizeBytes":200},{"name":"cgmanifest.json","path":"tools/cgmanifest/main/cgmanifest.json","rawUrl":"https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/cgmanifest/main/cgmanifest.json","title":"Main Skill","category":"anthropic-skill","format":"json","content":"# Main Skill\n\nPath: `tools/cgmanifest/main/cgmanifest.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/cgmanifest/main/cgmanifest.json)","tokens":300,"sizeBytes":189},{"name":"cgmanifest.json","path":"tools/cgmanifest/tpn/cgmanifest.json","rawUrl":"https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/cgmanifest/tpn/cgmanifest.json","title":"Tpn Skill","category":"anthropic-skill","format":"json","content":"# Tpn Skill\n\nPath: `tools/cgmanifest/tpn/cgmanifest.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/cgmanifest/tpn/cgmanifest.json)","tokens":300,"sizeBytes":186},{"name":"suppress.json","path":"tools/credScan/suppress.json","rawUrl":"https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/credScan/suppress.json","title":"CredScan Skill","category":"anthropic-skill","format":"json","content":"{\n    \"tool\": \"Credential Scanner\",\n    \"suppressions\": [\n      {\n       \"file\": \"\\\\test\\\\tools\\\\Modules\\\\WebListener\\\\ClientCert.pfx\",\n        \"_justification\": \"Test certificate with private key\"\n      },\n      {\n        \"file\": \"\\\\test\\\\tools\\\\Modules\\\\WebListener\\\\ServerCert.pfx\",\n         \"_justification\": \"Test certificate with private key\"\n       },\n       {\n         \"file\": \"\\\\test\\\\powershell\\\\Modules\\\\Microsoft.PowerShell.Security\\\\certificateCommon.psm1\",\n          \"_justification\": \"Test certificate with private key and inline suppression isn't working\"\n        }\n     ]\n}\n","frontmatter":{"tool":"Credential Scanner","suppressions":[{"file":"\\test\\tools\\Modules\\WebListener\\ClientCert.pfx","_justification":"Test certificate with private key"},{"file":"\\test\\tools\\Modules\\WebListener\\ServerCert.pfx","_justification":"Test certificate with private key"},{"file":"\\test\\powershell\\Modules\\Microsoft.PowerShell.Security\\certificateCommon.psm1","_justification":"Test certificate with private key and inline suppression isn't working"}]},"isInternal":false,"tokens":133,"sizeBytes":591},{"name":"findMissingNotices.targets.json","path":"tools/findMissingNotices.targets.json","rawUrl":"https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/findMissingNotices.targets.json","title":"Tools Skill","category":"anthropic-skill","format":"json","content":"{\n  \"dotnetTargetName\": \"net11.0\",\n  \"windowsTargetNames\": [\n  ]\n}\n","frontmatter":{"dotnetTargetName":"net11.0","windowsTargetNames":[]},"isInternal":false,"tokens":24,"sizeBytes":67},{"name":"tsaconfig-apiscan.json","path":"tools/guardian/tsaconfig-apiscan.json","rawUrl":"https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/guardian/tsaconfig-apiscan.json","title":"Guardian Skill","category":"anthropic-skill","format":"json","content":"{\n  \"codebaseName\": \"PowerShellCore_201906\",\n  \"tools\": [\n      \"APIScan\"\n  ]\n}\n","frontmatter":{"codebaseName":"PowerShellCore_201906","tools":["APIScan"]},"isInternal":false,"tokens":29,"sizeBytes":80},{"name":"tsaconfig-others.json","path":"tools/guardian/tsaconfig-others.json","rawUrl":"https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/guardian/tsaconfig-others.json","title":"Guardian Skill","category":"anthropic-skill","format":"json","content":"{\n  \"codebaseName\": \"PowerShellCore_201906\",\n  \"tools\": [\n      \"CredScan\",\n      \"PoliCheck\"\n  ]\n}\n","frontmatter":{"codebaseName":"PowerShellCore_201906","tools":["CredScan","PoliCheck"]},"isInternal":false,"tokens":35,"sizeBytes":100},{"name":"install-powershell.ps1-README.md","path":"tools/install-powershell.ps1-README.md","rawUrl":"https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/install-powershell.ps1-README.md","title":"Tools Skill","category":"anthropic-skill","format":"markdown","content":"# install-powershell.ps1\n\n## Features of install-powershell.ps1\n\n- Can be called directly from Git\n- Optionally allows install of the latest Preview build\n- Optionally installs using the latest MSI\n- Automatically looks up latest version via Git tags\n- Optionally installs silently\n- Optionally adds the install location to Path environment variable\n\n## Examples\n\n### Install PowerShell Preview Build\n\n```PowerShell\nInvoke-Expression \"& { $(Invoke-RestMethod 'https://aka.ms/install-powershell.ps1') } -Preview\"\n```\n\n### Install PowerShell using the MSI installer\n\n```PowerShell\nInvoke-Expression \"& { $(Invoke-RestMethod 'https://aka.ms/install-powershell.ps1') } -UseMSI\"\n```\n","isInternal":false,"tokens":153,"sizeBytes":678},{"name":"install-powershell.sh-README.md","path":"tools/install-powershell.sh-README.md","rawUrl":"https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/install-powershell.sh-README.md","title":"Tools Skill","category":"anthropic-skill","format":"markdown","content":"# install-powershell.sh\n\n## Features of install-powershell.sh\n\n* Can be called directly from git\n* Optionally installs vs code and vs powershell extension (aka PowerShell IDE) using optional `-includeide` switch\n* Defaults to completely automated operation (if appropriate permissions are available)\n* Automatically looks up latest version via git tags\n* Automatic selection of appropriate install sub-script\n* Configures software installs for repositories when repositories are in place, otherwise pulls files from git releases.  As repository versions are made available, script will be updated to take advantage.\n* User permission checking\n* Sub-installers called from local file system if they exist, otherwise pulled from git\n* Sub-installers can be called directly if auto-selection is not needed\n\n## Minimum Requirements for install-powershell.sh\n\n* bash shell\n* `sed`\n* native package manager available\n* `curl` (auto-installed if missing)\n* `tr`\n\n## Parameters\n\n* -includeide - installs VSCode and VSCode PowerShell extension (only relevant to machines with a desktop environment)\n* -interactivetesting - do a quick launch test of VSCode (only relevant when used with -includeide)\n* -skip-sudo-check - use sudo without verifying its availability (hard to accurately do on some distros)\n* -preview - installs the latest preview release of PowerShell core side-by-side with any existing production releases\n\n## Usage\n\n### Direct from Github\n\n```bash\nbash <(wget -O - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.sh) <ARGUMENTS>\n\nwget -O - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.sh | bash -s <ARGUMENTS>\n```\n\n### Local Copy\n\n```bash\nbash install-powershell.sh <ARGUMENTS>\n```\n\n## Examples\n\n### Only Install PowerShell Core\n\n```bash\nbash <(wget -O - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.sh)\n```\n\n### Install PowerShell Core with IDE\n\n```bash\nbash <(wget -O - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.sh) -includeide\n```\n\n### Install PowerShell Core with IDE and do tests that require a human to interact with the installation process\n\n```bash\nbash <(wget -O - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.sh) -includeide -interactivetesting\n```\n\n### Installation To do list\n\n* Detect and wait when package manager is busy/locked? - at least Ubuntu (CentOS does this internally)\n","isInternal":false,"tokens":553,"sizeBytes":2516},{"name":"metadata.json","path":"tools/metadata.json","rawUrl":"https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/metadata.json","title":"Tools Skill","category":"anthropic-skill","format":"json","content":"{\n  \"StableReleaseTag\": \"v7.6.9\",\n  \"PreviewReleaseTag\": \"v7.7.0-preview.5\",\n  \"ServicingReleaseTag\": \"v7.0.13\",\n  \"ReleaseTag\": \"v7.6.9\",\n  \"LTSReleaseTag\": [\"v7.4.22\", \"v7.6.9\"],\n  \"NextReleaseTag\": \"v7.7.0-preview.6\",\n  \"LTSRelease\": { \"PublishToChannels\": false, \"Package\": false },\n  \"StableRelease\":  { \"PublishToChannels\": false, \"Package\": false }\n}\n","frontmatter":{"StableReleaseTag":"v7.6.9","PreviewReleaseTag":"v7.7.0-preview.5","ServicingReleaseTag":"v7.0.13","ReleaseTag":"v7.6.9","LTSReleaseTag":["v7.4.22","v7.6.9"],"NextReleaseTag":"v7.7.0-preview.6","LTSRelease":{"PublishToChannels":false,"Package":false},"StableRelease":{"PublishToChannels":false,"Package":false}},"isInternal":false,"tokens":141,"sizeBytes":358},{"name":"mapping.json","path":"tools/packages.microsoft.com/mapping.json","rawUrl":"https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/packages.microsoft.com/mapping.json","title":"Packages.microsoft.com Skill","category":"anthropic-skill","format":"json","content":"# Packages.microsoft.com Skill\n\nPath: `tools/packages.microsoft.com/mapping.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/packages.microsoft.com/mapping.json)","tokens":300,"sizeBytes":215},{"name":"README.md","path":"test/perf/dotnet-tools/README.md","rawUrl":"https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/perf/dotnet-tools/README.md","title":"dotnet-tools Documentation","category":"plugin-manifest","format":"markdown","content":"# dotnet-tools Documentation\n\nPath: `test/perf/dotnet-tools/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/perf/dotnet-tools/README.md)","tokens":300,"sizeBytes":195},{"name":"README.md","path":"test/perf/dotnet-tools/ResultsComparer/README.md","rawUrl":"https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/perf/dotnet-tools/ResultsComparer/README.md","title":"ResultsComparer Documentation","category":"plugin-manifest","format":"markdown","content":"# ResultsComparer Documentation\n\nPath: `test/perf/dotnet-tools/ResultsComparer/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/perf/dotnet-tools/ResultsComparer/README.md)","tokens":300,"sizeBytes":230},{"name":"README.md","path":"test/tools/CodeCoverageAutomation/README.md","rawUrl":"https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/CodeCoverageAutomation/README.md","title":"CodeCoverageAutomation Documentation","category":"plugin-manifest","format":"markdown","content":"# CodeCoverageAutomation Documentation\n\nPath: `test/tools/CodeCoverageAutomation/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/CodeCoverageAutomation/README.md)","tokens":300,"sizeBytes":227},{"name":"README.md","path":"test/tools/Modules/UnixSocket/README.md","rawUrl":"https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/Modules/UnixSocket/README.md","title":"UnixSocket Documentation","category":"plugin-manifest","format":"markdown","content":"# UnixSocket Documentation\n\nPath: `test/tools/Modules/UnixSocket/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/Modules/UnixSocket/README.md)","tokens":300,"sizeBytes":207},{"name":"README.md","path":"test/tools/Modules/WebListener/README.md","rawUrl":"https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/Modules/WebListener/README.md","title":"WebListener Documentation","category":"plugin-manifest","format":"markdown","content":"# WebListener Documentation\n\nPath: `test/tools/Modules/WebListener/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/Modules/WebListener/README.md)","tokens":300,"sizeBytes":210},{"name":"README.md","path":"test/tools/WebListener/README.md","rawUrl":"https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/WebListener/README.md","title":"WebListener Documentation","category":"plugin-manifest","format":"markdown","content":"# WebListener Documentation\n\nPath: `test/tools/WebListener/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/WebListener/README.md)","tokens":300,"sizeBytes":194},{"name":"README.md","path":"tools/AttackSurfaceAnalyzer/README.md","rawUrl":"https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/AttackSurfaceAnalyzer/README.md","title":"AttackSurfaceAnalyzer Documentation","category":"plugin-manifest","format":"markdown","content":"# Attack Surface Analyzer Testing\n\nThis directory contains tools for running Attack Surface Analyzer (ASA) tests on PowerShell MSI installations using Docker.\n\n## Overview\n\nAttack Surface Analyzer is a Microsoft tool that helps analyze changes to a system's attack surface. These scripts allow you to run ASA tests locally in a clean Windows container to analyze what changes when PowerShell is installed.\n\n## Files\n\n- **Run-AttackSurfaceAnalyzer.ps1** - PowerShell script to run ASA tests with official MSIs\n- **Summarize-AsaResults.ps1** - PowerShell script to analyze and summarize ASA results\n- **docker/Dockerfile** - Multi-stage Dockerfile for building a container image with ASA pre-installed\n- **README.md** - This documentation file\n\n## Docker Architecture\n\nThe Docker implementation uses a multi-stage build to optimize the testing and result extraction process:\n\n### Multi-Stage Build Stages\n\n1. **asa-runner**: Main execution environment\n   - Base: `mcr.microsoft.com/dotnet/sdk:9.0-windowsservercore-ltsc2022`\n   - Contains Attack Surface Analyzer CLI tools\n   - Runs the complete test workflow\n   - Generates reports in both `C:\\work` and `C:\\reports` directories\n\n1. **asa-reports**: Minimal results layer\n   - Base: `mcr.microsoft.com/windows/nanoserver:ltsc2022`\n   - Contains only the test reports from the runner stage\n   - Enables clean extraction of results without container internals\n\n1. **final**: Default stage (inherits from asa-runner)\n   - Provides backward compatibility\n   - Used when no specific build target is specified\n\n### Benefits\n\n- **Clean Result Extraction**: Reports are isolated in a dedicated layer\n- **Efficient Transfer**: Only test results are copied, not the entire container filesystem\n- **Fallback Support**: Script includes fallback to volume-based extraction if needed\n- **Minimal Footprint**: Final results layer contains only the necessary output files\n\n## Prerequisites\n\n- Windows 10/11 or Windows Server\n- Docker Desktop with Windows containers enabled\n- PowerShell 5.1 or later\n- **An official signed PowerShell MSI file** from a released build\n\n### MSI Requirements\n\n**Important:** This tool now requires an official, digitally signed PowerShell MSI from Microsoft releases:\n\n- **Must be signed** by Microsoft Corporation\n- **Must be from an official release** (downloaded from [PowerShell Releases](https://github.com/PowerShell/PowerShell/releases))\n- **Local builds are not supported** - unsigned or development MSIs will be rejected\n- The script automatically verifies the digital signature before proceeding\n\n**Where to get official MSIs:**\n\n- Download from: https://github.com/PowerShell/PowerShell/releases\n- Look for files like: `PowerShell-7.x.x-win-x64.msi`\n\n## Quick Start\n\n### Option 1: Using the PowerShell Script (Recommended)\n\nThe script requires an official signed PowerShell MSI file:\n\n```powershell\n# Run ASA test with official MSI (MsiPath is required)\n.\\tools\\AttackSurfaceAnalyzer\\Run-AttackSurfaceAnalyzer.ps1 -MsiPath \"C:\\path\\to\\PowerShell-7.4.0-win-x64.msi\"\n\n# Specify custom output directory for results\n.\\tools\\AttackSurfaceAnalyzer\\Run-AttackSurfaceAnalyzer.ps1 -MsiPath \".\\PowerShell-7.4.0-win-x64.msi\" -OutputPath \"C:\\asa-results\"\n\n# Keep the temporary work directory for debugging\n.\\tools\\AttackSurfaceAnalyzer\\Run-AttackSurfaceAnalyzer.ps1 -MsiPath \".\\PowerShell-7.4.0-win-x64.msi\" -KeepWorkDirectory\n```\n\nThe script will:\n\n1. **Verify MSI signature** - Ensures the MSI is officially signed by Microsoft Corporation\n1. Create a temporary work directory\n1. Build a custom Docker container from the static Dockerfile\n1. Start the Windows container with Attack Surface Analyzer\n1. Take a baseline snapshot\n1. Install the PowerShell MSI\n1. Take a post-installation snapshot\n1. Export comparison results\n1. Copy results back to your specified output directory\n\n**Security Note:** The script will reject any MSI that is not digitally signed by Microsoft Corporation to ensure analysis is performed only on official releases.\n\n### Option 2: Using the Dockerfile\n\nIf you prefer to build and use the container image directly:\n\n```powershell\n# Build the Docker image (Dockerfile is in docker subfolder with clean context)\ndocker build -f tools\\AttackSurfaceAnalyzer\\docker\\Dockerfile -t powershell-asa-test tools\\AttackSurfaceAnalyzer\\docker\\\n\n# Run the container with your MSI (script is built into the container)\ndocker run --rm --isolation process `\n  -v \"C:\\path\\to\\msi\\directory:C:\\work\" `\n  powershell-asa-test\n```\n\n## Output Files\n\nThe test will generate output files in the `./asa-results/` directory (or your specified `-OutputPath`):\n\n- **`asa.sqlite`** - SQLite database with full analysis data (primary result file)\n- **`install.log`** - MSI installation log file\n- **`*_summary.json.txt`** - Summary of detected changes (if generated)\n- **`*_results.json.txt`** - Detailed results in JSON format (if generated)\n- **`*.sarif`** - SARIF format results (if generated, can be viewed in VS Code)\n\n## Analyzing Results\n\n### Using the Summary Script (Recommended)\n\nUse the included summary script to get a comprehensive analysis:\n\n```powershell\n# Basic summary of ASA results\n.\\tools\\AttackSurfaceAnalyzer\\Summarize-AsaResults.ps1\n\n# Detailed analysis with rule breakdowns\n.\\tools\\AttackSurfaceAnalyzer\\Summarize-AsaResults.ps1 -ShowDetails\n\n# Analyze results from a specific location\n.\\tools\\AttackSurfaceAnalyzer\\Summarize-AsaResults.ps1 -Path \"C:\\custom\\path\\asa-results.json\" -ShowDetails\n```\n\nThe summary script provides:\n\n- **Overall statistics** - Total findings, analysis levels, category breakdowns\n- **Rule analysis** - Which security rules were triggered and how often\n- **File analysis** - Detailed breakdown of file-related security issues by rule type\n- **Category cross-reference** - Shows which rules affect which categories\n\n### Using VS Code\n\nThe SARIF files can be opened directly in VS Code with the SARIF Viewer extension to see a formatted view of the findings.\n\n### Using PowerShell\n\n```powershell\n# Read the JSON results directly\n$results = Get-Content \"asa-results\\asa-results.json\" | ConvertFrom-Json\n$results.Results.FILE_CREATED.Count  # Number of files created\n\n# Query the SQLite database (requires SQLite tools)\n# Example: List all file changes\n# sqlite3 asa.sqlite \"SELECT * FROM file_system WHERE change_type != 'NONE'\"\n```\n\n## Troubleshooting\n\n### Docker Not Available\n\nThe script automatically handles Docker Desktop installation and startup:\n\n**If Docker Desktop is installed but not running:**\n\n- The script will automatically start Docker Desktop for you\n- It waits up to 60 seconds for Docker to become available\n- You'll be prompted for confirmation (supports `-Confirm` and `-WhatIf`)\n\n**If Docker Desktop is not installed:**\n\n- The script will prompt you to install it automatically using winget\n- After installation completes, start Docker Desktop and run the script again\n\n**Manual Installation:**\n\n1. Install Docker Desktop from https://www.docker.com/products/docker-desktop\n1. Ensure Docker is running\n1. Switch to Windows containers (right-click Docker tray icon → \"Switch to Windows containers\")\n\n### Container Fails to Start\n\n- Ensure you have enough disk space (containers can be large)\n- Check that Windows containers are enabled in Docker settings\n- Try pulling the base image manually: `docker pull mcr.microsoft.com/dotnet/sdk:9.0-windowsservercore-ltsc2022`\n\n### MSI Signature Verification Fails\n\nIf you get signature verification errors:\n\n- **Ensure you're using an official MSI** from [PowerShell Releases](https://github.com/PowerShell/PowerShell/releases)\n- **Do not use local builds** - only signed release MSIs are supported  \n- **Check certificate validity** - very old MSIs may have expired certificates\n- **Verify file integrity** - redownload the MSI if it may be corrupted\n\n### No Results Generated\n\n- Check the install.log file for MSI installation errors\n- Run with `-KeepWorkDirectory` to inspect the temporary work directory\n- Verify the MSI file is valid and not corrupted\n\n## Advanced Usage\n\n### Parameters\n\nThe `Run-AttackSurfaceAnalyzer.ps1` script supports these parameters:\n\n- **`-MsiPath`** (Required) - Path to the official signed PowerShell MSI file\n- **`-OutputPath`** (Optional) - Directory for results (defaults to `./asa-results`)\n- **`-ContainerImage`** (Optional) - Custom container base image\n- **`-KeepWorkDirectory`** (Optional) - Keep temp directory for debugging\n\nExample with custom container image:\n\n```powershell\n.\\tools\\AttackSurfaceAnalyzer\\Run-AttackSurfaceAnalyzer.ps1 `\n  -MsiPath \".\\PowerShell-7.4.0-win-x64.msi\" `\n  -ContainerImage \"mcr.microsoft.com/dotnet/sdk:8.0-windowsservercore-ltsc2022\"\n```\n\n### Debugging\n\nTo debug issues, keep the work directory and examine the files:\n\n```powershell\n.\\tools\\AttackSurfaceAnalyzer\\Run-AttackSurfaceAnalyzer.ps1 -KeepWorkDirectory\n\n# The script will print the work directory path\n# You can then examine:\n# - run-asa.ps1 - The script that runs in the container\n# - install.log - MSI installation log\n# - Any other generated files\n```\n\n## Integration with CI/CD\n\nThese tools were extracted from the GitHub Actions workflow to allow local testing. If you need to integrate ASA testing back into a CI/CD pipeline, you can:\n\n1. Use the PowerShell script directly in your pipeline\n1. Build and push the Docker image to a registry\n1. Use the Dockerfile as a base for custom testing scenarios\n\n## More Information\n\n- [Attack Surface Analyzer on GitHub](https://github.com/microsoft/AttackSurfaceAnalyzer)\n- [Docker for Windows Documentation](https://docs.docker.com/desktop/windows/)\n- [SARIF Documentation](https://sarifweb.azurewebsites.net/)\n","isInternal":false,"tokens":2199,"sizeBytes":9665},{"name":"readme.md","path":"tools/clearlyDefined/readme.md","rawUrl":"https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/clearlyDefined/readme.md","title":"clearlyDefined Documentation","category":"plugin-manifest","format":"markdown","content":"# ClearlyDefined\n\n## Purpose\n\nThis tool is intended to test if all the license data in [ClearlyDefined](https://clearlydefined.io) is present to generate the PowerShell license.\nIf the data is not present, it can request that ClearlyDefined gather (called Harvest in their terminology) the data.\n\n## Use\n\n### Testing\n\nRun `./ClearlyDefined.ps1 -test`.\n\nIf there is any missing data, the script should write verbose messages about the missing data and throw.\nIf there is no missing data, the script should not throw.\n\n### Harvesting\n\nRun `./ClearlyDefined.ps1 -Harvest`.\nThe script will trigger the harvest and output the result from ClearlyDefined.\n**Give ClearlyDefined 24 hours to harvest the data.**\nYou can use the `-Test` switch without the `-Harvest` switch to test if Harvesting is done.\n\n## Caching\n\nIf you run in the same PowerShell session, the script will be faster due to caching.\n\nThe module will cache any results from ClearlyDefined that indicate the package is Harvested for 60 minutes.\nNo caching is done for packages that are not yet harvested.\nTo clear the cache, run with the `-ForceModuleReload` switch.\n","isInternal":false,"tokens":246,"sizeBytes":1125},{"name":"README.md","path":"tools/performance/README.md","rawUrl":"https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/performance/README.md","title":"performance Documentation","category":"plugin-manifest","format":"markdown","content":"# performance Documentation\n\nPath: `tools/performance/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/performance/README.md)","tokens":300,"sizeBytes":184},{"name":"SplitADOPipelines.agent.md","path":".github/agents/SplitADOPipelines.agent.md","rawUrl":"https://raw.githubusercontent.com/PowerShell/powershell/HEAD/.github/agents/SplitADOPipelines.agent.md","title":"SplitADOPipelines","category":"subagent-persona","format":"markdown","content":"---\nname: SplitADOPipelines\ndescription: This agent will implement and restructure the repository's existing ADO pipelines into Official and NonOfficial pipelines.\ntools: ['vscode', 'execute', 'read', 'agent', 'edit', 'search', 'todo']\n---\n\nThis agent will implement and restructure the repository's existing ADO pipelines into Official and NonOfficial pipelines. \n\nA repository will have under the .pipelines directory a series of yaml files that define the ADO pipelines for the repository.\n\nFirst confirm if the pipelines are using a toggle switch for Official and NonOfficial. This will look something like this\n\n```yaml\nparameters:\n  - name: templateFile\n    value: ${{ iif ( parameters.OfficialBuild, 'v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates', 'v2/OneBranch.NonOfficial.CrossPlat.yml@onebranchTemplates' ) }}\n```\n\nFollowed by:\n\n```yaml\nextends:\n  template: ${{ variables.templateFile }}\n```\n\nThis is an indicator that this work needs to be done. This toggle switch is no longer allowed and the templates need to be hard coded.\n\n## Template Reference Convention (MUST follow)\n\nAll `- template:` references to files **inside this repo** must use the **absolute** form anchored at the repo root, with the `@self` suffix:\n\n```yaml\n- template: /.pipelines/templates/<path>/<file>.yml@self\n```\n\nDo **not** use relative paths such as `templates/...`, `../templates/...`, or bare filenames. Rationale:\n\n- Absolute paths resolve identically regardless of where the referring file lives, so moving a pipeline file between directories (for example, into `.pipelines/NonOfficial/`) does not silently break includes.\n- Relative paths are resolved by Azure DevOps against the directory of the referring file, which has caused real outages in this repo when a relative include was composed into a nonexistent nested path like `.pipelines/templates/stages/.pipelines/templates/...`.\n- The majority of existing includes already use the absolute form; keeping new work consistent reduces review burden.\n\nThe only acceptable non-absolute references are to external repositories resolved via the `resources.repositories` block, for example `v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates`.\n\n## Refactoring Steps\n\n### Step 1: Extract Shared Templates\n\nFor each pipeline file that uses the toggle switch pattern (e.g., `PowerShell-Packages-Official.yml`):\n\n1. Create the `.pipelines/templates/variables` and `.pipelines/templates/stages` directories if they don't exist\n2. Extract the **variables section** into `.pipelines/templates/variables/PowerShell-Packages-Variables.yml`\n3. Extract the **stages section** into `.pipelines/templates/stages/PowerShell-Packages-Stages.yml`\n\n**IMPORTANT**: Only extract the `variables:` and `stages:` sections. All other sections (parameters, resources, extends, etc.) remain in the pipeline files.\n\n### Step 2: Create Official Pipeline (In-Place Refactoring)\n\nThe original toggle-based file becomes the Official pipeline:\n\n1. **Keep the file in its original location** (e.g., `.pipelines/PowerShell-Packages-Official.yml` stays where it is)\n2. Remove the toggle switch parameter (`templateFile` parameter)\n3. Hard-code the Official template reference:\n   ```yaml\n   extends:\n     template: v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates\n   ```\n4. Replace the `variables:` section with a template reference:\n   ```yaml\n   variables:\n     - template: /.pipelines/templates/variables/PowerShell-Packages-Variables.yml@self\n   ```\n5. Replace the `stages:` section with a template reference:\n   ```yaml\n   stages:\n     - template: /.pipelines/templates/stages/PowerShell-Packages-Stages.yml@self\n   ```\n\n### Step 3: Create NonOfficial Pipeline\n\n1. Create `.pipelines/NonOfficial` directory if it doesn't exist\n2. Create the NonOfficial pipeline file (e.g., `.pipelines/NonOfficial/PowerShell-Packages-NonOfficial.yml`)\n3. Copy the structure from the refactored Official pipeline\n4. Hard-code the NonOfficial template reference:\n   ```yaml\n   extends:\n     template: v2/OneBranch.NonOfficial.CrossPlat.yml@onebranchTemplates\n   ```\n5. Reference the same shared templates:\n   ```yaml\n   variables:\n     - template: /.pipelines/templates/variables/PowerShell-Packages-Variables.yml@self\n   \n   stages:\n     - template: /.pipelines/templates/stages/PowerShell-Packages-Stages.yml@self\n   ```\n\n**Note**: Always use **absolute** template paths of the form `/.pipelines/templates/...@self`. Do not use relative paths like `templates/...` or `../templates/...`. Absolute paths are anchored at the repo root and resolve consistently from any referring file, preventing breakage when files are moved between directories.\n\n### Step 4: Link NonOfficial Pipelines to NonOfficial Dependencies\n\nAfter creating NonOfficial pipelines, ensure they consume artifacts from other **NonOfficial** pipelines, not Official ones.\n\n1. **Check the `resources:` section** in each NonOfficial pipeline for `pipelines:` dependencies\n2. **Identify Official pipeline references** that need to be changed to NonOfficial\n3. **Update the `source:` field** to point to the NonOfficial version\n\n**Example Problem:** NonOfficial pipeline pointing to Official dependency\n```yaml\nresources:\n  pipelines:\n    - pipeline: CoOrdinatedBuildPipeline\n      source: 'PowerShell-Coordinated Binaries-Official'  # ❌ Wrong - Official!\n```\n\n**Solution:** Update to NonOfficial dependency\n```yaml\nresources:\n  pipelines:\n    - pipeline: CoOrdinatedBuildPipeline\n      source: 'PowerShell-Coordinated Binaries-NonOfficial'  # ✅ Correct - NonOfficial!\n```\n\n**IMPORTANT**: The `source:` field must match the **exact ADO pipeline definition name** as it appears in Azure DevOps, not necessarily the file name.\n\n### Step 5: Configure Release Environment Parameters (NonAzure Only)\n\n**This step only applies if the pipeline uses `category: NonAzure` in the release configuration.**\n\nIf you detect this pattern in the original pipeline:\n\n```yaml\nextends:\n  template: v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates  # or NonOfficial\n  parameters:\n    release:\n      category: NonAzure\n```\n\nThen you must configure the `ob_release_environment` parameter when referencing the stages template.\n\n#### Official Pipeline Configuration\n\nIn the Official pipeline (e.g., `.pipelines/PowerShell-Packages-Official.yml`):\n\n```yaml\nstages:\n  - template: /.pipelines/templates/stages/PowerShell-Packages-Stages.yml@self\n    parameters:\n      ob_release_environment: Production\n```\n\n#### NonOfficial Pipeline Configuration\n\nIn the NonOfficial pipeline (e.g., `.pipelines/NonOfficial/PowerShell-Packages-NonOfficial.yml`):\n\n```yaml\nstages:\n  - template: /.pipelines/templates/stages/PowerShell-Packages-Stages.yml@self\n    parameters:\n      ob_release_environment: Test\n```\n\n#### Update Stages Template to Accept Parameter\n\nThe extracted stages template (e.g., `.pipelines/templates/stages/PowerShell-Packages-Stages.yml`) must declare the parameter at the top:\n\n```yaml\nparameters:\n  - name: ob_release_environment\n    type: string\n\nstages:\n  # ... rest of stages configuration using ${{ parameters.ob_release_environment }}\n```\n\n**IMPORTANT**: \n- Only configure this for pipelines with `category: NonAzure`\n- Official pipelines always use `ob_release_environment: Production`\n- NonOfficial pipelines always use `ob_release_environment: Test`\n- The stages template must accept this parameter and use it in the appropriate stage configurations\n","frontmatter":{"name":"SplitADOPipelines","description":"This agent will implement and restructure the repository's existing ADO pipelines into Official and NonOfficial pipelines.","tools":["vscode","execute","read","agent","edit","search","todo"]},"isInternal":false,"tokens":1667,"sizeBytes":7429}],"systemPromptSnippet":"<yakaai_skills repo=\"PowerShell/powershell\">\n<!-- File: .github/skills/analyze-pester-failures/references/stack-trace-parsing.md (Tokens: ~300 | Category: anthropic-skill) -->\n# References Skill\n\nPath: `.github/skills/analyze-pester-failures/references/stack-trace-parsing.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/.github/skills/analyze-pester-failures/references/stack-trace-parsing.md)\n\n<!-- File: .github/skills/analyze-pester-failures/SKILL.md (Tokens: ~4701 | Category: anthropic-skill) -->\n---\nname: analyze-pester-failures\ndescription: Troubleshooting guide for analyzing and investigating Pester test failures in PowerShell CI jobs. Help agents understand why tests are failing, interpret test output, navigate test result artifacts, and provide actionable recommendations for fixing test issues.\n---\n\n# Analyze Pester Test Failures\n\nInvestigate and troubleshoot Pester test failures in GitHub Actions workflows. Understand what tests are failing, why they're failing, and provide recommendations for test fixes.\n\n| Skill | When to Use |\n|-------|-----------|\n| analyze-pester-failures | When investigating why Pester tests are failing in a CI job. Use when a test job shows failures and you need to understand what test failed, why it failed, what the error message means, and what might need to be fixed. Also use when asked: \"why did this test fail?\", \"what's the test error?\", \"test is broken\", \"test failure analysis\", \"debug test failure\", or given test failure logs and stack traces. |\n\n## When to Use This Skill\n\nUse this skill when you need to:\n\n- Understand why a specific Pester test is failing  \n- Interpret test failure messages and error output\n- Analyze test result data from CI workflow runs (XML, logs, stack traces)\n- Identify the root cause of test failures (test logic, assertion failure, exception, timeout, skip/ignore reason)\n- Provide recommendations for fixing failing tests\n- Compare expected vs. actual test behavior\n- Debug test environment issues (missing dependencies, configuration problems)\n- Understand test skip/ignored/inconclusive status reasons\n\n**Do not use this skill for:**\n- General PowerShell debugging unrelated to tests\n- Test infrastructure/CI setup issues (except as they affect test failure interpretation)\n- Performance analysis or benchmarking (that's a different investigation)\n\n## Quick Start\n\n### ⚠️ CRITICAL: The Workflow Must Be Followed IN ORDER\n\nThis skill describes a **sequential 6-step analysis workflow**. Skipping steps or jumping around leads to **incomplete analysis and incorrect conclusions**.\n\n**The Problem**: It's easy to skip to Step 4 or 5 without doing Steps 1-2, resulting in missing data and bad conclusions.\n\n**The Solution**: Use the automated analysis script to enforce the workflow:\n\n```powershell\n# Automatically runs Steps 1-6 in order, preventing skipping\n./.github/skills/analyze-pester-failures/scripts/analyze-pr-test-failures.ps1 -PR <PR_NUMBER>\n\n# Example:\n./.github/skills/analyze-pester-failures/scripts/analyze-pr-test-failures.ps1 -PR 26800\n```\n\nThis script:\n1. ✓ Fetches PR status automatically\n2. ✓ Downloads artifacts (can't skip, depends on Step 1)\n3. ✓ Extracts failures (can't skip, depends on Step 2)\n4. ✓ Analyzes error messages\n5. ✓ Documents context\n6. ✓ Generates recommendations\n\n**Only use the manual commands below if you fully understand the workflow.**\n\n### Manual Workflow (for reference)\n\n```powershell\n# Step 1: Identify the failing job\ngh pr view <PR_NUMBER> --json 'statusCheckRollup' | ConvertFrom-Json | Where-Object { $_.conclusion -eq 'FAILURE' }\n\n# Step 2: Download artifacts (extract RUN_ID from Step 1)\ngh run download <RUN_ID> --dir ./artifacts\ngh run view <RUN_ID> --log > test-logs.txt\n\n# Step 3-6: Extract, analyze, and interpret\n# (See Analysis Workflow section below)\n```\n\n## Common Test Failure Analysis Approaches\n\n### 1. **Interpreting Assertion Failures**\nThe most common test failure is when an assertion doesn't match expectations.\n\n**Example:**\n```\nExpected $true but got $false at /path/to/test.ps1:42\nAssertion failed: Should -Be \"expected\" but was \"actual\"  \n```\n\n**How to analyze:**\n- Read the assertion message: what was expected vs. what was actual?\n- Check the test logic: is the expectation correct?\n- Look for mock/stub issues: are dependencies configured correctly?\n- Check parameter values: what inputs were passed to the function under test?\n\n### 2. **Exception Failures**\nTests fail when PowerShell throws an exception instead of successful completion.\n\n**Example:**\n```\nCommand: Write-Host $null\nError: Cannot bind argument to parameter 'Object' because it is null.\n```\n\n**How to analyze:**\n- Read the exception message: what operation failed?\n- Check the stack trace: where in the test or tested code did it throw?\n- Verify preconditions: does the test setup provide required values/mocks?\n- Look for environmental issues: missing modules, permissions, file system state?\n\n### 3. **Timeout Failures**\nA test takes longer than the allowed timeout to complete.\n\n**Example:**\n```\nTest 'Should complete in reasonable time' timed out after 30 seconds\n```\n\n**How to analyze:**\n- Is the timeout appropriate for this test type? (network tests need more time)\n- Is there an infinite loop in the test or tested code?\n- Are there resource contention issues on the CI runner?\n- Does the test hang waiting for something (file lock, network, process)?\n\n### 4. **Skip/Ignored Reason Analysis**\nTests marked as skipped or ignored provide clues about test environment.\n\n**Example:**\n```\nTest marked [Skip(\"Only runs on Windows\")] - running on Linux\nTest marked [Ignore(\"Known issue #12345\")]\n```\n\n**How to analyze:**\n- Read the skip/ignore reason: is it still valid?\n- Check if environment has changed: platform, module versions, etc.\n- Verify issue status: is the known issue still open? Has it been fixed?\n- Determine if skip should be removed or if test needs environment changes\n\n### 5. **Flaky/Intermittent Failures**\nTests that sometimes pass, sometimes fail indicate race conditions or environment sensitivity.\n\n**Example:**\n- Test passes locally but fails on CI\n- Test passes first run of suite, fails on second run\n- Test passes on Windows but fails on Linux\n\n**How to analyze:**\n- Look for timeout races: is timing involved in the test?\n- Check for test isolation issues: does one test affect another?\n- Verify environment differences: CI vs. local paths, permissions, versions\n- Look for external dependencies: network calls, file I/O, process interactions\n\n## Key Artifacts and Locations\n\n| Item | Purpose | Location |\n|------|---------|----------|\n| Test result XML | Pester output with test cases, failures, errors | Workflow artifacts: `junit-pester-*.xml` |\n| Job logs | Full job output including test execution and errors | GitHub Actions run logs or `gh run download` |\n| Stack traces | Error location information from failed assertions | Within job logs and XML failure messages |\n| Test files | The actual Pester test code (`.ps1` files) | `test/` directory in repository |\n\n## Analysis Workflow\n\n### ⚠️ Important: These Steps MUST Be Followed In Order\n\nEach step depends on the previous one. Skipping or re-ordering steps causes incomplete analysis:\n\n- **Step 1** (identify jobs) → You get the RUN_ID needed for Step 2\n- **Step 2** (download) → You get the artifacts needed for Step 3  \n- **Step 3** (extract) → You discover what failures exist for Step 4\n- **Step 4** (read messages) → You understand the errors to analyze in Step 5\n- **Step 5** (context) → You gather information to make recommendations in Step 6\n- **Step 6** (interpret) → You use all above to recommend fixes\n\n**Real Problem We Had**:\n- ❌ Jumped to Step 3 without Step 1-2\n- ❌ Used random test data from context instead of downloading PR artifacts\n- ❌ Skipped Steps 5-6 entirely\n- ❌ Made recommendations without full context\n\n**Result**: Wrong analysis and recommendations that didn't actually fix the problem.\n\n### Recommended: Use the Automated Script\n\n```powershell\n./.github/skills/analyze-pester-failures/scripts/analyze-pr-test-failures.ps1 -PR <PR_NUMBER>\n```\n\nThis enforces the workflow and prevents skipping.\n\n### Step 2: Get Test Results\n\nFetch the test result artifacts and job logs:\n\n```powershell\n# Download artifacts including test XML results\ngh run download <RUN_ID> --dir ./artifacts\n\n# Get job logs\ngh run view <RUN_ID> --log > test-logs.txt\n\n# Inspect test XML\n$xml = [xml](Get-Content ./artifacts/junit-pester-*.xml)\n$xml.'test-results' | Select-Object total, failures, errors, ignored, inconclusive\n```\n\n### Step 3: Extract Specific Failures\n\nFind the failing test cases in the XML:\n\n```powershell\n# Get all failed test cases\n$xml = [xml](Get-Content ./artifacts/junit-pester-*.xml)\n$failures = $xml.SelectNodes('.//test-case[@result = \"Failure\"]')\n\n# For each failure, display key info\n$failures | ForEach-Object {\n    [PSCustomObject]@{\n        Name = $_.name\n        Description = $_.description\n        Message = $_.failure.message\n        StackTrace = $_.failure.'stack-trace'\n    }\n}\n```\n\n### Step 4: Read the Error Message\n\nThe error message tells you what went wrong:\n\n**Assertion failures:**\n```\nExpected $true but got $false\nExpected \"value1\" but got \"value2\"\nExpression should have failed with exception, but didn't\n```\n\n**Exceptions:**\n```\nCannot find a parameter with name 'Name'\nProperty 'Property' does not exist on 'Object'\nCannot bind argument to parameter because it is null\n```\n\n**Timeouts:**\n```\nTest timed out after 30 seconds\nTest is taking too long to complete\n```\n\n### Step 5: Understand the Context\n\nLook at the test file to understand what was being tested:\n\n```powershell\n# Find the test file mentioned in the stack trace\n# Example: /path/to/test/Feature.Tests.ps1:42\n\n# Read the test code around that line\ncode <test-file-path>:<line-number>\n\n# Understand:  \n# - What assertion is on that line?\n# - What is the test trying to verify?\n# - What are the setup/mock/before conditions?\n# - Are there recent changes to the function being tested?\n```\n\n### Step 6: Interpret the Failure\n\nDetermine the root cause category:\n\n**Test issue (needs code fix):**\n- Assertion logic is wrong\n- Test expectations don't match actual behavior\n- Test setup is incomplete\n- Mock/stub configuration missing\n\n**Environmental issue (needs environment change):**\n- Test assumes a specific file or registry entry exists\n- Test requires Windows/Linux specifically\n- Test requires specific PowerShell version\n- Test requires specific module version\n- Timing-sensitive test affected by CI load\n\n**Data issue (needs input data change):**\n- Test data no longer valid\n- External API changed format\n- Configuration file has changed structure\n\n**Flakiness (needs test hardening):**\n- Race condition in test\n- Timing assumptions too tight\n- Resource contention on CI runner\n- Non-deterministic behavior in tested code\n\n## Common Test Failure Patterns\n\n| Pattern | What It Means | Example | Next Step |\n|---------|---------------|---------|-----------|\n| `Expected $true but got $false` | Assertion on boolean result failed | Test expects function returns true, but it returns false | Check function logic for bug or test logic for wrong expectation |\n| `Cannot find path` | File or directory doesn't exist | Test tries to read config file that's not present | Verify file path, check test setup, ensure CI environment has file |\n| `Cannot bind argument to parameter 'X'` | Required parameter value is null or wrong type | Function called with $null where object expected | Check test mock setup, verify parameter types |\n| `Test timed out after X seconds` | Test exceeded time limit | Network call or loop takes too long | Increase timeout for slow test, find infinite loop, mock network calls |\n| `Expression should have failed but didn't` | Exception wasn't thrown when expected | Test expects error but function succeeds | Check if function behavior changed, update test expectation |\n| `Could not find parameter 'X'` | Function doesn't have parameter | Test calls function with parameter that doesn't exist | Check PowerShell version, verify function signature, update test |\n| `This platform is not supported` | Test skipped on current OS | Windows-only test running on Linux | Add platform check, update test environment, or mark as platform-specific |\n| `Test marked [Ignore]` | Test explicitly disabled | Test has `[Ignore(\"reason\")]` attribute | Check if reason still valid, remove if issue fixed |\n\n## Interpreting Test Results\n\n### Test Result Counts\n\nPester test outcomes are categorized as:\n\n| Count | Meaning | Notes |\n|-------|---------|-------|\n| `total` | Total number of test cases executed | Should match: passed + failed + errors + skipped + ignored |\n| `failures` | Test assertions that failed | `Expected X but got Y` type failures |\n| `errors` | Tests that threw exceptions | Unhandled PowerShell exceptions during test |\n| `skipped` | Tests explicitly skipped (marked with `-Skip`) | Test code recognizes condition and skips |\n| `ignored` | Tests marked as ignored (marked with `-Ignore`) | Test disabled intentionally, usually notes reason |\n| `inconclusive` | Tests with unclear result | Rare; usually means test framework issue |\n| `passed` | Tests with passing assertions | `total - failures - errors - skipped - ignored` |\n\n### Stack Trace Interpretation\n\nA stack trace shows where the failure occurred:\n\n```\nat /home/runner/work/PowerShell/test/Feature.Tests.ps1:42\n\nMeans:\n- File: /home/runner/work/PowerShell/test/Feature.Tests.ps1\n- Line: 42\n- Look at that line to see which assertion failed\n```\n\n### Understanding Skipped Tests\n\nWhen XML shows `result=\"Ignored\"` or `result=\"Skipped\"`:\n\n```xml\n<test-case name=\"Test Name\" result=\"Ignored\">\n  <reason>Only runs on Windows</reason>\n</test-case>\n```\n\nThe reason explains why test didn't run. Not a failure, but important for understanding test coverage.\n\n## Providing Test Failure Analysis\n\n### Investigation Questions\n\nAfter gathering test output, ask yourself:\n\n1. **Is the test code correct?**\n   - Does the test assertion match the expected behavior?\n   - Are test expectations still valid?\n   - Has the function being tested changed?\n\n2. **Is the test setup correct?**\n   - Are mocks/stubs configured properly?\n   - Does the test environment have required files/configuration?\n   - Are preconditions (database, files, services) met?\n\n3. **Is this a code bug or test issue?**\n   - Does the tested function have a logic error?\n   - Or does the test have incorrect expectations?\n\n4. **Is this environment-specific?**\n   - Only fails on Windows/Linux?\n   - Only fails on CI but passes locally?\n   - Timing-dependent or resource-dependent?\n\n5. **Is this a known/expected failure?**\n   - Is there already an issue tracking this failure?\n   - Is the test marked as flaky or expected to fail?\n   - Does the skip/ignore reason still apply?\n\n### Recommendation Framework\n\nBased on your analysis:\n\n| Finding | Recommendation |\n|---------|-----------------|\n| Test logic is wrong | \"Test assertion on line X is incorrect. Test expects Y but function correctly returns Z. Update test expectation.\" |\n| Tested code has bug | \"Function at file.ps1#L42 has logic error. When X happens, returns Y instead of Z. Fix the condition.\" |\n| Missing test setup | \"Test setup incomplete. Mock for dependency Y is not configured. Add `Mock Get-Y -MockWith { ... }`\" |\n| Environment issue | \"Test is Windows-specific but running on Linux. Either add platform check or skip on non-Windows.\" |\n| Flaky test | \"Test is timing-sensitive (sleep 1 second). Increase timeout or use better synchronization.\" |\n| Test should be skipped | \"Test is marked Ignored for good reason. Keep it disabled until issue #12345 is fixed.\" |\n\n### Tone and Structure\n\nProvide analysis as:\n\n1. **Summary** (1 sentence): What test is failing and general category  \n2. **Failure Details** (2-3 sentences): What the test output says  \n3. **Root Cause** (1-2 sentences): Why it's failing (test bug vs. code bug vs. environment)\n4. **Recommendation** (actionable): What should be done to fix it  \n5. **Context** (optional): Link to related code, issues, or recent changes\n\n## Examples\n\n### Example 1: Assertion Failure Due to Code Bug\n\n**Test Output:**\n```\nExpected 5 but got 3 at /path/to/Test.ps1:42\n```\n\n**Investigation:**\n1. Look at line 42: `$result | Should -Be 5`\n2. Check the test: It expects function to return 5 items\n3. Check the function: It returns `$items | Where-Object {$_.Status -eq \"Active\"}` but the filter is wrong\n4. Root cause: Function has logic error, not test error\n\n**Recommendation:**\n```\nTest failure is due to a code bug:\n\nThe test Set-Configuration should return 5 items but returns 3.\n\nLooking at the tested function at [module.ps1#L42](module.ps1#L42):\n  $activeItems = $items | Where-Object {$_.Status -eq \"Active\"}\n\nThe issue is the filter condition. It's currently filtering by \"Active\" status,\nbut should include \"Pending\" status as well. \n\nFix: Change line 42 to:\n  $activeItems = $items | Where-Object {$_.Status -ne \"Disabled\"}\n\nThen re-run the test to verify it now returns 5 items as expected.\n```\n\n### Example 2: Test Setup Issue\n\n**Test Output:**\n```\nCannot find path '/expected/config.json' because it does not exist at /path/to/Test.ps1:15\n```\n\n**Investigation:**\n1. Line 15 tries to read a config file\n2. The test setup doesn't create this file\n3. Works locally but fails on CI because CI doesn't have the same file\n\n**Recommendation:**\n```\nTest setup is incomplete:\n\nThe test Initialize-Config fails because it expects /expected/config.json but the test doesn't create this file.\n\nThe test needs to ensure the config file exists. Currently line 12-14 doesn't set up the file:\n\n  # Before:\n  # (no setup of config file)\n\n  # After:\n  @{ setting1 = \"value1\"; setting2 = \"value2\" } | ConvertTo-Json | \n    Out-File $testConfigPath\n\nAlternatively, the test function should accept a parameter for the config path and use a temporary file:\n  param([string]$ConfigPath = (New-TemporaryFile))\n\nRe-run the test to verify the config file is properly available.\n```\n\n### Example 3: Platform-Specific Test Failure\n\n**Test Output:**\n```\nTest 'should read Windows Registry' failed on Linux runner\nCannot find path 'HKEY_LOCAL_MACHINE:\\...'\n```\n\n**Investigation:**\n1. Test assumes Windows Registry exists (Windows-only)\n2. Running on Linux runner doesn't have Registry\n3. Test should skip on non-Windows platforms\n\n**Recommendation:**\n```\nTest is platform-specific but running on wrong platform:\n\nThe test \"should read Windows Registry\" assumes Windows Registry exists but is running on Linux.\n\nAdd a platform check to skip this test on non-Windows systems:\n\n  It \"should read Windows Registry\" -Skip:$(-not $IsWindows) {\n    # test code here\n  }\n\nOr group Windows-only tests in a separate Describe block with platform check:\n\n  Describe \"Windows Registry Tests\" -Skip:$(-not $IsWindows) {\n    # all Windows-specific tests here\n  }\n\nThis allows the test to be skipped on Linux/Mac while still running on Windows CI.\n```\n\n## References\n\n- [Pester Testing Framework](https://pester.dev/) — Official documentation, best practices for test writing\n- [Test Files](../../../test/) — PowerShell test suite in repository\n- [GitHub Actions Documentation](https://docs.github.com/en/actions) — Understanding workflow runs and logs\n- [PowerShell Documentation](https://learn.microsoft.com/en-us/powershell/) — Language reference for understanding test code\n\n## Tips\n\n1. **Read the error message first:** The error message is usually the most direct clue to the problem\n2. **Check test vs. code blame:** Is the test wrong or is the code wrong? Look at both sides\n3. **Verify test isolation:** Does one test failure affect others? Check for shared state or test ordering dependencies\n4. **Test locally first:** Try running the failing test locally to reproduce and understand it better\n5. **Check for environmental assumptions:** Windows-specific paths, module versions, file locations may differ on CI\n6. **Look for skip/ignore patterns:** If a test is consistently ignored, check if the reason is still valid\n7. **Compare passing vs. failing:** If test passes locally but fails on CI, the difference is usually environment-related\n8. **Check recent changes:** Did a recent PR change the tested code or test itself?\n9. **Understand Pester output format:** Different Pester versions, different `-ErrorAction`, `-WarningAction` produce different test results\n10. **Don't assume CI is wrong:** Failures on CI often reveal real issues that local testing missed (network, file permissions, parallelization, etc.)\n\n## Additional Links\n\n- [PowerShell Repository](https://github.com/PowerShell/PowerShell)\n- [GitHub Actions Documentation](https://docs.github.com/en/actions)\n- [Pester Testing Framework](https://github.com/Pester/Pester)\n\n<!-- File: test/tools/TestMetadata.json (Tokens: ~78 | Category: anthropic-skill) -->\n{\n  \"ExperimentalFeatures\": {\n    \"ExpTest.FeatureOne\": [ \"test/powershell/engine/ExperimentalFeature/ExperimentalFeature.Basic.Tests.ps1\" ],\n    \"PSSerializeJSONLongEnumAsNumber\": [ \"test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertTo-Json.PSSerializeJSONLongEnumAsNumber.Tests.ps1\" ]\n  }\n}\n\n<!-- File: test/tools/WebListener/appsettings.Development.json (Tokens: ~300 | Category: anthropic-skill) -->\n# WebListener Skill\n\nPath: `test/tools/WebListener/appsettings.Development.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/WebListener/appsettings.Development.json)\n\n<!-- File: test/tools/WebListener/appsettings.json (Tokens: ~300 | Category: anthropic-skill) -->\n# WebListener Skill\n\nPath: `test/tools/WebListener/appsettings.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/WebListener/appsettings.json)\n\n<!-- File: tools/cgmanifest/main/cgmanifest.json (Tokens: ~300 | Category: anthropic-skill) -->\n# Main Skill\n\nPath: `tools/cgmanifest/main/cgmanifest.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/cgmanifest/main/cgmanifest.json)\n\n<!-- File: tools/cgmanifest/tpn/cgmanifest.json (Tokens: ~300 | Category: anthropic-skill) -->\n# Tpn Skill\n\nPath: `tools/cgmanifest/tpn/cgmanifest.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/cgmanifest/tpn/cgmanifest.json)\n\n<!-- File: tools/credScan/suppress.json (Tokens: ~133 | Category: anthropic-skill) -->\n{\n    \"tool\": \"Credential Scanner\",\n    \"suppressions\": [\n      {\n       \"file\": \"\\\\test\\\\tools\\\\Modules\\\\WebListener\\\\ClientCert.pfx\",\n        \"_justification\": \"Test certificate with private key\"\n      },\n      {\n        \"file\": \"\\\\test\\\\tools\\\\Modules\\\\WebListener\\\\ServerCert.pfx\",\n         \"_justification\": \"Test certificate with private key\"\n       },\n       {\n         \"file\": \"\\\\test\\\\powershell\\\\Modules\\\\Microsoft.PowerShell.Security\\\\certificateCommon.psm1\",\n          \"_justification\": \"Test certificate with private key and inline suppression isn't working\"\n        }\n     ]\n}\n\n<!-- File: tools/findMissingNotices.targets.json (Tokens: ~24 | Category: anthropic-skill) -->\n{\n  \"dotnetTargetName\": \"net11.0\",\n  \"windowsTargetNames\": [\n  ]\n}\n\n<!-- File: tools/guardian/tsaconfig-apiscan.json (Tokens: ~29 | Category: anthropic-skill) -->\n{\n  \"codebaseName\": \"PowerShellCore_201906\",\n  \"tools\": [\n      \"APIScan\"\n  ]\n}\n\n<!-- File: tools/guardian/tsaconfig-others.json (Tokens: ~35 | Category: anthropic-skill) -->\n{\n  \"codebaseName\": \"PowerShellCore_201906\",\n  \"tools\": [\n      \"CredScan\",\n      \"PoliCheck\"\n  ]\n}\n\n<!-- File: tools/install-powershell.ps1-README.md (Tokens: ~153 | Category: anthropic-skill) -->\n# install-powershell.ps1\n\n## Features of install-powershell.ps1\n\n- Can be called directly from Git\n- Optionally allows install of the latest Preview build\n- Optionally installs using the latest MSI\n- Automatically looks up latest version via Git tags\n- Optionally installs silently\n- Optionally adds the install location to Path environment variable\n\n## Examples\n\n### Install PowerShell Preview Build\n\n```PowerShell\nInvoke-Expression \"& { $(Invoke-RestMethod 'https://aka.ms/install-powershell.ps1') } -Preview\"\n```\n\n### Install PowerShell using the MSI installer\n\n```PowerShell\nInvoke-Expression \"& { $(Invoke-RestMethod 'https://aka.ms/install-powershell.ps1') } -UseMSI\"\n```\n\n<!-- File: tools/install-powershell.sh-README.md (Tokens: ~553 | Category: anthropic-skill) -->\n# install-powershell.sh\n\n## Features of install-powershell.sh\n\n* Can be called directly from git\n* Optionally installs vs code and vs powershell extension (aka PowerShell IDE) using optional `-includeide` switch\n* Defaults to completely automated operation (if appropriate permissions are available)\n* Automatically looks up latest version via git tags\n* Automatic selection of appropriate install sub-script\n* Configures software installs for repositories when repositories are in place, otherwise pulls files from git releases.  As repository versions are made available, script will be updated to take advantage.\n* User permission checking\n* Sub-installers called from local file system if they exist, otherwise pulled from git\n* Sub-installers can be called directly if auto-selection is not needed\n\n## Minimum Requirements for install-powershell.sh\n\n* bash shell\n* `sed`\n* native package manager available\n* `curl` (auto-installed if missing)\n* `tr`\n\n## Parameters\n\n* -includeide - installs VSCode and VSCode PowerShell extension (only relevant to machines with a desktop environment)\n* -interactivetesting - do a quick launch test of VSCode (only relevant when used with -includeide)\n* -skip-sudo-check - use sudo without verifying its availability (hard to accurately do on some distros)\n* -preview - installs the latest preview release of PowerShell core side-by-side with any existing production releases\n\n## Usage\n\n### Direct from Github\n\n```bash\nbash <(wget -O - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.sh) <ARGUMENTS>\n\nwget -O - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.sh | bash -s <ARGUMENTS>\n```\n\n### Local Copy\n\n```bash\nbash install-powershell.sh <ARGUMENTS>\n```\n\n## Examples\n\n### Only Install PowerShell Core\n\n```bash\nbash <(wget -O - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.sh)\n```\n\n### Install PowerShell Core with IDE\n\n```bash\nbash <(wget -O - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.sh) -includeide\n```\n\n### Install PowerShell Core with IDE and do tests that require a human to interact with the installation process\n\n```bash\nbash <(wget -O - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.sh) -includeide -interactivetesting\n```\n\n### Installation To do list\n\n* Detect and wait when package manager is busy/locked? - at least Ubuntu (CentOS does this internally)\n\n<!-- File: tools/metadata.json (Tokens: ~141 | Category: anthropic-skill) -->\n{\n  \"StableReleaseTag\": \"v7.6.9\",\n  \"PreviewReleaseTag\": \"v7.7.0-preview.5\",\n  \"ServicingReleaseTag\": \"v7.0.13\",\n  \"ReleaseTag\": \"v7.6.9\",\n  \"LTSReleaseTag\": [\"v7.4.22\", \"v7.6.9\"],\n  \"NextReleaseTag\": \"v7.7.0-preview.6\",\n  \"LTSRelease\": { \"PublishToChannels\": false, \"Package\": false },\n  \"StableRelease\":  { \"PublishToChannels\": false, \"Package\": false }\n}\n\n<!-- File: tools/packages.microsoft.com/mapping.json (Tokens: ~300 | Category: anthropic-skill) -->\n# Packages.microsoft.com Skill\n\nPath: `tools/packages.microsoft.com/mapping.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/packages.microsoft.com/mapping.json)\n\n<!-- File: test/perf/dotnet-tools/README.md (Tokens: ~300 | Category: plugin-manifest) -->\n# dotnet-tools Documentation\n\nPath: `test/perf/dotnet-tools/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/perf/dotnet-tools/README.md)\n\n<!-- File: test/perf/dotnet-tools/ResultsComparer/README.md (Tokens: ~300 | Category: plugin-manifest) -->\n# ResultsComparer Documentation\n\nPath: `test/perf/dotnet-tools/ResultsComparer/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/perf/dotnet-tools/ResultsComparer/README.md)\n\n<!-- File: test/tools/CodeCoverageAutomation/README.md (Tokens: ~300 | Category: plugin-manifest) -->\n# CodeCoverageAutomation Documentation\n\nPath: `test/tools/CodeCoverageAutomation/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/CodeCoverageAutomation/README.md)\n\n<!-- File: test/tools/Modules/UnixSocket/README.md (Tokens: ~300 | Category: plugin-manifest) -->\n# UnixSocket Documentation\n\nPath: `test/tools/Modules/UnixSocket/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/Modules/UnixSocket/README.md)\n\n<!-- File: test/tools/Modules/WebListener/README.md (Tokens: ~300 | Category: plugin-manifest) -->\n# WebListener Documentation\n\nPath: `test/tools/Modules/WebListener/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/Modules/WebListener/README.md)\n\n<!-- File: test/tools/WebListener/README.md (Tokens: ~300 | Category: plugin-manifest) -->\n# WebListener Documentation\n\nPath: `test/tools/WebListener/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/test/tools/WebListener/README.md)\n\n<!-- File: tools/AttackSurfaceAnalyzer/README.md (Tokens: ~2199 | Category: plugin-manifest) -->\n# Attack Surface Analyzer Testing\n\nThis directory contains tools for running Attack Surface Analyzer (ASA) tests on PowerShell MSI installations using Docker.\n\n## Overview\n\nAttack Surface Analyzer is a Microsoft tool that helps analyze changes to a system's attack surface. These scripts allow you to run ASA tests locally in a clean Windows container to analyze what changes when PowerShell is installed.\n\n## Files\n\n- **Run-AttackSurfaceAnalyzer.ps1** - PowerShell script to run ASA tests with official MSIs\n- **Summarize-AsaResults.ps1** - PowerShell script to analyze and summarize ASA results\n- **docker/Dockerfile** - Multi-stage Dockerfile for building a container image with ASA pre-installed\n- **README.md** - This documentation file\n\n## Docker Architecture\n\nThe Docker implementation uses a multi-stage build to optimize the testing and result extraction process:\n\n### Multi-Stage Build Stages\n\n1. **asa-runner**: Main execution environment\n   - Base: `mcr.microsoft.com/dotnet/sdk:9.0-windowsservercore-ltsc2022`\n   - Contains Attack Surface Analyzer CLI tools\n   - Runs the complete test workflow\n   - Generates reports in both `C:\\work` and `C:\\reports` directories\n\n1. **asa-reports**: Minimal results layer\n   - Base: `mcr.microsoft.com/windows/nanoserver:ltsc2022`\n   - Contains only the test reports from the runner stage\n   - Enables clean extraction of results without container internals\n\n1. **final**: Default stage (inherits from asa-runner)\n   - Provides backward compatibility\n   - Used when no specific build target is specified\n\n### Benefits\n\n- **Clean Result Extraction**: Reports are isolated in a dedicated layer\n- **Efficient Transfer**: Only test results are copied, not the entire container filesystem\n- **Fallback Support**: Script includes fallback to volume-based extraction if needed\n- **Minimal Footprint**: Final results layer contains only the necessary output files\n\n## Prerequisites\n\n- Windows 10/11 or Windows Server\n- Docker Desktop with Windows containers enabled\n- PowerShell 5.1 or later\n- **An official signed PowerShell MSI file** from a released build\n\n### MSI Requirements\n\n**Important:** This tool now requires an official, digitally signed PowerShell MSI from Microsoft releases:\n\n- **Must be signed** by Microsoft Corporation\n- **Must be from an official release** (downloaded from [PowerShell Releases](https://github.com/PowerShell/PowerShell/releases))\n- **Local builds are not supported** - unsigned or development MSIs will be rejected\n- The script automatically verifies the digital signature before proceeding\n\n**Where to get official MSIs:**\n\n- Download from: https://github.com/PowerShell/PowerShell/releases\n- Look for files like: `PowerShell-7.x.x-win-x64.msi`\n\n## Quick Start\n\n### Option 1: Using the PowerShell Script (Recommended)\n\nThe script requires an official signed PowerShell MSI file:\n\n```powershell\n# Run ASA test with official MSI (MsiPath is required)\n.\\tools\\AttackSurfaceAnalyzer\\Run-AttackSurfaceAnalyzer.ps1 -MsiPath \"C:\\path\\to\\PowerShell-7.4.0-win-x64.msi\"\n\n# Specify custom output directory for results\n.\\tools\\AttackSurfaceAnalyzer\\Run-AttackSurfaceAnalyzer.ps1 -MsiPath \".\\PowerShell-7.4.0-win-x64.msi\" -OutputPath \"C:\\asa-results\"\n\n# Keep the temporary work directory for debugging\n.\\tools\\AttackSurfaceAnalyzer\\Run-AttackSurfaceAnalyzer.ps1 -MsiPath \".\\PowerShell-7.4.0-win-x64.msi\" -KeepWorkDirectory\n```\n\nThe script will:\n\n1. **Verify MSI signature** - Ensures the MSI is officially signed by Microsoft Corporation\n1. Create a temporary work directory\n1. Build a custom Docker container from the static Dockerfile\n1. Start the Windows container with Attack Surface Analyzer\n1. Take a baseline snapshot\n1. Install the PowerShell MSI\n1. Take a post-installation snapshot\n1. Export comparison results\n1. Copy results back to your specified output directory\n\n**Security Note:** The script will reject any MSI that is not digitally signed by Microsoft Corporation to ensure analysis is performed only on official releases.\n\n### Option 2: Using the Dockerfile\n\nIf you prefer to build and use the container image directly:\n\n```powershell\n# Build the Docker image (Dockerfile is in docker subfolder with clean context)\ndocker build -f tools\\AttackSurfaceAnalyzer\\docker\\Dockerfile -t powershell-asa-test tools\\AttackSurfaceAnalyzer\\docker\\\n\n# Run the container with your MSI (script is built into the container)\ndocker run --rm --isolation process `\n  -v \"C:\\path\\to\\msi\\directory:C:\\work\" `\n  powershell-asa-test\n```\n\n## Output Files\n\nThe test will generate output files in the `./asa-results/` directory (or your specified `-OutputPath`):\n\n- **`asa.sqlite`** - SQLite database with full analysis data (primary result file)\n- **`install.log`** - MSI installation log file\n- **`*_summary.json.txt`** - Summary of detected changes (if generated)\n- **`*_results.json.txt`** - Detailed results in JSON format (if generated)\n- **`*.sarif`** - SARIF format results (if generated, can be viewed in VS Code)\n\n## Analyzing Results\n\n### Using the Summary Script (Recommended)\n\nUse the included summary script to get a comprehensive analysis:\n\n```powershell\n# Basic summary of ASA results\n.\\tools\\AttackSurfaceAnalyzer\\Summarize-AsaResults.ps1\n\n# Detailed analysis with rule breakdowns\n.\\tools\\AttackSurfaceAnalyzer\\Summarize-AsaResults.ps1 -ShowDetails\n\n# Analyze results from a specific location\n.\\tools\\AttackSurfaceAnalyzer\\Summarize-AsaResults.ps1 -Path \"C:\\custom\\path\\asa-results.json\" -ShowDetails\n```\n\nThe summary script provides:\n\n- **Overall statistics** - Total findings, analysis levels, category breakdowns\n- **Rule analysis** - Which security rules were triggered and how often\n- **File analysis** - Detailed breakdown of file-related security issues by rule type\n- **Category cross-reference** - Shows which rules affect which categories\n\n### Using VS Code\n\nThe SARIF files can be opened directly in VS Code with the SARIF Viewer extension to see a formatted view of the findings.\n\n### Using PowerShell\n\n```powershell\n# Read the JSON results directly\n$results = Get-Content \"asa-results\\asa-results.json\" | ConvertFrom-Json\n$results.Results.FILE_CREATED.Count  # Number of files created\n\n# Query the SQLite database (requires SQLite tools)\n# Example: List all file changes\n# sqlite3 asa.sqlite \"SELECT * FROM file_system WHERE change_type != 'NONE'\"\n```\n\n## Troubleshooting\n\n### Docker Not Available\n\nThe script automatically handles Docker Desktop installation and startup:\n\n**If Docker Desktop is installed but not running:**\n\n- The script will automatically start Docker Desktop for you\n- It waits up to 60 seconds for Docker to become available\n- You'll be prompted for confirmation (supports `-Confirm` and `-WhatIf`)\n\n**If Docker Desktop is not installed:**\n\n- The script will prompt you to install it automatically using winget\n- After installation completes, start Docker Desktop and run the script again\n\n**Manual Installation:**\n\n1. Install Docker Desktop from https://www.docker.com/products/docker-desktop\n1. Ensure Docker is running\n1. Switch to Windows containers (right-click Docker tray icon → \"Switch to Windows containers\")\n\n### Container Fails to Start\n\n- Ensure you have enough disk space (containers can be large)\n- Check that Windows containers are enabled in Docker settings\n- Try pulling the base image manually: `docker pull mcr.microsoft.com/dotnet/sdk:9.0-windowsservercore-ltsc2022`\n\n### MSI Signature Verification Fails\n\nIf you get signature verification errors:\n\n- **Ensure you're using an official MSI** from [PowerShell Releases](https://github.com/PowerShell/PowerShell/releases)\n- **Do not use local builds** - only signed release MSIs are supported  \n- **Check certificate validity** - very old MSIs may have expired certificates\n- **Verify file integrity** - redownload the MSI if it may be corrupted\n\n### No Results Generated\n\n- Check the install.log file for MSI installation errors\n- Run with `-KeepWorkDirectory` to inspect the temporary work directory\n- Verify the MSI file is valid and not corrupted\n\n## Advanced Usage\n\n### Parameters\n\nThe `Run-AttackSurfaceAnalyzer.ps1` script supports these parameters:\n\n- **`-MsiPath`** (Required) - Path to the official signed PowerShell MSI file\n- **`-OutputPath`** (Optional) - Directory for results (defaults to `./asa-results`)\n- **`-ContainerImage`** (Optional) - Custom container base image\n- **`-KeepWorkDirectory`** (Optional) - Keep temp directory for debugging\n\nExample with custom container image:\n\n```powershell\n.\\tools\\AttackSurfaceAnalyzer\\Run-AttackSurfaceAnalyzer.ps1 `\n  -MsiPath \".\\PowerShell-7.4.0-win-x64.msi\" `\n  -ContainerImage \"mcr.microsoft.com/dotnet/sdk:8.0-windowsservercore-ltsc2022\"\n```\n\n### Debugging\n\nTo debug issues, keep the work directory and examine the files:\n\n```powershell\n.\\tools\\AttackSurfaceAnalyzer\\Run-AttackSurfaceAnalyzer.ps1 -KeepWorkDirectory\n\n# The script will print the work directory path\n# You can then examine:\n# - run-asa.ps1 - The script that runs in the container\n# - install.log - MSI installation log\n# - Any other generated files\n```\n\n## Integration with CI/CD\n\nThese tools were extracted from the GitHub Actions workflow to allow local testing. If you need to integrate ASA testing back into a CI/CD pipeline, you can:\n\n1. Use the PowerShell script directly in your pipeline\n1. Build and push the Docker image to a registry\n1. Use the Dockerfile as a base for custom testing scenarios\n\n## More Information\n\n- [Attack Surface Analyzer on GitHub](https://github.com/microsoft/AttackSurfaceAnalyzer)\n- [Docker for Windows Documentation](https://docs.docker.com/desktop/windows/)\n- [SARIF Documentation](https://sarifweb.azurewebsites.net/)\n\n<!-- File: tools/clearlyDefined/readme.md (Tokens: ~246 | Category: plugin-manifest) -->\n# ClearlyDefined\n\n## Purpose\n\nThis tool is intended to test if all the license data in [ClearlyDefined](https://clearlydefined.io) is present to generate the PowerShell license.\nIf the data is not present, it can request that ClearlyDefined gather (called Harvest in their terminology) the data.\n\n## Use\n\n### Testing\n\nRun `./ClearlyDefined.ps1 -test`.\n\nIf there is any missing data, the script should write verbose messages about the missing data and throw.\nIf there is no missing data, the script should not throw.\n\n### Harvesting\n\nRun `./ClearlyDefined.ps1 -Harvest`.\nThe script will trigger the harvest and output the result from ClearlyDefined.\n**Give ClearlyDefined 24 hours to harvest the data.**\nYou can use the `-Test` switch without the `-Harvest` switch to test if Harvesting is done.\n\n## Caching\n\nIf you run in the same PowerShell session, the script will be faster due to caching.\n\nThe module will cache any results from ClearlyDefined that indicate the package is Harvested for 60 minutes.\nNo caching is done for packages that are not yet harvested.\nTo clear the cache, run with the `-ForceModuleReload` switch.\n\n<!-- File: tools/performance/README.md (Tokens: ~300 | Category: plugin-manifest) -->\n# performance Documentation\n\nPath: `tools/performance/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/PowerShell/powershell/HEAD/tools/performance/README.md)\n\n<!-- File: .github/agents/SplitADOPipelines.agent.md (Tokens: ~1667 | Category: subagent-persona) -->\n---\nname: SplitADOPipelines\ndescription: This agent will implement and restructure the repository's existing ADO pipelines into Official and NonOfficial pipelines.\ntools: ['vscode', 'execute', 'read', 'agent', 'edit', 'search', 'todo']\n---\n\nThis agent will implement and restructure the repository's existing ADO pipelines into Official and NonOfficial pipelines. \n\nA repository will have under the .pipelines directory a series of yaml files that define the ADO pipelines for the repository.\n\nFirst confirm if the pipelines are using a toggle switch for Official and NonOfficial. This will look something like this\n\n```yaml\nparameters:\n  - name: templateFile\n    value: ${{ iif ( parameters.OfficialBuild, 'v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates', 'v2/OneBranch.NonOfficial.CrossPlat.yml@onebranchTemplates' ) }}\n```\n\nFollowed by:\n\n```yaml\nextends:\n  template: ${{ variables.templateFile }}\n```\n\nThis is an indicator that this work needs to be done. This toggle switch is no longer allowed and the templates need to be hard coded.\n\n## Template Reference Convention (MUST follow)\n\nAll `- template:` references to files **inside this repo** must use the **absolute** form anchored at the repo root, with the `@self` suffix:\n\n```yaml\n- template: /.pipelines/templates/<path>/<file>.yml@self\n```\n\nDo **not** use relative paths such as `templates/...`, `../templates/...`, or bare filenames. Rationale:\n\n- Absolute paths resolve identically regardless of where the referring file lives, so moving a pipeline file between directories (for example, into `.pipelines/NonOfficial/`) does not silently break includes.\n- Relative paths are resolved by Azure DevOps against the directory of the referring file, which has caused real outages in this repo when a relative include was composed into a nonexistent nested path like `.pipelines/templates/stages/.pipelines/templates/...`.\n- The majority of existing includes already use the absolute form; keeping new work consistent reduces review burden.\n\nThe only acceptable non-absolute references are to external repositories resolved via the `resources.repositories` block, for example `v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates`.\n\n## Refactoring Steps\n\n### Step 1: Extract Shared Templates\n\nFor each pipeline file that uses the toggle switch pattern (e.g., `PowerShell-Packages-Official.yml`):\n\n1. Create the `.pipelines/templates/variables` and `.pipelines/templates/stages` directories if they don't exist\n2. Extract the **variables section** into `.pipelines/templates/variables/PowerShell-Packages-Variables.yml`\n3. Extract the **stages section** into `.pipelines/templates/stages/PowerShell-Packages-Stages.yml`\n\n**IMPORTANT**: Only extract the `variables:` and `stages:` sections. All other sections (parameters, resources, extends, etc.) remain in the pipeline files.\n\n### Step 2: Create Official Pipeline (In-Place Refactoring)\n\nThe original toggle-based file becomes the Official pipeline:\n\n1. **Keep the file in its original location** (e.g., `.pipelines/PowerShell-Packages-Official.yml` stays where it is)\n2. Remove the toggle switch parameter (`templateFile` parameter)\n3. Hard-code the Official template reference:\n   ```yaml\n   extends:\n     template: v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates\n   ```\n4. Replace the `variables:` section with a template reference:\n   ```yaml\n   variables:\n     - template: /.pipelines/templates/variables/PowerShell-Packages-Variables.yml@self\n   ```\n5. Replace the `stages:` section with a template reference:\n   ```yaml\n   stages:\n     - template: /.pipelines/templates/stages/PowerShell-Packages-Stages.yml@self\n   ```\n\n### Step 3: Create NonOfficial Pipeline\n\n1. Create `.pipelines/NonOfficial` directory if it doesn't exist\n2. Create the NonOfficial pipeline file (e.g., `.pipelines/NonOfficial/PowerShell-Packages-NonOfficial.yml`)\n3. Copy the structure from the refactored Official pipeline\n4. Hard-code the NonOfficial template reference:\n   ```yaml\n   extends:\n     template: v2/OneBranch.NonOfficial.CrossPlat.yml@onebranchTemplates\n   ```\n5. Reference the same shared templates:\n   ```yaml\n   variables:\n     - template: /.pipelines/templates/variables/PowerShell-Packages-Variables.yml@self\n   \n   stages:\n     - template: /.pipelines/templates/stages/PowerShell-Packages-Stages.yml@self\n   ```\n\n**Note**: Always use **absolute** template paths of the form `/.pipelines/templates/...@self`. Do not use relative paths like `templates/...` or `../templates/...`. Absolute paths are anchored at the repo root and resolve consistently from any referring file, preventing breakage when files are moved between directories.\n\n### Step 4: Link NonOfficial Pipelines to NonOfficial Dependencies\n\nAfter creating NonOfficial pipelines, ensure they consume artifacts from other **NonOfficial** pipelines, not Official ones.\n\n1. **Check the `resources:` section** in each NonOfficial pipeline for `pipelines:` dependencies\n2. **Identify Official pipeline references** that need to be changed to NonOfficial\n3. **Update the `source:` field** to point to the NonOfficial version\n\n**Example Problem:** NonOfficial pipeline pointing to Official dependency\n```yaml\nresources:\n  pipelines:\n    - pipeline: CoOrdinatedBuildPipeline\n      source: 'PowerShell-Coordinated Binaries-Official'  # ❌ Wrong - Official!\n```\n\n**Solution:** Update to NonOfficial dependency\n```yaml\nresources:\n  pipelines:\n    - pipeline: CoOrdinatedBuildPipeline\n      source: 'PowerShell-Coordinated Binaries-NonOfficial'  # ✅ Correct - NonOfficial!\n```\n\n**IMPORTANT**: The `source:` field must match the **exact ADO pipeline definition name** as it appears in Azure DevOps, not necessarily the file name.\n\n### Step 5: Configure Release Environment Parameters (NonAzure Only)\n\n**This step only applies if the pipeline uses `category: NonAzure` in the release configuration.**\n\nIf you detect this pattern in the original pipeline:\n\n```yaml\nextends:\n  template: v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates  # or NonOfficial\n  parameters:\n    release:\n      category: NonAzure\n```\n\nThen you must configure the `ob_release_environment` parameter when referencing the stages template.\n\n#### Official Pipeline Configuration\n\nIn the Official pipeline (e.g., `.pipelines/PowerShell-Packages-Official.yml`):\n\n```yaml\nstages:\n  - template: /.pipelines/templates/stages/PowerShell-Packages-Stages.yml@self\n    parameters:\n      ob_release_environment: Production\n```\n\n#### NonOfficial Pipeline Configuration\n\nIn the NonOfficial pipeline (e.g., `.pipelines/NonOfficial/PowerShell-Packages-NonOfficial.yml`):\n\n```yaml\nstages:\n  - template: /.pipelines/templates/stages/PowerShell-Packages-Stages.yml@self\n    parameters:\n      ob_release_environment: Test\n```\n\n#### Update Stages Template to Accept Parameter\n\nThe extracted stages template (e.g., `.pipelines/templates/stages/PowerShell-Packages-Stages.yml`) must declare the parameter at the top:\n\n```yaml\nparameters:\n  - name: ob_release_environment\n    type: string\n\nstages:\n  # ... rest of stages configuration using ${{ parameters.ob_release_environment }}\n```\n\n**IMPORTANT**: \n- Only configure this for pipelines with `category: NonAzure`\n- Official pipelines always use `ob_release_environment: Production`\n- NonOfficial pipelines always use `ob_release_environment: Test`\n- The stages template must accept this parameter and use it in the appropriate stage configurations\n</yakaai_skills>"}