Repository navigation
Open
Labels
Description
Prerequisites
- Write a descriptive title.
- Make sure you are able to repro it on the latest version
- Search the existing issues.
Summary
There is an option in the module manifest to set which capabilities are present for a resource however that applies to all resources in the module and not to individual resources.
DSC/powershell-adapter/psDscAdapter/powershell.resource.ps1
Lines 90 to 100 in 7ed105e
| # Provide a way for existing resources to specify their capabilities, or default to Get, Set, Test | |
| # TODO: for perf, it is better to take capabilities from psd1 in Invoke-DscCacheRefresh, not by extra call to Get-Module | |
| if ($DscResourceInfo.ModuleName) { | |
| $module = Get-Module -Name $DscResourceInfo.ModuleName -ListAvailable | Sort-Object -Property Version -Descending | Select-Object -First 1 | |
| if ($module.PrivateData.PSData.DscCapabilities) { | |
| $capabilities = $module.PrivateData.PSData.DscCapabilities | |
| } | |
| else { | |
| $capabilities = @('get', 'set', 'test') | |
| } | |
| } |
The schema should be updated to allow individual resources to specify their capabilities.
PSData = @{
DscCapabilities = @{
TestClassResource = @('get', test', 'export)
NoExport = @('get', test')
}
}
The ideal state is to allow class-based resources to not have to implement all methods. This could be done by checking the AST if the method contains a throw [NotImplementedException]::new() so that the code and capabilities match at all times.
Steps to reproduce
n/a
Expected behavior
n/aActual behavior
n/aError details
Environment data
n/aVersion
3.1-preview6
Visuals
No response
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsReviewed
Activity
[-]Class-based resource capabilities[/-][+]Class-based resource capabilities in module manifest[/+]michaeltlombardi commentedon May 30, 2025
I think it would be useful to consider an all-up re-approach to indicating metadata about DSC resources in module manifests. For example, something like:
Right now, we don't have a way to surface most of this information. In the future, with the resource development kit (RDK), we'll be able to surface more of this information easier - but I think it's probably still a good idea to define a model to shortcut the adapter needing to analyze resources in full, particularly for use cases like searching for resources or integrating into editors and other higher-order tools.
michaeltlombardi commentedon Sep 17, 2025
Thought about this a bit more, and I think what I would propose looks more like this:
Notes:
Microsoft.DSCkey instead ofDscResources.DscResourcesToExportkey or PSDSC. Resources may be PSDSC compatible, but that's handled by existing manifest structure.DscResourcesas the top-level key.gaelcolas commentedon Oct 15, 2025
I think that's a great way to expose the required metadata to the adapter, but is it the best?
If we put aside the adapter implementation for now, could DSC discover PowerShell class-based resources shipped within a module just by looking at a json (i.e. without even spinning up pwsh).
Maybe adding the complete metadata object in the module manifest is a bit too much, and would still require to read the psd1 (spin up pwsh).
Couldn't we have a convention that if there's a
ModuleName.Microsoft.DSC.json(by convention) along the module PSD1 or PSM1 it would just find it and read the resources capabilities & info?Then the right way to have the metadata would be in the class definition in the form of an attribute (and some could be derived/deduced from the class definition).
The RDK (or anyone) could create the attribute, and provide the tools used at compilation to generate the json.
Attribute would be in a third module that has to be Required/Nested for the parser.
Let's discuss, and we could discuss that during the community call tonight.
gaelcolas commentedon Oct 15, 2025
As discussed with Mikey, discovery needs to look into $Env:PSModulePath, not Path...
So it should still be done from the adapater.
SteveL-MSFT commentedon Oct 15, 2025
WG discussion is to have a new
.dsc.adaptedresource.json(or yaml) file which is the current DscResource schema (not the manifest) with the addition of a newschemaproperty that holds the JSONSchema. A newdiscoverextension would traverse$env:PSModulePathto look for these files and thediscoverextension would be enhanced to allow extensions to return a list of manifests or a list of these new adapted manifests.This will make discovery much faster than currently which needs to import the module or parse the module manifest. These resources will also just show up via
dsc resource listwithout specifying the adapter making discovery better in addition to being faster. The current engine logic will fallback to querying adapters if the resource isn't found so existing PS class based resources will still be found the "old way".ThomasNieto commentedon Oct 22, 2025
Is
.dsc.adaptedresource.jsoncreated at build time with the module author or is it generated at runtime with the adapter/discovery extension?Runtime built
.dsc.adaptedresource.jsonfiles in the module manifest has a few issues. The user has to have write access to$env:PSModulePathwhich works for user installed modules but not machine installed without escalation.Module shipped
.dsc.adaptedresource.jsonrequires an extra step from the module author and can lead to a mismatch between resource and schema.Adapter flow
flowchart TD A[Resource Lookup] B[Adapter] C[Adapter Cache] D{Resource Found?} F[Return Resource Metadata] H[Search $env:PSModulePath] I[Read Module Manifest] J[AST Parse Module] K[Return Resource Metadata] A --> B B --> C C --> D D -->|Yes| F D -->|No| H H --> I I --> J J --> K K --> FDiscovery with pre-built manifests
This method is required for resources and extensions using this model like PSResourceGet: PowerShell/PSResourceGet#1852
This method is already in scope in issue #913
flowchart TD A[Resource Lookup] B[Search $env:PSModulePath] C[Return Resource Manifest Paths] A --> B B --> CDiscovery with runtime built manifests (new adapter)
Proposed discovery extension without needing adapters.
flowchart TD A[Resource Lookup] B[Discovery Extension] C[Discovery Resource Cache] D{Resource Found?} F[Return Resource Manifests] H[Search $env:PSModulePath] I[Read Module Manifest] J[AST Parse Module] K[Build full manifest] A --> B B --> C C --> D D -->|Yes| F D -->|No| H H --> I I --> J J --> K K --> FExample manifest
Leveraging the newly added single manifest with multiple resources (#1187) we can accomplish the following.
{ "manifests": [ { "$schema": "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json", "type": "AnyPackageDsc/Package", "version": "0.1.0", "get": { "executable": "pwsh", "args": [ "-NoLogo", "-NonInteractive", "-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", "$Input | ./psDscAdapter/powershell.resource.ps1 Get" ], "input": "stdin" }, "set": { "executable": "pwsh", "args": [ "-NoLogo", "-NonInteractive", "-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", "$Input | ./psDscAdapter/powershell.resource.ps1 Set" ], "input": "stdin" }, "schema": { "embedded": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "name": { "type": "string" }, "version": { "type": "string" }, "latest": { "type": "boolean" } }, "required": [ "name", "version" ], "additionalProperties": false } } }, { "$schema": "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json", "type": "AnyPackageDsc/Source", "version": "0.1.0", "get": { "executable": "pwsh", "args": [ "-NoLogo", "-NonInteractive", "-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", "$Input | ./psDscAdapter/powershell.resource.ps1 Get" ], "input": "stdin" }, "set": { "executable": "pwsh", "args": [ "-NoLogo", "-NonInteractive", "-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", "$Input | ./psDscAdapter/powershell.resource.ps1 Set" ], "input": "stdin" }, "schema": { "embedded": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "name": { "type": "string" }, "location": { "type": "string" }, "trusted": { "type": "boolean" } }, "required": [ "name", "location" ], "additionalProperties": false } } } ] }What does using discovery get us over adapters?
If you have any questions or comments feel free to post and I'll answer them to the best of my ability.
This is quite a lot to describe over text, I plan on creating a proof of concept and can describe over the working group call.
ThomasNieto commentedon Oct 28, 2025
In the working group call last week it was mentioned that there would be a
requiredAdaptersproperty where the adapted resource declares which adapters are supported.The adapted resource should not assert which adapters are supported but rather the discovery/adapter system that should make that assertion. Here is an example of the implications, lets say for example someone forks the PowerShell adapter to either add new features or to use
pwsh-preview.exeIn that case if the resource author declares which adapters are supported forking of adapters or custom built adapters that support existing paradigms are not allowed.