Skip to main content

DSC Integration

WinGet integrates with PowerShell Desired State Configuration (DSC) to enable configuration as code scenarios. This allows you to define your development environment, applications, and settings in declarative configuration files.

Overview

WinGet configuration enables:
  • Declarative setup - Define desired system state in YAML files
  • Reproducible environments - Share and recreate development environments
  • Automated provisioning - Apply configurations programmatically
  • State management - Test, get, and set system configuration
WinGet configuration is built on the Microsoft.Management.Configuration API and supports both DSC v2 (PowerShell-based) and DSC v3 (PowerShell-free) resources.

Configuration Files

Configuration files are YAML documents that describe the desired state of your system.

Basic Structure (DSC v2)

properties:
  configurationVersion: 0.2
  resources:
    - resource: Microsoft.WinGet.DSC/WinGetPackage
      directives:
        description: Install Git
        allowPrerelease: true
      settings:
        Id: Git.Git
        Source: winget

DSC v3 Structure

$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
  winget:
    processor: dscv3
resources:
  - name: Install Git
    type: Microsoft.WinGet.DSC/WinGetPackage
    properties:
      Id: Git.Git
      Source: winget
      Ensure: Present

Configuration Schema

Properties Section

properties.configurationVersion
string
required
Configuration syntax version (e.g., “0.2”).
properties.resources
array
List of resources to configure.
properties.assertions
array
Preconditions required to run the configuration.
properties.parameters
array
Resources that retrieve information via ‘get’ operation.

Resource Definition

Each resource in the configuration defines a unit of desired state:
resource
string
required
Name of the resource (e.g., “Microsoft.WinGet.DSC/WinGetPackage”).
id
string
Unique identifier for this resource instance.
dependsOn
array
List of resource IDs this resource depends on.
directives
object
Metadata about the module and resource.
settings
object
Configuration parameters for the resource.

WinGet DSC Resources

WinGet provides several DSC resources for package and source management.

WinGetPackage

Manage package installation state.
resources:
  - resource: Microsoft.WinGet.DSC/WinGetPackage
    id: installVSCode
    directives:
      description: Install Visual Studio Code
      securityContext: elevated
    settings:
      Id: Microsoft.VisualStudioCode
      Source: winget
      Ensure: Present
      UseLatest: true
Settings:
Id
string
required
Package identifier from the source.
Source
string
Source name providing the package (e.g., “winget”, “msstore”).
Version
string
Specific package version to install.
Ensure
string
default:"Present"
Whether package should be installed (Present) or not (Absent).
UseLatest
boolean
default:"false"
Update to latest version (overrides Version).
MatchOption
string
default:"EqualsCaseInsensitive"
How to match the package Id: Equals, EqualsCaseInsensitive, StartsWithCaseInsensitive, ContainsCaseInsensitive.
InstallMode
string
default:"Silent"
Installation interactivity: Default, Silent, Interactive.

WinGetSource

Configure WinGet package sources.
resources:
  - resource: Microsoft.WinGet.DSC/WinGetSource
    id: addCorpSource
    settings:
      Name: Corporate
      Argument: https://packages.corp.example.com
      Type: Microsoft.PreIndexed.Package
      Ensure: Present
      TrustLevel: Trusted
Settings:
Name
string
required
Source name.
Argument
string
required
Source URI or identifier.
Type
string
Source type: Microsoft.PreIndexed.Package, Microsoft.Rest.
TrustLevel
string
default:"None"
Trust level: Undefined, None, Trusted.
Explicit
boolean
default:"false"
Whether source is excluded from default searches (true) or included (false).
Ensure
string
default:"Present"
Whether source should exist (Present) or not (Absent).

WinGetPackageManager

Ensure WinGet itself is at a specific version.
resources:
  - resource: Microsoft.WinGet.DSC/WinGetPackageManager
    settings:
      SID: ""
      UseLatest: true
Settings:
SID
string
required
User SID (currently only empty string "" is supported for current user).
Version
string
Specific WinGet version to install.
UseLatest
boolean
default:"false"
Install latest stable release.
UseLatestPreRelease
boolean
default:"false"
Install latest preview release.

WinGetUserSettings / WinGetAdminSettings

Manage WinGet settings files.
resources:
  - resource: Microsoft.WinGet.DSC/WinGetUserSettings
    settings:
      Settings:
        visual:
          progressBar: rainbow
        experimentalFeatures:
          directMSI: true

PowerShell Configuration Module

Use WinGet configuration from PowerShell.

Installation

The configuration module is included with WinGet (version 1.4+):
# Verify module is available
Get-Module -ListAvailable Microsoft.WinGet.Configuration

# Import module
Import-Module Microsoft.WinGet.Configuration

Available Cmdlets

Load a configuration file.
Get-WinGetConfiguration -File .\myconfig.yaml
Parameters:
  • -File <string> - Path to configuration YAML file
Returns: PSConfigurationSet object
Get detailed information about configuration resources.
$config = Get-WinGetConfiguration -File .\myconfig.yaml
Get-WinGetConfigurationDetails -Set $config
Parameters:
  • -Set <PSConfigurationSet> - Configuration set to inspect
Returns: Detailed resource information
Apply a configuration synchronously.
$config = Get-WinGetConfiguration -File .\myconfig.yaml
Invoke-WinGetConfiguration -Set $config -AcceptConfigurationAgreements
Parameters:
  • -Set <PSConfigurationSet> - Configuration to apply
  • -AcceptConfigurationAgreements - Accept all agreements automatically
Returns: Configuration result
Apply a configuration asynchronously.
$config = Get-WinGetConfiguration -File .\myconfig.yaml
$job = Start-WinGetConfiguration -Set $config -AcceptConfigurationAgreements
Parameters:
  • -Set <PSConfigurationSet> - Configuration to apply
  • -AcceptConfigurationAgreements - Accept all agreements
Returns: PSConfigurationJob for async operation
Wait for an asynchronous configuration to complete.
$job = Start-WinGetConfiguration -Set $config
Complete-WinGetConfiguration -ConfigurationJob $job
Parameters:
  • -ConfigurationJob <PSConfigurationJob> - Job to wait for
Returns: Configuration result

Configuration Examples

Development Environment Setup

properties:
  configurationVersion: 0.2
  assertions:
    - resource: Microsoft.WinGet.DSC/WinGetPackageManager
      directives:
        description: Ensure WinGet is up to date
      settings:
        SID: ""
        UseLatest: true
  
  resources:
    # Install development tools
    - resource: Microsoft.WinGet.DSC/WinGetPackage
      id: git
      directives:
        description: Install Git
        securityContext: elevated
      settings:
        Id: Git.Git
        Source: winget
        Ensure: Present
    
    - resource: Microsoft.WinGet.DSC/WinGetPackage
      id: vscode
      dependsOn:
        - git
      directives:
        description: Install VS Code
      settings:
        Id: Microsoft.VisualStudioCode
        Source: winget
        UseLatest: true
    
    - resource: Microsoft.WinGet.DSC/WinGetPackage
      id: nodejs
      directives:
        description: Install Node.js LTS
      settings:
        Id: OpenJS.NodeJS.LTS
        Source: winget
    
    # Configure WinGet settings
    - resource: Microsoft.WinGet.DSC/WinGetUserSettings
      id: configureWinGet
      directives:
        description: Configure WinGet preferences
      settings:
        Settings:
          visual:
            progressBar: rainbow
          installBehavior:
            preferences:
              scope: user
          experimentalFeatures:
            directMSI: true

Corporate Environment Configuration

properties:
  configurationVersion: 0.2
  resources:
    # Add corporate source
    - resource: Microsoft.WinGet.DSC/WinGetSource
      id: corpSource
      directives:
        description: Add corporate package source
      settings:
        Name: Corporate
        Argument: https://packages.corp.example.com
        Type: Microsoft.PreIndexed.Package
        TrustLevel: Trusted
        Ensure: Present
    
    # Install required corporate apps
    - resource: Microsoft.WinGet.DSC/WinGetPackage
      id: corpVPN
      dependsOn:
        - corpSource
      settings:
        Id: Corp.VPNClient
        Source: Corporate
        Ensure: Present
    
    - resource: Microsoft.WinGet.DSC/WinGetPackage
      id: corpChat
      dependsOn:
        - corpSource
      settings:
        Id: Corp.ChatClient
        Source: Corporate
        Ensure: Present

Multi-Language Development Setup

properties:
  configurationVersion: 0.2
  parameters:
    - resource: Environment/GetEnvironmentVariable
      id: userProfile
      settings:
        Name: USERPROFILE
  
  resources:
    # Python development
    - resource: Microsoft.WinGet.DSC/WinGetPackage
      id: python
      settings:
        Id: Python.Python.3.12
        Source: winget
    
    # Node.js development
    - resource: Microsoft.WinGet.DSC/WinGetPackage
      id: node
      settings:
        Id: OpenJS.NodeJS.LTS
        Source: winget
    
    # .NET development
    - resource: Microsoft.WinGet.DSC/WinGetPackage
      id: dotnet
      settings:
        Id: Microsoft.DotNet.SDK.8
        Source: winget
    
    # Shared tools
    - resource: Microsoft.WinGet.DSC/WinGetPackage
      id: git
      settings:
        Id: Git.Git
        Source: winget

Configuration Directives

Directives provide metadata and control how resources are processed.
directives.module
string
PowerShell module name containing the resource.
directives.description
string
Human-readable description of what the resource does.
directives.allowPrerelease
boolean
default:"false"
Allow prerelease versions of PowerShell modules.
directives.securityContext
string
default:"current"
Security context for execution: current, restricted, elevated.
directives:
  description: Install Visual Studio with admin rights
  securityContext: elevated
  allowPrerelease: false

Dependency Management

Use dependsOn to control resource application order:
resources:
  - resource: Microsoft.WinGet.DSC/WinGetPackage
    id: git
    settings:
      Id: Git.Git
  
  - resource: Microsoft.WinGet.DSC/WinGetPackage
    id: githubDesktop
    dependsOn:
      - git
    settings:
      Id: GitHub.GitHubDesktop
Avoid circular dependencies. WinGet will detect and reject configurations with dependency cycles.

Configuration Variables

Use variables to make configurations dynamic:
properties:
  configurationVersion: 0.2
  resources:
    - resource: Microsoft.WinGet.DSC/WinGetPackage
      settings:
        Id: Git.Git
        # Use WinGetConfigRoot variable
        InstallLocation: ${WinGetConfigRoot}\Git
Available variables:
  • ${WinGetConfigRoot} - Root directory of the configuration file
  • Environment variables (e.g., ${USERPROFILE}, ${TEMP})

Testing Configurations

Test configuration without applying:
# Load configuration
$config = Get-WinGetConfiguration -File .\myconfig.yaml

# Get details without applying
Get-WinGetConfigurationDetails -Set $config

# Test what would happen
# (Future: Test-WinGetConfiguration cmdlet)

Configuration History

WinGet tracks applied configurations:
# View configuration history
winget configure list

# Show specific configuration details
winget configure show --id {configuration-id}

Troubleshooting

  1. Validate YAML syntax
  2. Check configurationVersion is specified
  3. Verify resource names are correct
  4. Ensure schema reference is valid (for DSC v3)
  1. Verify PowerShell module is installed
  2. Check module name in directives.module
  3. Set allowPrerelease: true if using prerelease modules
  4. Ensure WinGet version supports the resource
  1. Check for circular dependencies
  2. Verify all referenced IDs exist
  3. Ensure dependency order is logical
  4. Test dependencies individually
  1. Add securityContext: elevated to directives
  2. Run PowerShell as administrator
  3. Check if package requires elevation
  4. Verify user has necessary permissions

Best Practices

  1. Use version control - Store configuration files in Git
  2. Add descriptions - Document each resource’s purpose
  3. Handle dependencies - Explicitly define resource dependencies
  4. Test incrementally - Test resources individually before combining
  5. Use assertions - Validate preconditions before applying
  6. Security context - Only elevate when necessary
  7. Modularize - Split large configurations into smaller files
  8. Version packages - Pin critical packages to specific versions

See Also

Build docs developers (and LLMs) love