Skip to content

Experimental PowerShell discover extension#1071

Open
Gijsreyn wants to merge 47 commits intoPowerShell:mainfrom
Gijsreyn:implement-powershell-discover
Open

Experimental PowerShell discover extension#1071
Gijsreyn wants to merge 47 commits intoPowerShell:mainfrom
Gijsreyn:implement-powershell-discover

Conversation

@Gijsreyn
Copy link
Collaborator

@Gijsreyn Gijsreyn commented Aug 21, 2025

PR Summary

Implements an optimized approach to discovering PowerShell resources using .NET with parallel processing and direct result synchronization.

The previous approach using Get-ChildItem had unnecessary object overhead and required post-processing with Where-Object. The same is implied when using a thread-safe collection (ConcurrentBag), which adds unnecessary complexity.

PR Context

Fix #913

@Gijsreyn
Copy link
Collaborator Author

With PR #1025 around, it might be worthwhile to rename the directories.

@Gijsreyn Gijsreyn force-pushed the implement-powershell-discover branch 2 times, most recently from 623d593 to 5b7502f Compare August 24, 2025 21:04
@Gijsreyn Gijsreyn force-pushed the implement-powershell-discover branch from 5b7502f to 991f7ce Compare August 27, 2025 01:07
@Gijsreyn Gijsreyn force-pushed the implement-powershell-discover branch from 6337045 to f15195a Compare September 3, 2025 16:22
Copy link
Collaborator

@michaeltlombardi michaeltlombardi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few questions and requests:

  1. Do I correctly understand that this extension only for resources implemented in PowerShell and excluding Windows PowerShell? If so, do we need a second extension for discovering those resources, or can we handle that in this one? I'm not sure I see an immediate reason for why we can't handle both here, given the manifest has to indicate whether the resource is invoked with powershell or pwsh.
  2. Can we slightly restructure this script to define (currently empty) param block and put the implementation into the process block? That can help with organization and testing later on.
  3. The current implementation can't run in Windows PowerShell, I think, given the use of ForEach-Object -Parallel - but we can still discover resources in Windows PowerShell modules.

@Gijsreyn
Copy link
Collaborator Author

Gijsreyn commented Sep 3, 2025

A few questions and requests:

  1. Do I correctly understand that this extension only for resources implemented in PowerShell and excluding Windows PowerShell? If so, do we need a second extension for discovering those resources, or can we handle that in this one? I'm not sure I see an immediate reason for why we can't handle both here, given the manifest has to indicate whether the resource is invoked with powershell or pwsh.
  2. Can we slightly restructure this script to define (currently empty) param block and put the implementation into the process block? That can help with organization and testing later on.
  3. The current implementation can't run in Windows PowerShell, I think, given the use of ForEach-Object -Parallel - but we can still discover resources in Windows PowerShell modules.
  1. The one currently written is only compatible with PowerShell 7+ because of the [System.IO.EnumerationOptions]. We might be able to rewrite it, but as you also mentioned (from point 3), the Foreach-Object -Parallel is not implemented. It would be best to create a second extension for it with different logic.
  2. Sure, I'll implement this change. Thanks for the comment!
  3. Answered in point 1.

@Gijsreyn
Copy link
Collaborator Author

@SteveL-MSFT - by any chance, if you have time to review this one, I would appreciate it.

@Gijsreyn
Copy link
Collaborator Author

Gijsreyn commented Oct 8, 2025

@SteveL-MSFT - caching added. Took a couple of rounds because of returning nothing. Added this to the docs after discussing with Mikey.

@Gijsreyn Gijsreyn requested a review from SteveL-MSFT October 10, 2025 00:40
@SteveL-MSFT SteveL-MSFT added this to the 3.2-Consider milestone Mar 19, 2026
Copilot AI review requested due to automatic review settings March 20, 2026 04:43
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an experimental PowerShell discover extension to enable DSC to discover resource/extension manifests shipped inside PowerShell 7 modules (via PSModulePath), aiming to reduce overhead versus Get-ChildItem by using .NET enumeration with parallelism and a disk cache.

Changes:

  • Introduces a new Microsoft.PowerShell/Discover extension manifest and a pwsh-based discover script.
  • Adds Pester tests validating cache creation/usage/invalidation and discovery output.
  • Updates extension discovery tests and clarifies discover stdout documentation (including “no output when nothing is found”).

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
extensions/powershell/powershell.dsc.extension.json Registers the new PowerShell discover extension (pwsh entrypoint).
extensions/powershell/powershell.discover.ps1 Implements module-path scanning + caching for discovered manifests.
extensions/powershell/powershell.discover.tests.ps1 Adds tests for cache and discovery behavior of the PowerShell discover script.
extensions/powershell/copy_files.txt Ensures the new script/manifest are packaged with the extension.
dsc/tests/dsc_extension_discover.tests.ps1 Expands extension list expectations to include the new PowerShell discover extension.
docs/reference/schemas/extension/stdout/discover.md Updates/clarifies discover stdout schema guidance, including empty-output semantics.
Comments suppressed due to low confidence (1)

dsc/tests/dsc_extension_discover.tests.ps1:66

  • The new $expectedExtensions loop isn’t closed before the old $IsWindows assertions start, so the legacy assertions are now nested inside the foreach and will run multiple times (and the old expected counts/types are no longer correct). Remove the old block (or move it outside) and ensure the foreach block is properly closed.
        $out.Count | Should -Be $expectedExtensions.Count -Because ($out | Out-String)
        
        foreach ($expected in $expectedExtensions) {
            $extension = $out | Where-Object { $_.type -eq $expected.type }
            $extension | Should -Not -BeNullOrEmpty -Because "Extension $($expected.type) should exist"
            $extension.version | Should -BeExactly $expected.version
            $extension.capabilities | Should -BeExactly $expected.capabilities
            $extension.manifest | Should -Not -BeNullOrEmpty
        if ($IsWindows) {
            $out.Count | Should -Be 2 -Because ($out | Out-String)
            $out[0].type | Should -Be 'Microsoft.Windows.Appx/Discover'
            $out[0].version | Should -Be '0.1.0'
            $out[0].capabilities | Should -BeExactly @('discover')
            $out[0].manifest | Should -Not -BeNullOrEmpty
            $out[1].type | Should -BeExactly 'Test/Discover'
            $out[1].version | Should -BeExactly '0.1.0'
            $out[1].capabilities | Should -BeExactly @('discover')
            $out[1].manifest | Should -Not -BeNullOrEmpty
        } else {
            $out.Count | Should -Be 1 -Because ($out | Out-String)
            $out[0].type | Should -BeExactly 'Test/Discover'
            $out[0].version | Should -BeExactly '0.1.0'
            $out[0].capabilities | Should -BeExactly @('discover')
            $out[0].manifest | Should -Not -BeNullOrEmpty
        }
    }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Reviewed

Development

Successfully merging this pull request may close these issues.

Discover extension for PSModulePath

4 participants