Skip to content

DSC v3 resource for PSResourceGet - #1852

Merged
Aditya Patwardhan (adityapatwardhan) merged 66 commits into
masterfrom
DscResource
Apr 29, 2026
Merged

DSC v3 resource for PSResourceGet#1852
Aditya Patwardhan (adityapatwardhan) merged 66 commits into
masterfrom
DscResource

Conversation

@adityapatwardhan

Copy link
Copy Markdown
Member

PR Summary

The initial implementation of DSC v3 resource for PSResourceGet. It include two resources, Repository and PSResources.

PR Context

PR Checklist

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Quick review pass on the manifests, looking at resource implementation next.

Comment thread src/dsc/repository.dsc.resource.json Outdated
Comment thread src/dsc/repository.dsc.resource.json Outdated
Comment thread src/dsc/repository.dsc.resource.json
Comment thread src/dsc/psresources.dsc.resource.json Outdated
Comment thread src/dsc/psresources.dsc.resource.json Outdated
Comment thread src/dsc/psresources.dsc.resource.json Outdated
Comment thread src/dsc/repository.dsc.resource.json
Comment thread src/dsc/psresourceget.ps1 Outdated
Comment thread src/dsc/psresourceget.ps1 Outdated
Comment thread src/dsc/psresourceget.ps1 Outdated
Comment thread src/dsc/psresourceget.ps1 Outdated
Comment thread src/dsc/psresources.dsc.resource.json Outdated
Comment thread src/dsc/psresourceget.ps1 Outdated
Comment thread src/dsc/psresourceget.ps1 Outdated
Comment thread src/dsc/psresourceget.ps1 Outdated
Comment thread src/dsc/psresources.dsc.resource.json Outdated

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

A few more comments on the schema and implementation.

Comment thread src/dsc/psresourceget.ps1
Comment thread src/dsc/psresourceget.ps1 Outdated
Comment thread src/dsc/psresourceget.ps1 Outdated
Comment thread src/dsc/psresources.dsc.resource.json Outdated
Comment thread src/dsc/psresources.dsc.resource.json Outdated
Comment thread src/dsc/psresources.dsc.resource.json Outdated
Comment thread src/dsc/psresources.dsc.resource.json Outdated
Comment thread src/dsc/psresources.dsc.resource.json Outdated
Comment thread src/dsc/psresources.dsc.resource.json Outdated
Comment thread src/dsc/psresources.dsc.resource.json Outdated
@ThomasNieto

Copy link
Copy Markdown
Contributor

Is the plan to add a discover extension in DSC to be able to find these resource manifests? If so, is there an issue/pr for that?

Comment thread src/dsc/psresources.dsc.resource.json Outdated
Comment thread src/dsc/repository.dsc.resource.json
@michaeltlombardi

Copy link
Copy Markdown

Is the plan to add a discover extension in DSC to be able to find these resource manifests? If so, is there an issue/pr for that?

Thomas Nieto (@ThomasNieto) yup! PowerShell/DSC#913 proposes a discovery extension for finding resource and extension manifests through the PSModulePath.

@ThomasNieto

Copy link
Copy Markdown
Contributor

I logged PowerShell/DSC#1024 issue. PSResourceGet will also have the same issue since it uses NuGet version range syntax containing square brackets.

@Gijsreyn

Copy link
Copy Markdown

Aditya Patwardhan (@adityapatwardhan) - I think you've followed the news, but you should be able to define a single resource manifest now e.g.,:

// psresourceget.dsc.manifests.json
{
  "resources": [
    {
      "$schema": "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json",
      "description": "Manage PowerShell resources using PSResourceGet.",
      "tags": [
        "linux",
        "windows",
        "macos",
        "powershell",
        "nuget"
      ],
      "type": "Microsoft.PowerShell.PSResourceGet/PSResourceList",
      "version": "0.0.1",
      "get": {
        "executable": "pwsh",
        "args": [
          "-NoLogo",
          "-NonInteractive",
          "-NoProfile",
          "-ExecutionPolicy",
          "Bypass",
          "-Command",
          "$Input | ./psresourceget.ps1 -resourcetype 'psresourcelist' -operation 'get'"
        ],
        "input": "stdin"
      },
      "set": {
        "executable": "pwsh",
        "args": [
          "-NoLogo",
          "-NonInteractive",
          "-NoProfile",
          "-ExecutionPolicy",
          "Bypass",
          "-Command",
          "$Input | ./psresourceget.ps1 -resourcetype 'psresourcelist' -operation set"
        ],
        "input": "stdin",
        "return": "stateAndDiff"
      },
      "export": {
        "executable": "pwsh",
        "args": [
          "-NoLogo",
          "-NonInteractive",
          "-NoProfile",
          "-ExecutionPolicy",
          "Bypass",
          "-Command",
          "./psresourceget.ps1 -resourcetype 'psresourcelist' -operation export"
        ],
        "input": "stdin"
      },
      "test": {
        "executable": "pwsh",
        "args": [
          "-NoLogo",
          "-NonInteractive",
          "-NoProfile",
          "-ExecutionPolicy",
          "Bypass",
          "-Command",
          "$Input | ./psresourceget.ps1 -resourcetype 'psresourcelist' -operation test"
        ],
        "input": "stdin",
        "return": "stateAndDiff"
      },
      "schema": {
        "embedded": {
          "$schema": "https://json-schema.org/draft/2020-12/schema",
          "title": "PSResourceList",
          "type": "object",
          "additionalProperties": false,
          "required": [
            "repositoryName"
          ],
          "properties": {
            "repositoryName": {
              "title": "Repository Name",
              "description": "The name of the repository from where the resources are acquired.",
              "type": "string"
            },
            "resources": {
              "title": "Resources",
              "description": "The list of resources to manage.",
              "type": "array",
              "items": {
                "$ref": "#/$defs/PSResource"
              },
              "minItems": 0
            },
            "_exist": {
              "$ref": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/v3/resource/properties/exist.json"
            },
            "_inDesiredState": {
              "$ref": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/v3/resource/properties/inDesiredState.json"
            }
          },
          "$defs": {
            "Scope": {
              "type": "string",
              "title": "Scope",
              "description": "Scope of the resource installation.",
              "enum": [
                "CurrentUser",
                "AllUsers"
              ]
            },
            "PSResource": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "name"
              ],
              "properties": {
                "name": {
                  "title": "Name",
                  "description": "The name of the resource.",
                  "type": "string"
                },
                "version": {
                  "title": "Version",
                  "description": "The version range of the resource.",
                  "type": "string",
                  "pattern": "^(\\[|\\()\\s*\\d+(\\.\\d+){0,2}(-[0-9A-Za-z-.]+)?\\s*(,\\s*(\\d+(\\.\\d+){0,2}(-[0-9A-Za-z-.]+)?)?\\s*(\\]|\\)))?$"
                },
                "scope": {
                  "title": "Scope",
                  "description": "The scope of the resource. Can be 'CurrentUser' or 'AllUsers'.",
                  "$ref": "#/$defs/Scope"
                },
                "repositoryName": {
                  "title": "Repository Name",
                  "description": "The name of the repository from where the resource is acquired.",
                  "type": "string"
                },
                "preRelease": {
                  "title": "Pre-Release version",
                  "description": "Indicates whether to include pre-release versions of the resource.",
                  "type": "boolean",
                  "default": false
                },
                "_exist": {
                  "$ref": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/v3/resource/properties/exist.json"
                },
                "_inDesiredState": {
                  "$ref": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/v3/resource/properties/inDesiredState.json"
                }
              }
            },
            "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/v3/resource/properties/exist.json": {
              "$schema": "https://json-schema.org/draft/2020-12/schema",
              "$id": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/v3/resource/properties/exist.json",
              "title": "Instance should exist",
              "description": "Indicates whether the DSC resource instance should exist.",
              "type": "boolean",
              "default": true,
              "enum": [
                false,
                true
              ]
            },
            "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/v3/resource/properties/inDesiredState.json": {
              "$schema": "https://json-schema.org/draft/2020-12/schema",
              "$id": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/v3/resource/properties/inDesiredState.json",
              "title": "Instance is in desired state",
              "description": "Indicates whether the DSC resource instance is in the desired state.",
              "type": "boolean",
              "default": true,
              "enum": [
                false,
                true
              ]
            }
          }
        }
      }
    },
    {
      "$schema": "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json",
      "description": "Manage PowerShell repositories using PSResourceGet.",
      "tags": [
        "linux",
        "windows",
        "macos",
        "powershell",
        "nuget"
      ],
      "type": "Microsoft.PowerShell.PSResourceGet/Repository",
      "version": "0.0.1",
      "get": {
        "executable": "pwsh",
        "args": [
          "-NoLogo",
          "-NonInteractive",
          "-NoProfile",
          "-ExecutionPolicy",
          "Bypass",
          "-Command",
          "$Input | ./psresourceget.ps1 -resourcetype 'repository' -operation 'get'"
        ],
        "input": "stdin"
      },
      "set": {
        "executable": "pwsh",
        "args": [
          "-NoLogo",
          "-NonInteractive",
          "-NoProfile",
          "-ExecutionPolicy",
          "Bypass",
          "-Command",
          "$Input | ./psresourceget.ps1 -resourcetype 'repository' -operation set"
        ],
        "input": "stdin"
      },
      "delete": {
        "executable": "pwsh",
        "args": [
          "-NoLogo",
          "-NonInteractive",
          "-NoProfile",
          "-ExecutionPolicy",
          "Bypass",
          "-Command",
          "$Input | ./psresourceget.ps1 -resourcetype 'repository' -operation delete"
        ],
        "input": "stdin"
      },
      "export": {
        "executable": "pwsh",
        "args": [
          "-NoLogo",
          "-NonInteractive",
          "-NoProfile",
          "-ExecutionPolicy",
          "Bypass",
          "-Command",
          "./psresourceget.ps1 -resourcetype 'repository' -operation export"
        ],
        "input": "stdin"
      },
      "schema": {
        "embedded": {
          "$schema": "https://json-schema.org/draft/2020-12/schema",
          "title": "Repository",
          "description": "A PowerShell Resource repository from where to acquire the resources.",
          "type": "object",
          "additionalProperties": false,
          "allOf": [
            {
              "if": {
                "properties": {
                  "_exist": {
                    "const": false
                  }
                }
              },
              "then": {
                "required": [
                  "name"
                ]
              },
              "else": {
                "required": [
                  "name",
                  "uri"
                ]
              }
            }
          ],
          "properties": {
            "name": {
              "title": "Name",
              "description": "The name of the repository.",
              "type": "string"
            },
            "uri": {
              "title": "URI",
              "description": "The URI of the repository.",
              "type": "string",
              "format": "uri"
            },
            "trusted": {
              "title": "Trusted",
              "description": "Indicates whether the repository is trusted.",
              "type": "boolean"
            },
            "priority": {
              "title": "Priority",
              "description": "The priority of the repository. Lower numbers indicate higher priority.",
              "type": "integer",
              "minimum": 0,
              "maximum": 100
            },
            "repositoryType": {
              "title": "Repository Type",
              "description": "The type of the repository.",
              "$ref": "#/$defs/RepositoryType"
            },
            "_exist": {
              "$ref": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/v3/resource/properties/exist.json"
            }
          },
          "$defs": {
            "RepositoryType": {
              "type": "string",
              "title": "Repository Type",
              "description": "The type of the repository. Can be 'Unknown', 'V2', 'V3', 'Local', 'NugetServer', or 'ContainerRegistry'.",
              "enum": [
                "Unknown",
                "V2",
                "V3",
                "Local",
                "NugetServer",
                "ContainerRegistry"
              ]
            },
            "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/v3/resource/properties/exist.json": {
              "$schema": "https://json-schema.org/draft/2020-12/schema",
              "$id": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/v3/resource/properties/exist.json",
              "title": "Instance should exist",
              "description": "Indicates whether the DSC resource instance should exist.",
              "type": "boolean",
              "default": true,
              "enum": [
                false,
                true
              ]
            }
          }
        }
      }
    }
  ]
}

@Gijsreyn

Gijs Reijn (Gijsreyn) commented Nov 8, 2025

Copy link
Copy Markdown

I think the pattern for version should also slightly change to:

"pattern": "^((\\[|\\()[ \\t]*(>=|>|<=|<)?[ \\t]*\\d+(\\.\\d+){0,2}(-[0-9A-Za-z-.]+)?[ \\t]*(,[ \\t]*(>=|>|<=|<)?[ \\t]*(\\d+(\\.\\d+){0,2}(-[0-9A-Za-z-.]+)?)?[ \\t]*)?(\\]|\\))|\\d+(\\.\\d+){0,2}(-[0-9A-Za-z-.]+)?)$"

@adityapatwardhan

Copy link
Copy Markdown
Member Author

Gijs Reijn (@Gijsreyn) - thanks for your comments. I would still maybe want to keep it separate files for two resources. Easier to understand. What do others think?

Also, I removed the pattern validation for the NuGet version ranges. It can get really unwieldy and difficult to maintain.

@adityapatwardhan

Copy link
Copy Markdown
Member Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@adityapatwardhan
Aditya Patwardhan (adityapatwardhan) marked this pull request as ready for review March 2, 2026 17:54
@adityapatwardhan Aditya Patwardhan (adityapatwardhan) changed the title WIP: DSC v3 resource for PSResourceGet DSC v3 resource for PSResourceGet Mar 2, 2026
@adityapatwardhan

Copy link
Copy Markdown
Member Author

Close / Re-Open to re-kick off pipelines.

@adityapatwardhan
Aditya Patwardhan (adityapatwardhan) merged commit ff881f4 into master Apr 29, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants