From dd4163420d64b8811328a3b2da64da3155ef12cc Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Thu, 21 Aug 2025 14:38:26 +0200 Subject: [PATCH 01/20] Init --- .vscode/launch.json | 78 +++++++++---------- extensions/powershell/powershell-discover.ps1 | 13 ++++ 2 files changed, 52 insertions(+), 39 deletions(-) create mode 100644 extensions/powershell/powershell-discover.ps1 diff --git a/.vscode/launch.json b/.vscode/launch.json index c0fe66904..00879d03f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,39 +1,39 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "lldb", - "request": "launch", - "name": "Debug config", - "program": "${workspaceFolder}/config/target/debug/config", - "args": [ - "list", - "r*" - ], - "cwd": "${workspaceFolder}" - }, - { - "name": "(macOS) Attach", - "type": "lldb", - "request": "attach", - "pid": "${command:pickMyProcess}", - }, - { - "name": "(Windows) Attach", - "type": "cppvsdbg", - "request": "attach", - "processId": "${command:pickProcess}", - }, - { - "name": "Debug sshdconfig", - "type": "cppvsdbg", - "request": "launch", - "program": "${workspaceFolder}/sshdconfig/target/debug/sshdconfig.exe", - "args": ["get"], - "cwd": "${workspaceFolder}" - } - ] -} +// { +// // Use IntelliSense to learn about possible attributes. +// // Hover to view descriptions of existing attributes. +// // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 +// "version": "0.2.0", +// "configurations": [ +// { +// "type": "lldb", +// "request": "launch", +// "name": "Debug config", +// "program": "${workspaceFolder}/config/target/debug/config", +// "args": [ +// "list", +// "r*" +// ], +// "cwd": "${workspaceFolder}" +// }, +// { +// "name": "(macOS) Attach", +// "type": "lldb", +// "request": "attach", +// "pid": "${command:pickMyProcess}", +// }, +// { +// "name": "(Windows) Attach", +// "type": "cppvsdbg", +// "request": "attach", +// "processId": "${command:pickProcess}", +// }, +// { +// "name": "Debug sshdconfig", +// "type": "cppvsdbg", +// "request": "launch", +// "program": "${workspaceFolder}/sshdconfig/target/debug/sshdconfig.exe", +// "args": ["get"], +// "cwd": "${workspaceFolder}" +// } +// ] +// } diff --git a/extensions/powershell/powershell-discover.ps1 b/extensions/powershell/powershell-discover.ps1 new file mode 100644 index 000000000..bfa56b08e --- /dev/null +++ b/extensions/powershell/powershell-discover.ps1 @@ -0,0 +1,13 @@ +$psPaths = $env:PSModulePath -split [System.IO.Path]::PathSeparator | Where-Object { $_ -notmatch 'WindowsPowerShell' } +$manifests = [System.Collections.Generic.List[hashtable]]::new() + +$psPaths | ForEach-Object -Parallel { + $queue = $using:manifests + $files = Get-ChildItem -Path $_ -Recurse -File -Include '*.dsc.resource.json', '*.dsc.resource.yaml', '*.dsc.resource.yml' -ErrorAction Ignore + foreach ($file in $files) { + $m = @{ manifestPath = $file.FullName } + $queue.Add($m) + } +} -ThrottleLimit 10 + +$manifests | ConvertTo-Json -Compress \ No newline at end of file From 9e04ed5e6e960a7ac46c2c0fa1cfc688d489a99a Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Thu, 21 Aug 2025 14:40:57 +0200 Subject: [PATCH 02/20] Use concurrentbag --- extensions/powershell/powershell-discover.ps1 | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/extensions/powershell/powershell-discover.ps1 b/extensions/powershell/powershell-discover.ps1 index bfa56b08e..578cfd6b1 100644 --- a/extensions/powershell/powershell-discover.ps1 +++ b/extensions/powershell/powershell-discover.ps1 @@ -1,13 +1,15 @@ $psPaths = $env:PSModulePath -split [System.IO.Path]::PathSeparator | Where-Object { $_ -notmatch 'WindowsPowerShell' } -$manifests = [System.Collections.Generic.List[hashtable]]::new() + +$m = [System.Collections.Concurrent.ConcurrentBag[hashtable]]::new() $psPaths | ForEach-Object -Parallel { - $queue = $using:manifests - $files = Get-ChildItem -Path $_ -Recurse -File -Include '*.dsc.resource.json', '*.dsc.resource.yaml', '*.dsc.resource.yml' -ErrorAction Ignore + $queue = $using:m + $files = Get-ChildItem -Path $_ -Recurse -File -Filter '*.dsc.resource.*' -ErrorAction Ignore | + Where-Object -Property Extension -In @('.json', '.yaml', '.yml') + foreach ($file in $files) { - $m = @{ manifestPath = $file.FullName } - $queue.Add($m) + $queue.Add(@{ manifestPath = $file.FullName }) } } -ThrottleLimit 10 -$manifests | ConvertTo-Json -Compress \ No newline at end of file +@($m) | ConvertTo-Json -Compress \ No newline at end of file From dae94e474d5ff56dc5e23826f10c275af945cba5 Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Thu, 21 Aug 2025 14:49:30 +0200 Subject: [PATCH 03/20] Use .NET --- extensions/powershell/powershell-discover.ps1 | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/extensions/powershell/powershell-discover.ps1 b/extensions/powershell/powershell-discover.ps1 index 578cfd6b1..b44f3cb5d 100644 --- a/extensions/powershell/powershell-discover.ps1 +++ b/extensions/powershell/powershell-discover.ps1 @@ -4,12 +4,14 @@ $m = [System.Collections.Concurrent.ConcurrentBag[hashtable]]::new() $psPaths | ForEach-Object -Parallel { $queue = $using:m - $files = Get-ChildItem -Path $_ -Recurse -File -Filter '*.dsc.resource.*' -ErrorAction Ignore | - Where-Object -Property Extension -In @('.json', '.yaml', '.yml') - - foreach ($file in $files) { - $queue.Add(@{ manifestPath = $file.FullName }) + $searchPatterns = @('*.dsc.resource.json', '*.dsc.resource.yaml', '*.dsc.resource.yml') + foreach ($pattern in $searchPatterns) { + try { + [System.IO.Directory]::EnumerateFiles($_, $pattern, 'AllDirectories') | ForEach-Object { + $queue.Add(@{ manifestPath = $_ }) + } + } catch { } } -} -ThrottleLimit 10 +} -ThrottleLimit 30 -@($m) | ConvertTo-Json -Compress \ No newline at end of file +[array]$m | ConvertTo-Json -Compress \ No newline at end of file From 6ec70d70e768cb05381ab29f0992392d8c7c3934 Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Thu, 21 Aug 2025 15:26:38 +0200 Subject: [PATCH 04/20] Use .NET with enumeration option --- .vscode/launch.json | 78 +++++++++---------- build.ps1 | 12 ++- dsc/tests/dsc_extension_discover.tests.ps1 | 46 +++++------ extensions/powershell/copy_files.txt | 2 + extensions/powershell/powershell-discover.ps1 | 17 ---- extensions/powershell/powershell.discover.ps1 | 18 +++++ .../powershell/powershell.discover.tests.ps1 | 32 ++++++++ .../powershell/powershell.dsc.extension.json | 18 +++++ 8 files changed, 141 insertions(+), 82 deletions(-) create mode 100644 extensions/powershell/copy_files.txt delete mode 100644 extensions/powershell/powershell-discover.ps1 create mode 100644 extensions/powershell/powershell.discover.ps1 create mode 100644 extensions/powershell/powershell.discover.tests.ps1 create mode 100644 extensions/powershell/powershell.dsc.extension.json diff --git a/.vscode/launch.json b/.vscode/launch.json index 00879d03f..c0fe66904 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,39 +1,39 @@ -// { -// // Use IntelliSense to learn about possible attributes. -// // Hover to view descriptions of existing attributes. -// // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -// "version": "0.2.0", -// "configurations": [ -// { -// "type": "lldb", -// "request": "launch", -// "name": "Debug config", -// "program": "${workspaceFolder}/config/target/debug/config", -// "args": [ -// "list", -// "r*" -// ], -// "cwd": "${workspaceFolder}" -// }, -// { -// "name": "(macOS) Attach", -// "type": "lldb", -// "request": "attach", -// "pid": "${command:pickMyProcess}", -// }, -// { -// "name": "(Windows) Attach", -// "type": "cppvsdbg", -// "request": "attach", -// "processId": "${command:pickProcess}", -// }, -// { -// "name": "Debug sshdconfig", -// "type": "cppvsdbg", -// "request": "launch", -// "program": "${workspaceFolder}/sshdconfig/target/debug/sshdconfig.exe", -// "args": ["get"], -// "cwd": "${workspaceFolder}" -// } -// ] -// } +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug config", + "program": "${workspaceFolder}/config/target/debug/config", + "args": [ + "list", + "r*" + ], + "cwd": "${workspaceFolder}" + }, + { + "name": "(macOS) Attach", + "type": "lldb", + "request": "attach", + "pid": "${command:pickMyProcess}", + }, + { + "name": "(Windows) Attach", + "type": "cppvsdbg", + "request": "attach", + "processId": "${command:pickProcess}", + }, + { + "name": "Debug sshdconfig", + "type": "cppvsdbg", + "request": "launch", + "program": "${workspaceFolder}/sshdconfig/target/debug/sshdconfig.exe", + "args": ["get"], + "cwd": "${workspaceFolder}" + } + ] +} diff --git a/build.ps1 b/build.ps1 index c551877d5..223e83f73 100755 --- a/build.ps1 +++ b/build.ps1 @@ -60,6 +60,8 @@ $filesForWindowsPackage = @( 'NOTICE.txt', 'osinfo.exe', 'osinfo.dsc.resource.json', + 'powershell.discover.ps1', + 'powershell.dsc.extension.json', 'powershell.dsc.resource.json', 'psDscAdapter/', 'psscript.ps1', @@ -98,6 +100,8 @@ $filesForLinuxPackage = @( 'NOTICE.txt', 'osinfo', 'osinfo.dsc.resource.json', + 'powershell.discover.ps1', + 'powershell.dsc.extension.json', 'powershell.dsc.resource.json', 'psDscAdapter/', 'psscript.ps1', @@ -123,6 +127,8 @@ $filesForMacPackage = @( 'NOTICE.txt', 'osinfo', 'osinfo.dsc.resource.json', + 'powershell.discover.ps1', + 'powershell.dsc.extension.json', 'powershell.dsc.resource.json', 'psDscAdapter/', 'psscript.ps1', @@ -324,9 +330,9 @@ if (!$SkipBuild) { } # make sure dependencies are built first so clippy runs correctly - $windows_projects = @("pal", "registry_lib", "registry", "reboot_pending", "wmi-adapter", "configurations/windows", 'extensions/appx') - $macOS_projects = @("resources/brew") - $linux_projects = @("resources/apt") + $windows_projects = @("pal", "registry_lib", "registry", "reboot_pending", "wmi-adapter", "configurations/windows", "extensions/appx", "extensions/powershell") + $macOS_projects = @("resources/brew", "extensions/powershell") + $linux_projects = @("resources/apt", "extensions/powershell") # projects are in dependency order $projects = @( diff --git a/dsc/tests/dsc_extension_discover.tests.ps1 b/dsc/tests/dsc_extension_discover.tests.ps1 index d37455465..f09cca1ad 100644 --- a/dsc/tests/dsc_extension_discover.tests.ps1 +++ b/dsc/tests/dsc_extension_discover.tests.ps1 @@ -23,30 +23,30 @@ Describe 'Discover extension tests' { It 'Discover extensions' { $out = dsc extension list | ConvertFrom-Json $LASTEXITCODE | Should -Be 0 - if ($IsWindows) { - $out.Count | Should -Be 3 -Because ($out | Out-String) - $out[0].type | Should -Be 'Microsoft.DSC.Extension/Bicep' - $out[0].version | Should -Be '0.1.0' - $out[0].capabilities | Should -BeExactly @('import') - $out[0].manifest | Should -Not -BeNullOrEmpty - $out[1].type | Should -Be 'Microsoft.Windows.Appx/Discover' - $out[1].version | Should -Be '0.1.0' - $out[1].capabilities | Should -BeExactly @('discover') - $out[1].manifest | Should -Not -BeNullOrEmpty - $out[2].type | Should -BeExactly 'Test/Discover' - $out[2].version | Should -BeExactly '0.1.0' - $out[2].capabilities | Should -BeExactly @('discover') - $out[2].manifest | Should -Not -BeNullOrEmpty + $expectedExtensions = if ($IsWindows) { + @( + @{ type = 'Microsoft.DSC.Extension/Bicep'; version = '0.1.0'; capabilities = @('import') } + @{ type = 'Microsoft.DSC.Transitional/PSDesiredStateConfiguration'; version = '0.1.0'; capabilities = @('import') } + @{ type = 'Microsoft.Windows.Appx/Discover'; version = '0.1.0'; capabilities = @('discover') } + @{ type = 'Microsoft.PowerShell/Discover'; version = '0.1.0'; capabilities = @('discover') } + @{ type = 'Test/Discover'; version = '0.1.0'; capabilities = @('discover') } + ) } else { - $out.Count | Should -Be 2 -Because ($out | Out-String) - $out[0].type | Should -Be 'Microsoft.DSC.Extension/Bicep' - $out[0].version | Should -Be '0.1.0' - $out[0].capabilities | Should -BeExactly @('import') - $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 + @( + @{ type = 'Microsoft.DSC.Extension/Bicep'; version = '0.1.0'; capabilities = @('import') } + @{ type = 'Microsoft.PowerShell/Discover'; version = '0.1.0'; capabilities = @('discover') } + @{ type = 'Test/Discover'; version = '0.1.0'; capabilities = @('discover') } + ) + } + + $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 } } diff --git a/extensions/powershell/copy_files.txt b/extensions/powershell/copy_files.txt new file mode 100644 index 000000000..e3b12dc13 --- /dev/null +++ b/extensions/powershell/copy_files.txt @@ -0,0 +1,2 @@ +powershell.discover.ps1 +powershell.dsc.extension.json diff --git a/extensions/powershell/powershell-discover.ps1 b/extensions/powershell/powershell-discover.ps1 deleted file mode 100644 index b44f3cb5d..000000000 --- a/extensions/powershell/powershell-discover.ps1 +++ /dev/null @@ -1,17 +0,0 @@ -$psPaths = $env:PSModulePath -split [System.IO.Path]::PathSeparator | Where-Object { $_ -notmatch 'WindowsPowerShell' } - -$m = [System.Collections.Concurrent.ConcurrentBag[hashtable]]::new() - -$psPaths | ForEach-Object -Parallel { - $queue = $using:m - $searchPatterns = @('*.dsc.resource.json', '*.dsc.resource.yaml', '*.dsc.resource.yml') - foreach ($pattern in $searchPatterns) { - try { - [System.IO.Directory]::EnumerateFiles($_, $pattern, 'AllDirectories') | ForEach-Object { - $queue.Add(@{ manifestPath = $_ }) - } - } catch { } - } -} -ThrottleLimit 30 - -[array]$m | ConvertTo-Json -Compress \ No newline at end of file diff --git a/extensions/powershell/powershell.discover.ps1 b/extensions/powershell/powershell.discover.ps1 new file mode 100644 index 000000000..43c4130d3 --- /dev/null +++ b/extensions/powershell/powershell.discover.ps1 @@ -0,0 +1,18 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +$psPaths = $env:PSModulePath -split [System.IO.Path]::PathSeparator | Where-Object { $_ -notmatch 'WindowsPowerShell' } + +$manifests = $psPaths | ForEach-Object -Parallel { + $searchPatterns = @('*.dsc.resource.json', '*.dsc.resource.yaml', '*.dsc.resource.yml') + $enumOptions = [System.IO.EnumerationOptions]@{ IgnoreInaccessible = $false; RecurseSubdirectories = $true } + foreach ($pattern in $searchPatterns) { + try { + [System.IO.Directory]::EnumerateFiles($_, $pattern, $enumOptions) | ForEach-Object { + @{ manifestPath = $_ } + } + } catch { } + } +} -ThrottleLimit 10 + +$manifests | ForEach-Object { $_ | ConvertTo-Json -Compress } \ No newline at end of file diff --git a/extensions/powershell/powershell.discover.tests.ps1 b/extensions/powershell/powershell.discover.tests.ps1 new file mode 100644 index 000000000..6b321d471 --- /dev/null +++ b/extensions/powershell/powershell.discover.tests.ps1 @@ -0,0 +1,32 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +BeforeAll { + $fakeManifest = @{ + '$schema' = "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json" + type = "Test/FakeResource" + version = "0.1.0" + get = @{ + executable = "fakeResource" + args = @( + "get", + @{ + jsonInputArg = "--input" + mandatory = $true + } + ) + } + } + + $manifestPath = Join-Path $TestDrive "fake.dsc.resource.json" + $fakeManifest | ConvertTo-Json -Depth 10 | Set-Content -Path $manifestPath + $env:PSModulePath += [System.IO.Path]::PathSeparator + $TestDrive +} + +Describe 'Tests for PowerShell resource discovery' { + It 'Should find DSC PowerShell resources' { + $out = dsc resource list | ConvertFrom-Json + $LASTEXITCODE | Should -Be 0 + $out.directory | Should -Contain $TestDrive + } +} diff --git a/extensions/powershell/powershell.dsc.extension.json b/extensions/powershell/powershell.dsc.extension.json new file mode 100644 index 000000000..aa10cffa3 --- /dev/null +++ b/extensions/powershell/powershell.dsc.extension.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json", + "type": "Microsoft.PowerShell/Discover", + "version": "0.1.0", + "description": "Discovers DSC resources packaged in PowerShell 7 modules.", + "discover": { + "executable": "pwsh", + "args": [ + "-NoLogo", + "-NonInteractive", + "-ExecutionPolicy", + "Bypass", + "-NoProfile", + "-Command", + "./powershell.discover.ps1" + ] + } +} From d13045dbb5c27521e58a8ccfc758dba0c02308ac Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Thu, 21 Aug 2025 14:38:26 +0200 Subject: [PATCH 05/20] Init --- .vscode/launch.json | 78 +++++++++---------- extensions/powershell/powershell-discover.ps1 | 13 ++++ 2 files changed, 52 insertions(+), 39 deletions(-) create mode 100644 extensions/powershell/powershell-discover.ps1 diff --git a/.vscode/launch.json b/.vscode/launch.json index c0fe66904..00879d03f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,39 +1,39 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "lldb", - "request": "launch", - "name": "Debug config", - "program": "${workspaceFolder}/config/target/debug/config", - "args": [ - "list", - "r*" - ], - "cwd": "${workspaceFolder}" - }, - { - "name": "(macOS) Attach", - "type": "lldb", - "request": "attach", - "pid": "${command:pickMyProcess}", - }, - { - "name": "(Windows) Attach", - "type": "cppvsdbg", - "request": "attach", - "processId": "${command:pickProcess}", - }, - { - "name": "Debug sshdconfig", - "type": "cppvsdbg", - "request": "launch", - "program": "${workspaceFolder}/sshdconfig/target/debug/sshdconfig.exe", - "args": ["get"], - "cwd": "${workspaceFolder}" - } - ] -} +// { +// // Use IntelliSense to learn about possible attributes. +// // Hover to view descriptions of existing attributes. +// // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 +// "version": "0.2.0", +// "configurations": [ +// { +// "type": "lldb", +// "request": "launch", +// "name": "Debug config", +// "program": "${workspaceFolder}/config/target/debug/config", +// "args": [ +// "list", +// "r*" +// ], +// "cwd": "${workspaceFolder}" +// }, +// { +// "name": "(macOS) Attach", +// "type": "lldb", +// "request": "attach", +// "pid": "${command:pickMyProcess}", +// }, +// { +// "name": "(Windows) Attach", +// "type": "cppvsdbg", +// "request": "attach", +// "processId": "${command:pickProcess}", +// }, +// { +// "name": "Debug sshdconfig", +// "type": "cppvsdbg", +// "request": "launch", +// "program": "${workspaceFolder}/sshdconfig/target/debug/sshdconfig.exe", +// "args": ["get"], +// "cwd": "${workspaceFolder}" +// } +// ] +// } diff --git a/extensions/powershell/powershell-discover.ps1 b/extensions/powershell/powershell-discover.ps1 new file mode 100644 index 000000000..bfa56b08e --- /dev/null +++ b/extensions/powershell/powershell-discover.ps1 @@ -0,0 +1,13 @@ +$psPaths = $env:PSModulePath -split [System.IO.Path]::PathSeparator | Where-Object { $_ -notmatch 'WindowsPowerShell' } +$manifests = [System.Collections.Generic.List[hashtable]]::new() + +$psPaths | ForEach-Object -Parallel { + $queue = $using:manifests + $files = Get-ChildItem -Path $_ -Recurse -File -Include '*.dsc.resource.json', '*.dsc.resource.yaml', '*.dsc.resource.yml' -ErrorAction Ignore + foreach ($file in $files) { + $m = @{ manifestPath = $file.FullName } + $queue.Add($m) + } +} -ThrottleLimit 10 + +$manifests | ConvertTo-Json -Compress \ No newline at end of file From 33b7ab2dfbb773c2d84aa92e14e2eb44b14ba12b Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Thu, 21 Aug 2025 14:40:57 +0200 Subject: [PATCH 06/20] Use concurrentbag --- extensions/powershell/powershell-discover.ps1 | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/extensions/powershell/powershell-discover.ps1 b/extensions/powershell/powershell-discover.ps1 index bfa56b08e..578cfd6b1 100644 --- a/extensions/powershell/powershell-discover.ps1 +++ b/extensions/powershell/powershell-discover.ps1 @@ -1,13 +1,15 @@ $psPaths = $env:PSModulePath -split [System.IO.Path]::PathSeparator | Where-Object { $_ -notmatch 'WindowsPowerShell' } -$manifests = [System.Collections.Generic.List[hashtable]]::new() + +$m = [System.Collections.Concurrent.ConcurrentBag[hashtable]]::new() $psPaths | ForEach-Object -Parallel { - $queue = $using:manifests - $files = Get-ChildItem -Path $_ -Recurse -File -Include '*.dsc.resource.json', '*.dsc.resource.yaml', '*.dsc.resource.yml' -ErrorAction Ignore + $queue = $using:m + $files = Get-ChildItem -Path $_ -Recurse -File -Filter '*.dsc.resource.*' -ErrorAction Ignore | + Where-Object -Property Extension -In @('.json', '.yaml', '.yml') + foreach ($file in $files) { - $m = @{ manifestPath = $file.FullName } - $queue.Add($m) + $queue.Add(@{ manifestPath = $file.FullName }) } } -ThrottleLimit 10 -$manifests | ConvertTo-Json -Compress \ No newline at end of file +@($m) | ConvertTo-Json -Compress \ No newline at end of file From f12038ed1e8fafff87b74bddd744dbb2d27634e6 Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Thu, 21 Aug 2025 14:49:30 +0200 Subject: [PATCH 07/20] Use .NET --- extensions/powershell/powershell-discover.ps1 | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/extensions/powershell/powershell-discover.ps1 b/extensions/powershell/powershell-discover.ps1 index 578cfd6b1..b44f3cb5d 100644 --- a/extensions/powershell/powershell-discover.ps1 +++ b/extensions/powershell/powershell-discover.ps1 @@ -4,12 +4,14 @@ $m = [System.Collections.Concurrent.ConcurrentBag[hashtable]]::new() $psPaths | ForEach-Object -Parallel { $queue = $using:m - $files = Get-ChildItem -Path $_ -Recurse -File -Filter '*.dsc.resource.*' -ErrorAction Ignore | - Where-Object -Property Extension -In @('.json', '.yaml', '.yml') - - foreach ($file in $files) { - $queue.Add(@{ manifestPath = $file.FullName }) + $searchPatterns = @('*.dsc.resource.json', '*.dsc.resource.yaml', '*.dsc.resource.yml') + foreach ($pattern in $searchPatterns) { + try { + [System.IO.Directory]::EnumerateFiles($_, $pattern, 'AllDirectories') | ForEach-Object { + $queue.Add(@{ manifestPath = $_ }) + } + } catch { } } -} -ThrottleLimit 10 +} -ThrottleLimit 30 -@($m) | ConvertTo-Json -Compress \ No newline at end of file +[array]$m | ConvertTo-Json -Compress \ No newline at end of file From 991f7ce027fd663bc71d9044c186198e4f11e69d Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Thu, 21 Aug 2025 15:26:38 +0200 Subject: [PATCH 08/20] Use .NET with enumeration option --- .vscode/launch.json | 78 +++++++++---------- build.ps1 | 12 ++- dsc/tests/dsc_extension_discover.tests.ps1 | 46 +++++------ extensions/powershell/copy_files.txt | 2 + extensions/powershell/powershell-discover.ps1 | 17 ---- extensions/powershell/powershell.discover.ps1 | 18 +++++ .../powershell/powershell.discover.tests.ps1 | 32 ++++++++ .../powershell/powershell.dsc.extension.json | 18 +++++ 8 files changed, 141 insertions(+), 82 deletions(-) create mode 100644 extensions/powershell/copy_files.txt delete mode 100644 extensions/powershell/powershell-discover.ps1 create mode 100644 extensions/powershell/powershell.discover.ps1 create mode 100644 extensions/powershell/powershell.discover.tests.ps1 create mode 100644 extensions/powershell/powershell.dsc.extension.json diff --git a/.vscode/launch.json b/.vscode/launch.json index 00879d03f..c0fe66904 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,39 +1,39 @@ -// { -// // Use IntelliSense to learn about possible attributes. -// // Hover to view descriptions of existing attributes. -// // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -// "version": "0.2.0", -// "configurations": [ -// { -// "type": "lldb", -// "request": "launch", -// "name": "Debug config", -// "program": "${workspaceFolder}/config/target/debug/config", -// "args": [ -// "list", -// "r*" -// ], -// "cwd": "${workspaceFolder}" -// }, -// { -// "name": "(macOS) Attach", -// "type": "lldb", -// "request": "attach", -// "pid": "${command:pickMyProcess}", -// }, -// { -// "name": "(Windows) Attach", -// "type": "cppvsdbg", -// "request": "attach", -// "processId": "${command:pickProcess}", -// }, -// { -// "name": "Debug sshdconfig", -// "type": "cppvsdbg", -// "request": "launch", -// "program": "${workspaceFolder}/sshdconfig/target/debug/sshdconfig.exe", -// "args": ["get"], -// "cwd": "${workspaceFolder}" -// } -// ] -// } +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug config", + "program": "${workspaceFolder}/config/target/debug/config", + "args": [ + "list", + "r*" + ], + "cwd": "${workspaceFolder}" + }, + { + "name": "(macOS) Attach", + "type": "lldb", + "request": "attach", + "pid": "${command:pickMyProcess}", + }, + { + "name": "(Windows) Attach", + "type": "cppvsdbg", + "request": "attach", + "processId": "${command:pickProcess}", + }, + { + "name": "Debug sshdconfig", + "type": "cppvsdbg", + "request": "launch", + "program": "${workspaceFolder}/sshdconfig/target/debug/sshdconfig.exe", + "args": ["get"], + "cwd": "${workspaceFolder}" + } + ] +} diff --git a/build.ps1 b/build.ps1 index 78f71004a..375bbb78a 100755 --- a/build.ps1 +++ b/build.ps1 @@ -63,6 +63,8 @@ $filesForWindowsPackage = @( 'NOTICE.txt', 'osinfo.exe', 'osinfo.dsc.resource.json', + 'powershell.discover.ps1', + 'powershell.dsc.extension.json', 'powershell.dsc.resource.json', 'psDscAdapter/', 'psscript.ps1', @@ -101,6 +103,8 @@ $filesForLinuxPackage = @( 'NOTICE.txt', 'osinfo', 'osinfo.dsc.resource.json', + 'powershell.discover.ps1', + 'powershell.dsc.extension.json', 'powershell.dsc.resource.json', 'psDscAdapter/', 'psscript.ps1', @@ -126,6 +130,8 @@ $filesForMacPackage = @( 'NOTICE.txt', 'osinfo', 'osinfo.dsc.resource.json', + 'powershell.discover.ps1', + 'powershell.dsc.extension.json', 'powershell.dsc.resource.json', 'psDscAdapter/', 'psscript.ps1', @@ -331,9 +337,9 @@ if (!$SkipBuild) { New-Item -ItemType Directory $target -ErrorAction Ignore > $null # make sure dependencies are built first so clippy runs correctly - $windows_projects = @("pal", "registry_lib", "registry", "reboot_pending", "wmi-adapter", "configurations/windows", 'extensions/appx') - $macOS_projects = @("resources/brew") - $linux_projects = @("resources/apt") + $windows_projects = @("pal", "registry_lib", "registry", "reboot_pending", "wmi-adapter", "configurations/windows", "extensions/appx", "extensions/powershell") + $macOS_projects = @("resources/brew", "extensions/powershell") + $linux_projects = @("resources/apt", "extensions/powershell") # projects are in dependency order $projects = @( diff --git a/dsc/tests/dsc_extension_discover.tests.ps1 b/dsc/tests/dsc_extension_discover.tests.ps1 index d37455465..f09cca1ad 100644 --- a/dsc/tests/dsc_extension_discover.tests.ps1 +++ b/dsc/tests/dsc_extension_discover.tests.ps1 @@ -23,30 +23,30 @@ Describe 'Discover extension tests' { It 'Discover extensions' { $out = dsc extension list | ConvertFrom-Json $LASTEXITCODE | Should -Be 0 - if ($IsWindows) { - $out.Count | Should -Be 3 -Because ($out | Out-String) - $out[0].type | Should -Be 'Microsoft.DSC.Extension/Bicep' - $out[0].version | Should -Be '0.1.0' - $out[0].capabilities | Should -BeExactly @('import') - $out[0].manifest | Should -Not -BeNullOrEmpty - $out[1].type | Should -Be 'Microsoft.Windows.Appx/Discover' - $out[1].version | Should -Be '0.1.0' - $out[1].capabilities | Should -BeExactly @('discover') - $out[1].manifest | Should -Not -BeNullOrEmpty - $out[2].type | Should -BeExactly 'Test/Discover' - $out[2].version | Should -BeExactly '0.1.0' - $out[2].capabilities | Should -BeExactly @('discover') - $out[2].manifest | Should -Not -BeNullOrEmpty + $expectedExtensions = if ($IsWindows) { + @( + @{ type = 'Microsoft.DSC.Extension/Bicep'; version = '0.1.0'; capabilities = @('import') } + @{ type = 'Microsoft.DSC.Transitional/PSDesiredStateConfiguration'; version = '0.1.0'; capabilities = @('import') } + @{ type = 'Microsoft.Windows.Appx/Discover'; version = '0.1.0'; capabilities = @('discover') } + @{ type = 'Microsoft.PowerShell/Discover'; version = '0.1.0'; capabilities = @('discover') } + @{ type = 'Test/Discover'; version = '0.1.0'; capabilities = @('discover') } + ) } else { - $out.Count | Should -Be 2 -Because ($out | Out-String) - $out[0].type | Should -Be 'Microsoft.DSC.Extension/Bicep' - $out[0].version | Should -Be '0.1.0' - $out[0].capabilities | Should -BeExactly @('import') - $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 + @( + @{ type = 'Microsoft.DSC.Extension/Bicep'; version = '0.1.0'; capabilities = @('import') } + @{ type = 'Microsoft.PowerShell/Discover'; version = '0.1.0'; capabilities = @('discover') } + @{ type = 'Test/Discover'; version = '0.1.0'; capabilities = @('discover') } + ) + } + + $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 } } diff --git a/extensions/powershell/copy_files.txt b/extensions/powershell/copy_files.txt new file mode 100644 index 000000000..e3b12dc13 --- /dev/null +++ b/extensions/powershell/copy_files.txt @@ -0,0 +1,2 @@ +powershell.discover.ps1 +powershell.dsc.extension.json diff --git a/extensions/powershell/powershell-discover.ps1 b/extensions/powershell/powershell-discover.ps1 deleted file mode 100644 index b44f3cb5d..000000000 --- a/extensions/powershell/powershell-discover.ps1 +++ /dev/null @@ -1,17 +0,0 @@ -$psPaths = $env:PSModulePath -split [System.IO.Path]::PathSeparator | Where-Object { $_ -notmatch 'WindowsPowerShell' } - -$m = [System.Collections.Concurrent.ConcurrentBag[hashtable]]::new() - -$psPaths | ForEach-Object -Parallel { - $queue = $using:m - $searchPatterns = @('*.dsc.resource.json', '*.dsc.resource.yaml', '*.dsc.resource.yml') - foreach ($pattern in $searchPatterns) { - try { - [System.IO.Directory]::EnumerateFiles($_, $pattern, 'AllDirectories') | ForEach-Object { - $queue.Add(@{ manifestPath = $_ }) - } - } catch { } - } -} -ThrottleLimit 30 - -[array]$m | ConvertTo-Json -Compress \ No newline at end of file diff --git a/extensions/powershell/powershell.discover.ps1 b/extensions/powershell/powershell.discover.ps1 new file mode 100644 index 000000000..43c4130d3 --- /dev/null +++ b/extensions/powershell/powershell.discover.ps1 @@ -0,0 +1,18 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +$psPaths = $env:PSModulePath -split [System.IO.Path]::PathSeparator | Where-Object { $_ -notmatch 'WindowsPowerShell' } + +$manifests = $psPaths | ForEach-Object -Parallel { + $searchPatterns = @('*.dsc.resource.json', '*.dsc.resource.yaml', '*.dsc.resource.yml') + $enumOptions = [System.IO.EnumerationOptions]@{ IgnoreInaccessible = $false; RecurseSubdirectories = $true } + foreach ($pattern in $searchPatterns) { + try { + [System.IO.Directory]::EnumerateFiles($_, $pattern, $enumOptions) | ForEach-Object { + @{ manifestPath = $_ } + } + } catch { } + } +} -ThrottleLimit 10 + +$manifests | ForEach-Object { $_ | ConvertTo-Json -Compress } \ No newline at end of file diff --git a/extensions/powershell/powershell.discover.tests.ps1 b/extensions/powershell/powershell.discover.tests.ps1 new file mode 100644 index 000000000..6b321d471 --- /dev/null +++ b/extensions/powershell/powershell.discover.tests.ps1 @@ -0,0 +1,32 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +BeforeAll { + $fakeManifest = @{ + '$schema' = "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json" + type = "Test/FakeResource" + version = "0.1.0" + get = @{ + executable = "fakeResource" + args = @( + "get", + @{ + jsonInputArg = "--input" + mandatory = $true + } + ) + } + } + + $manifestPath = Join-Path $TestDrive "fake.dsc.resource.json" + $fakeManifest | ConvertTo-Json -Depth 10 | Set-Content -Path $manifestPath + $env:PSModulePath += [System.IO.Path]::PathSeparator + $TestDrive +} + +Describe 'Tests for PowerShell resource discovery' { + It 'Should find DSC PowerShell resources' { + $out = dsc resource list | ConvertFrom-Json + $LASTEXITCODE | Should -Be 0 + $out.directory | Should -Contain $TestDrive + } +} diff --git a/extensions/powershell/powershell.dsc.extension.json b/extensions/powershell/powershell.dsc.extension.json new file mode 100644 index 000000000..aa10cffa3 --- /dev/null +++ b/extensions/powershell/powershell.dsc.extension.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json", + "type": "Microsoft.PowerShell/Discover", + "version": "0.1.0", + "description": "Discovers DSC resources packaged in PowerShell 7 modules.", + "discover": { + "executable": "pwsh", + "args": [ + "-NoLogo", + "-NonInteractive", + "-ExecutionPolicy", + "Bypass", + "-NoProfile", + "-Command", + "./powershell.discover.ps1" + ] + } +} From 1e80819244d8af75e931aea586022fc9ce9b2540 Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Wed, 27 Aug 2025 03:10:22 +0200 Subject: [PATCH 09/20] Remove undiscovered resource --- dsc/tests/dsc_extension_discover.tests.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/dsc/tests/dsc_extension_discover.tests.ps1 b/dsc/tests/dsc_extension_discover.tests.ps1 index f09cca1ad..3c7c44a54 100644 --- a/dsc/tests/dsc_extension_discover.tests.ps1 +++ b/dsc/tests/dsc_extension_discover.tests.ps1 @@ -26,7 +26,6 @@ Describe 'Discover extension tests' { $expectedExtensions = if ($IsWindows) { @( @{ type = 'Microsoft.DSC.Extension/Bicep'; version = '0.1.0'; capabilities = @('import') } - @{ type = 'Microsoft.DSC.Transitional/PSDesiredStateConfiguration'; version = '0.1.0'; capabilities = @('import') } @{ type = 'Microsoft.Windows.Appx/Discover'; version = '0.1.0'; capabilities = @('discover') } @{ type = 'Microsoft.PowerShell/Discover'; version = '0.1.0'; capabilities = @('discover') } @{ type = 'Test/Discover'; version = '0.1.0'; capabilities = @('discover') } From 69ef04258f058c05dfb64c8200e9cd6a9d461805 Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Thu, 21 Aug 2025 14:38:26 +0200 Subject: [PATCH 10/20] Init --- .vscode/launch.json | 78 +++++++++---------- extensions/powershell/powershell-discover.ps1 | 13 ++++ 2 files changed, 52 insertions(+), 39 deletions(-) create mode 100644 extensions/powershell/powershell-discover.ps1 diff --git a/.vscode/launch.json b/.vscode/launch.json index c0fe66904..00879d03f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,39 +1,39 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "lldb", - "request": "launch", - "name": "Debug config", - "program": "${workspaceFolder}/config/target/debug/config", - "args": [ - "list", - "r*" - ], - "cwd": "${workspaceFolder}" - }, - { - "name": "(macOS) Attach", - "type": "lldb", - "request": "attach", - "pid": "${command:pickMyProcess}", - }, - { - "name": "(Windows) Attach", - "type": "cppvsdbg", - "request": "attach", - "processId": "${command:pickProcess}", - }, - { - "name": "Debug sshdconfig", - "type": "cppvsdbg", - "request": "launch", - "program": "${workspaceFolder}/sshdconfig/target/debug/sshdconfig.exe", - "args": ["get"], - "cwd": "${workspaceFolder}" - } - ] -} +// { +// // Use IntelliSense to learn about possible attributes. +// // Hover to view descriptions of existing attributes. +// // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 +// "version": "0.2.0", +// "configurations": [ +// { +// "type": "lldb", +// "request": "launch", +// "name": "Debug config", +// "program": "${workspaceFolder}/config/target/debug/config", +// "args": [ +// "list", +// "r*" +// ], +// "cwd": "${workspaceFolder}" +// }, +// { +// "name": "(macOS) Attach", +// "type": "lldb", +// "request": "attach", +// "pid": "${command:pickMyProcess}", +// }, +// { +// "name": "(Windows) Attach", +// "type": "cppvsdbg", +// "request": "attach", +// "processId": "${command:pickProcess}", +// }, +// { +// "name": "Debug sshdconfig", +// "type": "cppvsdbg", +// "request": "launch", +// "program": "${workspaceFolder}/sshdconfig/target/debug/sshdconfig.exe", +// "args": ["get"], +// "cwd": "${workspaceFolder}" +// } +// ] +// } diff --git a/extensions/powershell/powershell-discover.ps1 b/extensions/powershell/powershell-discover.ps1 new file mode 100644 index 000000000..bfa56b08e --- /dev/null +++ b/extensions/powershell/powershell-discover.ps1 @@ -0,0 +1,13 @@ +$psPaths = $env:PSModulePath -split [System.IO.Path]::PathSeparator | Where-Object { $_ -notmatch 'WindowsPowerShell' } +$manifests = [System.Collections.Generic.List[hashtable]]::new() + +$psPaths | ForEach-Object -Parallel { + $queue = $using:manifests + $files = Get-ChildItem -Path $_ -Recurse -File -Include '*.dsc.resource.json', '*.dsc.resource.yaml', '*.dsc.resource.yml' -ErrorAction Ignore + foreach ($file in $files) { + $m = @{ manifestPath = $file.FullName } + $queue.Add($m) + } +} -ThrottleLimit 10 + +$manifests | ConvertTo-Json -Compress \ No newline at end of file From f7c606afba2331af20c47b66ebad37e681c92d0c Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Thu, 21 Aug 2025 14:40:57 +0200 Subject: [PATCH 11/20] Use concurrentbag --- extensions/powershell/powershell-discover.ps1 | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/extensions/powershell/powershell-discover.ps1 b/extensions/powershell/powershell-discover.ps1 index bfa56b08e..578cfd6b1 100644 --- a/extensions/powershell/powershell-discover.ps1 +++ b/extensions/powershell/powershell-discover.ps1 @@ -1,13 +1,15 @@ $psPaths = $env:PSModulePath -split [System.IO.Path]::PathSeparator | Where-Object { $_ -notmatch 'WindowsPowerShell' } -$manifests = [System.Collections.Generic.List[hashtable]]::new() + +$m = [System.Collections.Concurrent.ConcurrentBag[hashtable]]::new() $psPaths | ForEach-Object -Parallel { - $queue = $using:manifests - $files = Get-ChildItem -Path $_ -Recurse -File -Include '*.dsc.resource.json', '*.dsc.resource.yaml', '*.dsc.resource.yml' -ErrorAction Ignore + $queue = $using:m + $files = Get-ChildItem -Path $_ -Recurse -File -Filter '*.dsc.resource.*' -ErrorAction Ignore | + Where-Object -Property Extension -In @('.json', '.yaml', '.yml') + foreach ($file in $files) { - $m = @{ manifestPath = $file.FullName } - $queue.Add($m) + $queue.Add(@{ manifestPath = $file.FullName }) } } -ThrottleLimit 10 -$manifests | ConvertTo-Json -Compress \ No newline at end of file +@($m) | ConvertTo-Json -Compress \ No newline at end of file From f93e69120e5f3647eaae0b30baf94b1c1a32e8d6 Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Thu, 21 Aug 2025 14:49:30 +0200 Subject: [PATCH 12/20] Use .NET --- extensions/powershell/powershell-discover.ps1 | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/extensions/powershell/powershell-discover.ps1 b/extensions/powershell/powershell-discover.ps1 index 578cfd6b1..b44f3cb5d 100644 --- a/extensions/powershell/powershell-discover.ps1 +++ b/extensions/powershell/powershell-discover.ps1 @@ -4,12 +4,14 @@ $m = [System.Collections.Concurrent.ConcurrentBag[hashtable]]::new() $psPaths | ForEach-Object -Parallel { $queue = $using:m - $files = Get-ChildItem -Path $_ -Recurse -File -Filter '*.dsc.resource.*' -ErrorAction Ignore | - Where-Object -Property Extension -In @('.json', '.yaml', '.yml') - - foreach ($file in $files) { - $queue.Add(@{ manifestPath = $file.FullName }) + $searchPatterns = @('*.dsc.resource.json', '*.dsc.resource.yaml', '*.dsc.resource.yml') + foreach ($pattern in $searchPatterns) { + try { + [System.IO.Directory]::EnumerateFiles($_, $pattern, 'AllDirectories') | ForEach-Object { + $queue.Add(@{ manifestPath = $_ }) + } + } catch { } } -} -ThrottleLimit 10 +} -ThrottleLimit 30 -@($m) | ConvertTo-Json -Compress \ No newline at end of file +[array]$m | ConvertTo-Json -Compress \ No newline at end of file From 16bf2f55f2ca750eb27c4dd078e783add69f19a7 Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Thu, 21 Aug 2025 15:26:38 +0200 Subject: [PATCH 13/20] Use .NET with enumeration option --- .vscode/launch.json | 78 +++++++++---------- build.ps1 | 12 ++- dsc/tests/dsc_extension_discover.tests.ps1 | 46 +++++------ extensions/powershell/copy_files.txt | 2 + extensions/powershell/powershell-discover.ps1 | 17 ---- extensions/powershell/powershell.discover.ps1 | 18 +++++ .../powershell/powershell.discover.tests.ps1 | 32 ++++++++ .../powershell/powershell.dsc.extension.json | 18 +++++ 8 files changed, 141 insertions(+), 82 deletions(-) create mode 100644 extensions/powershell/copy_files.txt delete mode 100644 extensions/powershell/powershell-discover.ps1 create mode 100644 extensions/powershell/powershell.discover.ps1 create mode 100644 extensions/powershell/powershell.discover.tests.ps1 create mode 100644 extensions/powershell/powershell.dsc.extension.json diff --git a/.vscode/launch.json b/.vscode/launch.json index 00879d03f..c0fe66904 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,39 +1,39 @@ -// { -// // Use IntelliSense to learn about possible attributes. -// // Hover to view descriptions of existing attributes. -// // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -// "version": "0.2.0", -// "configurations": [ -// { -// "type": "lldb", -// "request": "launch", -// "name": "Debug config", -// "program": "${workspaceFolder}/config/target/debug/config", -// "args": [ -// "list", -// "r*" -// ], -// "cwd": "${workspaceFolder}" -// }, -// { -// "name": "(macOS) Attach", -// "type": "lldb", -// "request": "attach", -// "pid": "${command:pickMyProcess}", -// }, -// { -// "name": "(Windows) Attach", -// "type": "cppvsdbg", -// "request": "attach", -// "processId": "${command:pickProcess}", -// }, -// { -// "name": "Debug sshdconfig", -// "type": "cppvsdbg", -// "request": "launch", -// "program": "${workspaceFolder}/sshdconfig/target/debug/sshdconfig.exe", -// "args": ["get"], -// "cwd": "${workspaceFolder}" -// } -// ] -// } +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug config", + "program": "${workspaceFolder}/config/target/debug/config", + "args": [ + "list", + "r*" + ], + "cwd": "${workspaceFolder}" + }, + { + "name": "(macOS) Attach", + "type": "lldb", + "request": "attach", + "pid": "${command:pickMyProcess}", + }, + { + "name": "(Windows) Attach", + "type": "cppvsdbg", + "request": "attach", + "processId": "${command:pickProcess}", + }, + { + "name": "Debug sshdconfig", + "type": "cppvsdbg", + "request": "launch", + "program": "${workspaceFolder}/sshdconfig/target/debug/sshdconfig.exe", + "args": ["get"], + "cwd": "${workspaceFolder}" + } + ] +} diff --git a/build.ps1 b/build.ps1 index 78f71004a..375bbb78a 100755 --- a/build.ps1 +++ b/build.ps1 @@ -63,6 +63,8 @@ $filesForWindowsPackage = @( 'NOTICE.txt', 'osinfo.exe', 'osinfo.dsc.resource.json', + 'powershell.discover.ps1', + 'powershell.dsc.extension.json', 'powershell.dsc.resource.json', 'psDscAdapter/', 'psscript.ps1', @@ -101,6 +103,8 @@ $filesForLinuxPackage = @( 'NOTICE.txt', 'osinfo', 'osinfo.dsc.resource.json', + 'powershell.discover.ps1', + 'powershell.dsc.extension.json', 'powershell.dsc.resource.json', 'psDscAdapter/', 'psscript.ps1', @@ -126,6 +130,8 @@ $filesForMacPackage = @( 'NOTICE.txt', 'osinfo', 'osinfo.dsc.resource.json', + 'powershell.discover.ps1', + 'powershell.dsc.extension.json', 'powershell.dsc.resource.json', 'psDscAdapter/', 'psscript.ps1', @@ -331,9 +337,9 @@ if (!$SkipBuild) { New-Item -ItemType Directory $target -ErrorAction Ignore > $null # make sure dependencies are built first so clippy runs correctly - $windows_projects = @("pal", "registry_lib", "registry", "reboot_pending", "wmi-adapter", "configurations/windows", 'extensions/appx') - $macOS_projects = @("resources/brew") - $linux_projects = @("resources/apt") + $windows_projects = @("pal", "registry_lib", "registry", "reboot_pending", "wmi-adapter", "configurations/windows", "extensions/appx", "extensions/powershell") + $macOS_projects = @("resources/brew", "extensions/powershell") + $linux_projects = @("resources/apt", "extensions/powershell") # projects are in dependency order $projects = @( diff --git a/dsc/tests/dsc_extension_discover.tests.ps1 b/dsc/tests/dsc_extension_discover.tests.ps1 index 03da8c429..1ad519047 100644 --- a/dsc/tests/dsc_extension_discover.tests.ps1 +++ b/dsc/tests/dsc_extension_discover.tests.ps1 @@ -23,30 +23,30 @@ Describe 'Discover extension tests' { It 'Discover extensions' { $out = dsc extension list | ConvertFrom-Json $LASTEXITCODE | Should -Be 0 - if ($IsWindows) { - $out.Count | Should -Be 3 -Because ($out | Out-String) - $out[0].type | Should -Be 'Microsoft.DSC.Extension/Bicep' - $out[0].version | Should -Be '0.1.0' - $out[0].capabilities | Should -BeExactly @('import') - $out[0].manifest | Should -Not -BeNullOrEmpty - $out[1].type | Should -Be 'Microsoft.Windows.Appx/Discover' - $out[1].version | Should -Be '0.1.0' - $out[1].capabilities | Should -BeExactly @('discover') - $out[1].manifest | Should -Not -BeNullOrEmpty - $out[2].type | Should -BeExactly 'Test/Discover' - $out[2].version | Should -BeExactly '0.1.0' - $out[2].capabilities | Should -BeExactly @('discover') - $out[2].manifest | Should -Not -BeNullOrEmpty + $expectedExtensions = if ($IsWindows) { + @( + @{ type = 'Microsoft.DSC.Extension/Bicep'; version = '0.1.0'; capabilities = @('import') } + @{ type = 'Microsoft.DSC.Transitional/PSDesiredStateConfiguration'; version = '0.1.0'; capabilities = @('import') } + @{ type = 'Microsoft.Windows.Appx/Discover'; version = '0.1.0'; capabilities = @('discover') } + @{ type = 'Microsoft.PowerShell/Discover'; version = '0.1.0'; capabilities = @('discover') } + @{ type = 'Test/Discover'; version = '0.1.0'; capabilities = @('discover') } + ) } else { - $out.Count | Should -Be 2 -Because ($out | Out-String) - $out[0].type | Should -Be 'Microsoft.DSC.Extension/Bicep' - $out[0].version | Should -Be '0.1.0' - $out[0].capabilities | Should -BeExactly @('import') - $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 + @( + @{ type = 'Microsoft.DSC.Extension/Bicep'; version = '0.1.0'; capabilities = @('import') } + @{ type = 'Microsoft.PowerShell/Discover'; version = '0.1.0'; capabilities = @('discover') } + @{ type = 'Test/Discover'; version = '0.1.0'; capabilities = @('discover') } + ) + } + + $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 } } diff --git a/extensions/powershell/copy_files.txt b/extensions/powershell/copy_files.txt new file mode 100644 index 000000000..e3b12dc13 --- /dev/null +++ b/extensions/powershell/copy_files.txt @@ -0,0 +1,2 @@ +powershell.discover.ps1 +powershell.dsc.extension.json diff --git a/extensions/powershell/powershell-discover.ps1 b/extensions/powershell/powershell-discover.ps1 deleted file mode 100644 index b44f3cb5d..000000000 --- a/extensions/powershell/powershell-discover.ps1 +++ /dev/null @@ -1,17 +0,0 @@ -$psPaths = $env:PSModulePath -split [System.IO.Path]::PathSeparator | Where-Object { $_ -notmatch 'WindowsPowerShell' } - -$m = [System.Collections.Concurrent.ConcurrentBag[hashtable]]::new() - -$psPaths | ForEach-Object -Parallel { - $queue = $using:m - $searchPatterns = @('*.dsc.resource.json', '*.dsc.resource.yaml', '*.dsc.resource.yml') - foreach ($pattern in $searchPatterns) { - try { - [System.IO.Directory]::EnumerateFiles($_, $pattern, 'AllDirectories') | ForEach-Object { - $queue.Add(@{ manifestPath = $_ }) - } - } catch { } - } -} -ThrottleLimit 30 - -[array]$m | ConvertTo-Json -Compress \ No newline at end of file diff --git a/extensions/powershell/powershell.discover.ps1 b/extensions/powershell/powershell.discover.ps1 new file mode 100644 index 000000000..43c4130d3 --- /dev/null +++ b/extensions/powershell/powershell.discover.ps1 @@ -0,0 +1,18 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +$psPaths = $env:PSModulePath -split [System.IO.Path]::PathSeparator | Where-Object { $_ -notmatch 'WindowsPowerShell' } + +$manifests = $psPaths | ForEach-Object -Parallel { + $searchPatterns = @('*.dsc.resource.json', '*.dsc.resource.yaml', '*.dsc.resource.yml') + $enumOptions = [System.IO.EnumerationOptions]@{ IgnoreInaccessible = $false; RecurseSubdirectories = $true } + foreach ($pattern in $searchPatterns) { + try { + [System.IO.Directory]::EnumerateFiles($_, $pattern, $enumOptions) | ForEach-Object { + @{ manifestPath = $_ } + } + } catch { } + } +} -ThrottleLimit 10 + +$manifests | ForEach-Object { $_ | ConvertTo-Json -Compress } \ No newline at end of file diff --git a/extensions/powershell/powershell.discover.tests.ps1 b/extensions/powershell/powershell.discover.tests.ps1 new file mode 100644 index 000000000..6b321d471 --- /dev/null +++ b/extensions/powershell/powershell.discover.tests.ps1 @@ -0,0 +1,32 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +BeforeAll { + $fakeManifest = @{ + '$schema' = "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json" + type = "Test/FakeResource" + version = "0.1.0" + get = @{ + executable = "fakeResource" + args = @( + "get", + @{ + jsonInputArg = "--input" + mandatory = $true + } + ) + } + } + + $manifestPath = Join-Path $TestDrive "fake.dsc.resource.json" + $fakeManifest | ConvertTo-Json -Depth 10 | Set-Content -Path $manifestPath + $env:PSModulePath += [System.IO.Path]::PathSeparator + $TestDrive +} + +Describe 'Tests for PowerShell resource discovery' { + It 'Should find DSC PowerShell resources' { + $out = dsc resource list | ConvertFrom-Json + $LASTEXITCODE | Should -Be 0 + $out.directory | Should -Contain $TestDrive + } +} diff --git a/extensions/powershell/powershell.dsc.extension.json b/extensions/powershell/powershell.dsc.extension.json new file mode 100644 index 000000000..aa10cffa3 --- /dev/null +++ b/extensions/powershell/powershell.dsc.extension.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json", + "type": "Microsoft.PowerShell/Discover", + "version": "0.1.0", + "description": "Discovers DSC resources packaged in PowerShell 7 modules.", + "discover": { + "executable": "pwsh", + "args": [ + "-NoLogo", + "-NonInteractive", + "-ExecutionPolicy", + "Bypass", + "-NoProfile", + "-Command", + "./powershell.discover.ps1" + ] + } +} From 34375b6c7bc41d7398782bf029929836969c5b8e Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Thu, 21 Aug 2025 14:38:26 +0200 Subject: [PATCH 14/20] Init --- .vscode/launch.json | 78 +++++++++---------- extensions/powershell/powershell-discover.ps1 | 13 ++++ 2 files changed, 52 insertions(+), 39 deletions(-) create mode 100644 extensions/powershell/powershell-discover.ps1 diff --git a/.vscode/launch.json b/.vscode/launch.json index c0fe66904..00879d03f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,39 +1,39 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "lldb", - "request": "launch", - "name": "Debug config", - "program": "${workspaceFolder}/config/target/debug/config", - "args": [ - "list", - "r*" - ], - "cwd": "${workspaceFolder}" - }, - { - "name": "(macOS) Attach", - "type": "lldb", - "request": "attach", - "pid": "${command:pickMyProcess}", - }, - { - "name": "(Windows) Attach", - "type": "cppvsdbg", - "request": "attach", - "processId": "${command:pickProcess}", - }, - { - "name": "Debug sshdconfig", - "type": "cppvsdbg", - "request": "launch", - "program": "${workspaceFolder}/sshdconfig/target/debug/sshdconfig.exe", - "args": ["get"], - "cwd": "${workspaceFolder}" - } - ] -} +// { +// // Use IntelliSense to learn about possible attributes. +// // Hover to view descriptions of existing attributes. +// // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 +// "version": "0.2.0", +// "configurations": [ +// { +// "type": "lldb", +// "request": "launch", +// "name": "Debug config", +// "program": "${workspaceFolder}/config/target/debug/config", +// "args": [ +// "list", +// "r*" +// ], +// "cwd": "${workspaceFolder}" +// }, +// { +// "name": "(macOS) Attach", +// "type": "lldb", +// "request": "attach", +// "pid": "${command:pickMyProcess}", +// }, +// { +// "name": "(Windows) Attach", +// "type": "cppvsdbg", +// "request": "attach", +// "processId": "${command:pickProcess}", +// }, +// { +// "name": "Debug sshdconfig", +// "type": "cppvsdbg", +// "request": "launch", +// "program": "${workspaceFolder}/sshdconfig/target/debug/sshdconfig.exe", +// "args": ["get"], +// "cwd": "${workspaceFolder}" +// } +// ] +// } diff --git a/extensions/powershell/powershell-discover.ps1 b/extensions/powershell/powershell-discover.ps1 new file mode 100644 index 000000000..bfa56b08e --- /dev/null +++ b/extensions/powershell/powershell-discover.ps1 @@ -0,0 +1,13 @@ +$psPaths = $env:PSModulePath -split [System.IO.Path]::PathSeparator | Where-Object { $_ -notmatch 'WindowsPowerShell' } +$manifests = [System.Collections.Generic.List[hashtable]]::new() + +$psPaths | ForEach-Object -Parallel { + $queue = $using:manifests + $files = Get-ChildItem -Path $_ -Recurse -File -Include '*.dsc.resource.json', '*.dsc.resource.yaml', '*.dsc.resource.yml' -ErrorAction Ignore + foreach ($file in $files) { + $m = @{ manifestPath = $file.FullName } + $queue.Add($m) + } +} -ThrottleLimit 10 + +$manifests | ConvertTo-Json -Compress \ No newline at end of file From 16b41c4a6d8ac949692b36ef52e4f7c74746c1c5 Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Thu, 21 Aug 2025 14:40:57 +0200 Subject: [PATCH 15/20] Use concurrentbag --- extensions/powershell/powershell-discover.ps1 | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/extensions/powershell/powershell-discover.ps1 b/extensions/powershell/powershell-discover.ps1 index bfa56b08e..578cfd6b1 100644 --- a/extensions/powershell/powershell-discover.ps1 +++ b/extensions/powershell/powershell-discover.ps1 @@ -1,13 +1,15 @@ $psPaths = $env:PSModulePath -split [System.IO.Path]::PathSeparator | Where-Object { $_ -notmatch 'WindowsPowerShell' } -$manifests = [System.Collections.Generic.List[hashtable]]::new() + +$m = [System.Collections.Concurrent.ConcurrentBag[hashtable]]::new() $psPaths | ForEach-Object -Parallel { - $queue = $using:manifests - $files = Get-ChildItem -Path $_ -Recurse -File -Include '*.dsc.resource.json', '*.dsc.resource.yaml', '*.dsc.resource.yml' -ErrorAction Ignore + $queue = $using:m + $files = Get-ChildItem -Path $_ -Recurse -File -Filter '*.dsc.resource.*' -ErrorAction Ignore | + Where-Object -Property Extension -In @('.json', '.yaml', '.yml') + foreach ($file in $files) { - $m = @{ manifestPath = $file.FullName } - $queue.Add($m) + $queue.Add(@{ manifestPath = $file.FullName }) } } -ThrottleLimit 10 -$manifests | ConvertTo-Json -Compress \ No newline at end of file +@($m) | ConvertTo-Json -Compress \ No newline at end of file From 3037ffe9a54689e2139dfe32a186733570aa73c8 Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Thu, 21 Aug 2025 14:49:30 +0200 Subject: [PATCH 16/20] Use .NET --- extensions/powershell/powershell-discover.ps1 | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/extensions/powershell/powershell-discover.ps1 b/extensions/powershell/powershell-discover.ps1 index 578cfd6b1..b44f3cb5d 100644 --- a/extensions/powershell/powershell-discover.ps1 +++ b/extensions/powershell/powershell-discover.ps1 @@ -4,12 +4,14 @@ $m = [System.Collections.Concurrent.ConcurrentBag[hashtable]]::new() $psPaths | ForEach-Object -Parallel { $queue = $using:m - $files = Get-ChildItem -Path $_ -Recurse -File -Filter '*.dsc.resource.*' -ErrorAction Ignore | - Where-Object -Property Extension -In @('.json', '.yaml', '.yml') - - foreach ($file in $files) { - $queue.Add(@{ manifestPath = $file.FullName }) + $searchPatterns = @('*.dsc.resource.json', '*.dsc.resource.yaml', '*.dsc.resource.yml') + foreach ($pattern in $searchPatterns) { + try { + [System.IO.Directory]::EnumerateFiles($_, $pattern, 'AllDirectories') | ForEach-Object { + $queue.Add(@{ manifestPath = $_ }) + } + } catch { } } -} -ThrottleLimit 10 +} -ThrottleLimit 30 -@($m) | ConvertTo-Json -Compress \ No newline at end of file +[array]$m | ConvertTo-Json -Compress \ No newline at end of file From 1ef648234ca99d60d3b14a5a66d736ccb8ede617 Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Thu, 21 Aug 2025 15:26:38 +0200 Subject: [PATCH 17/20] Use .NET with enumeration option --- .vscode/launch.json | 78 +++++++++---------- extensions/powershell/powershell-discover.ps1 | 17 ---- 2 files changed, 39 insertions(+), 56 deletions(-) delete mode 100644 extensions/powershell/powershell-discover.ps1 diff --git a/.vscode/launch.json b/.vscode/launch.json index 00879d03f..c0fe66904 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,39 +1,39 @@ -// { -// // Use IntelliSense to learn about possible attributes. -// // Hover to view descriptions of existing attributes. -// // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -// "version": "0.2.0", -// "configurations": [ -// { -// "type": "lldb", -// "request": "launch", -// "name": "Debug config", -// "program": "${workspaceFolder}/config/target/debug/config", -// "args": [ -// "list", -// "r*" -// ], -// "cwd": "${workspaceFolder}" -// }, -// { -// "name": "(macOS) Attach", -// "type": "lldb", -// "request": "attach", -// "pid": "${command:pickMyProcess}", -// }, -// { -// "name": "(Windows) Attach", -// "type": "cppvsdbg", -// "request": "attach", -// "processId": "${command:pickProcess}", -// }, -// { -// "name": "Debug sshdconfig", -// "type": "cppvsdbg", -// "request": "launch", -// "program": "${workspaceFolder}/sshdconfig/target/debug/sshdconfig.exe", -// "args": ["get"], -// "cwd": "${workspaceFolder}" -// } -// ] -// } +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug config", + "program": "${workspaceFolder}/config/target/debug/config", + "args": [ + "list", + "r*" + ], + "cwd": "${workspaceFolder}" + }, + { + "name": "(macOS) Attach", + "type": "lldb", + "request": "attach", + "pid": "${command:pickMyProcess}", + }, + { + "name": "(Windows) Attach", + "type": "cppvsdbg", + "request": "attach", + "processId": "${command:pickProcess}", + }, + { + "name": "Debug sshdconfig", + "type": "cppvsdbg", + "request": "launch", + "program": "${workspaceFolder}/sshdconfig/target/debug/sshdconfig.exe", + "args": ["get"], + "cwd": "${workspaceFolder}" + } + ] +} diff --git a/extensions/powershell/powershell-discover.ps1 b/extensions/powershell/powershell-discover.ps1 deleted file mode 100644 index b44f3cb5d..000000000 --- a/extensions/powershell/powershell-discover.ps1 +++ /dev/null @@ -1,17 +0,0 @@ -$psPaths = $env:PSModulePath -split [System.IO.Path]::PathSeparator | Where-Object { $_ -notmatch 'WindowsPowerShell' } - -$m = [System.Collections.Concurrent.ConcurrentBag[hashtable]]::new() - -$psPaths | ForEach-Object -Parallel { - $queue = $using:m - $searchPatterns = @('*.dsc.resource.json', '*.dsc.resource.yaml', '*.dsc.resource.yml') - foreach ($pattern in $searchPatterns) { - try { - [System.IO.Directory]::EnumerateFiles($_, $pattern, 'AllDirectories') | ForEach-Object { - $queue.Add(@{ manifestPath = $_ }) - } - } catch { } - } -} -ThrottleLimit 30 - -[array]$m | ConvertTo-Json -Compress \ No newline at end of file From f15195a8f75b771d6f9522b832b296c086a5d8eb Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Wed, 27 Aug 2025 03:10:22 +0200 Subject: [PATCH 18/20] Remove undiscovered resource --- dsc/tests/dsc_extension_discover.tests.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/dsc/tests/dsc_extension_discover.tests.ps1 b/dsc/tests/dsc_extension_discover.tests.ps1 index 1ad519047..b854fc3a4 100644 --- a/dsc/tests/dsc_extension_discover.tests.ps1 +++ b/dsc/tests/dsc_extension_discover.tests.ps1 @@ -26,7 +26,6 @@ Describe 'Discover extension tests' { $expectedExtensions = if ($IsWindows) { @( @{ type = 'Microsoft.DSC.Extension/Bicep'; version = '0.1.0'; capabilities = @('import') } - @{ type = 'Microsoft.DSC.Transitional/PSDesiredStateConfiguration'; version = '0.1.0'; capabilities = @('import') } @{ type = 'Microsoft.Windows.Appx/Discover'; version = '0.1.0'; capabilities = @('discover') } @{ type = 'Microsoft.PowerShell/Discover'; version = '0.1.0'; capabilities = @('discover') } @{ type = 'Test/Discover'; version = '0.1.0'; capabilities = @('discover') } From a7263ba067eaf319ffc5533d3808cade4b2e8287 Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Wed, 3 Sep 2025 19:20:02 +0200 Subject: [PATCH 19/20] Fix point 2 --- extensions/powershell/powershell.discover.ps1 | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/extensions/powershell/powershell.discover.ps1 b/extensions/powershell/powershell.discover.ps1 index 43c4130d3..6f05b0b2f 100644 --- a/extensions/powershell/powershell.discover.ps1 +++ b/extensions/powershell/powershell.discover.ps1 @@ -1,18 +1,25 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. -$psPaths = $env:PSModulePath -split [System.IO.Path]::PathSeparator | Where-Object { $_ -notmatch 'WindowsPowerShell' } +[CmdletBinding()] +param () -$manifests = $psPaths | ForEach-Object -Parallel { - $searchPatterns = @('*.dsc.resource.json', '*.dsc.resource.yaml', '*.dsc.resource.yml') - $enumOptions = [System.IO.EnumerationOptions]@{ IgnoreInaccessible = $false; RecurseSubdirectories = $true } - foreach ($pattern in $searchPatterns) { - try { - [System.IO.Directory]::EnumerateFiles($_, $pattern, $enumOptions) | ForEach-Object { - @{ manifestPath = $_ } - } - } catch { } - } -} -ThrottleLimit 10 - -$manifests | ForEach-Object { $_ | ConvertTo-Json -Compress } \ No newline at end of file +begin { + $psPaths = $env:PSModulePath -split [System.IO.Path]::PathSeparator | Where-Object { $_ -notmatch 'WindowsPowerShell' } +} +process { + $manifests = $psPaths | ForEach-Object -Parallel { + $searchPatterns = @('*.dsc.resource.json', '*.dsc.resource.yaml', '*.dsc.resource.yml') + $enumOptions = [System.IO.EnumerationOptions]@{ IgnoreInaccessible = $false; RecurseSubdirectories = $true } + foreach ($pattern in $searchPatterns) { + try { + [System.IO.Directory]::EnumerateFiles($_, $pattern, $enumOptions) | ForEach-Object { + @{ manifestPath = $_ } + } + } catch { } + } + } -ThrottleLimit 10 +} +end { + $manifests | ForEach-Object { $_ | ConvertTo-Json -Compress } +} \ No newline at end of file From 640c664af1947ae25a50de1e5dd4dc3ae04efb2b Mon Sep 17 00:00:00 2001 From: "G.Reijn" Date: Thu, 4 Sep 2025 04:17:49 +0200 Subject: [PATCH 20/20] Add newline --- extensions/powershell/powershell.discover.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/powershell/powershell.discover.ps1 b/extensions/powershell/powershell.discover.ps1 index 6f05b0b2f..5ae2e32c5 100644 --- a/extensions/powershell/powershell.discover.ps1 +++ b/extensions/powershell/powershell.discover.ps1 @@ -22,4 +22,4 @@ process { } end { $manifests | ForEach-Object { $_ | ConvertTo-Json -Compress } -} \ No newline at end of file +}