WinGet and IaC – Take Winget to the next level

WinGet and IaC are maybe your next step to automate your environment. In the past, managing third-party applications on Windows meant 3rd party tools or gathering MSI installers on network shares, writing complex deployment wrappers, and battling silent installation switches that changed from vendor to vendor. I enjoyed that work a lot, but it is no longer a modern approach.

Microsoft’s WinGet package manager takes the package management concepts we’ve respected in Linux for decades and bakes them natively into the Windows ecosystem. But now with IaC it is time to say that WinGet has evolved massively. We are no longer just running basic install commands; we can deploy and standardize our Windows environments as code.

Get started with WinGet and IaC on Windows 11 and Windows Server 2025

WinGet is integrated into modern Windows OS versions via the App Installer package. However, there is an operational catch: the WinGet tool typically only registers and becomes available after the first interactive login of a Windows user.

If you are automating a server deployment and WinGet is not available immediately, do not waste time rebooting. You can forcefully register the package with the following command:

Add-AppxPackage -RegisterByFamilyName -MainPackage Microsoft.DesktopAppInstaller_8wekyb3d8bbwe

Search and Install Applications

With WinGet, installing and managing applications from the command line eliminates the need to hunt for vendor download pages. To see what is available, use the search command:

winget search sysinternals

Once you identify the official product ID (usually Microsoft.Sysinternals), use the following command for a clean, automated installation. To execute without interactive prompts, you must accept the source and package agreements directly:

winget install --id Microsoft.Sysinternals --exact --accept-source-agreements --accept-package-agreements --silent

Winget and Machine-Wide Install Scope

By default, many WinGet packages may attempt to install in the User Scope (under %LocalAppData%). On a Remote Desktop Session Host (RDS), Win11 multi-user system, or automated server, this is useless. You must explicitly define the scope to ensure the software is available to all users and resides in Program Files:

winget install --id Microsoft.Sysinternals --scope machine

Always use --scope machine for server automation to ensure consistent paths and availability across service accounts.

Important: Not all Winget Packages do support machine scope installation. Test carefully before deploying these.

Step 1 Winget and IaC – Export and Reproduce Environments

Before we use IaC level automatation lets move toward advanced automation and learn about the ability to clone an environment Winget Configuration.

Export a Snapshot:

winget export -o hartigade.json
Winget and IaC Export Yaml Example on hartiga.de
Winget and IaC Export Yaml

Import on New Target:

winget import -i hartigade.json --accept-source-agreements --accept-package-agreements

Important: : Use Export/Import for current status or call it snapshot replication. It’s a point-in-time copy of what is currently installed to another system

The IaC Standard: WinGet Configuration (DSC)

Today i focus on a new using WinGet Configuration. Microsoft has integrated PowerShell Desired State Configuration (DSC) v3 directly into WinGet. Instead of writing sequential install scripts, you declare the exact desired state in a YAML file. Check here for the official information from Microsoft.

To truly embrace the “Infrastructure as Code” (IaC) mindset, we need YAML config files. There are three primary ways to get your hands on a server-baseline.dsc.yaml file.

Recommend: Generate from an Existing Machine

If you have a “Gold Standard” server or a reference machine that is already configured exactly how you want it, you don’t need to write the YAML. You can let WinGet’s engine reverse-engineer the installed packages into a configuration file for you.

Run this command to capture the current state:

winget export -o server-baseline.dsc.yaml --include-versions

You will then need to wrap this exported list into the DSC properties header (the properties: and resources: tags) to make it a valid configuration file. Check in the next chapter on how that template should look like.

Perfect way: Write your template

If you are starting from a blank slate, you create the file in a text editor like VS Code. Here is the minimal, functional template you need to get started. Copy this into a file named hartiga-baseline.dsc.yaml

# yaml-language-server: $schema=https://aka.ms/configuration-dsc-schema/0.2
properties:
  configurationVersion: 0.2.0
  resources:
    - resource: Microsoft.WinGet.DSC/WinGetPackage
      directives:
        description: Install Sysinternals Suite
      settings:
        id: Microsoft.Sysinternals
        source: winget
        scope: machine # Ensure machine-wide install for servers

    - resource: Microsoft.WinGet.DSC/WinGetPackage
      directives:
        description: Install 7zip (Pinned Version)
      settings:
        id: 7zip.7zip
        version: 24.08
        source: winget

Existing examples: Microsoft’s Configuration Gallery

For complex setups (like setting up a developer machine or a specific SQL server role), Microsoft and the community maintain a library of ready-to-use configurations.

You can find these on the Microsoft Dev Home repositories or by searching for “WinGet Configuration” on GitHub. Instead of reinventing the wheel, you download a .dsc.yaml from a trusted source and modify it to fit your organizational baselines, i.e. you can try https://github.com/dmealo/devboot to start with.

Understanding your WinGet and IaC Lifecycle

Step 1. Authoring: You create or edit the .dsc.yaml file.

Step 2. Testing (Validation):

You run

winget configure test -f .\hartiga-baseline.dsc.yaml

to see if the server matches your requirements.

Step 3. Enforcement:

You run

winget configure -f .\hartiga-baseline.dsc.yaml

to apply the changes.

By using this approach, you move away from “one-off” installs and toward a state where your servers are standardized, can easily auto update itself and is self-documenting.

Important: Use Configure (DSC) for state enforcement. It ensures the machine stays in the desired state over time.

WinGet Configuration (DSC) – Version Pinning

For controlled enterprise environments, “latest” isn’t always “greatest.” You need to pin versions to ensure compatibility and stability. In your DSC configuration, you can specify the exact version required:

# yaml-language-server: $schema=https://aka.ms/configuration-dsc-schema/0.2
properties:
  configurationVersion: 0.2.0
  resources:
    - resource: Microsoft.WinGet.DSC/WinGetPackage
      settings:
        id: "Microsoft.Sysinternals"
        version: "2024.9.0" # Version Pinning for Stability
        source: winget

WinGet Configuration (DSC) – Drift Detection

One of the most valuable features of the modern WinGet stack is the ability to test compliance without making changes. This is essential for CI/CD pipelines and auditing:

winget configure test -f .\hartiga-baseline.dsc.yaml

This command allows you to detect configuration drift. If a technician manually uninstalled a tool or changed a version, this test will flag the machine as non-compliant, allowing you to remediate proactively.

Forcing Auto-Updates for the Windows Store

WinGet is updated via the Microsoft Store. On servers where the Store GUI is never opened, the App Installer package can become severely outdated, breaking your automation.

While you can target specific task names, names can vary across Windows builds. A safer, enterprise-grade approach to trigger these updates via PowerShell is to filter for the task dynamically:

Get-ScheduledTask -TaskPath "\Microsoft\Windows\WindowsUpdate\" | Where-Object {$_.TaskName -like "*App*"} | Start-ScheduledTask

When encountering issues or as a preperation you can risk this to guarantee that your WinGet and IaC environment remains fully capable of securing and configuring your Windows systems.

Conclusion on WinGet and IaC

Winget started as a replacement for 3rd party installer and update tools like patchmypc. Over the time it has evolved into a tool that is ready for Enterprise deployments using IaC and CI/CD pipelines. Start testing that functionality today. I am sure you will identify more than one use case to simplify your daily work.

To get started with Winget I highly recommend reading my original story here or check here with Thomas Maurer here or with Sarah Lean here.

If you have any questions please don’t hesitate to reach out to me on LinkedIn, Bluesky or check my newly created Adaptive Cloud community on Reddit.

LinkedIn: https://www.linkedin.com/in/andreas-hartig/
Bluesky: https://bsky.app/profile/hartiga.de
Adaptive Cloud community on Reddit: https://www.reddit.com/r/AdaptiveCloud/

Additional Resources

“Using the PowerShell WinGet module” by Harm Veenstra for an advanced insight into the PowerShell Winget module

Microsoft Learn on WinGet Configuration

Windows Dev Home (Out of Support but still a good place to start searching for Dev machines)

Find your Winget Packages here on Winget Run.

Spread the knowledge
Avatar for Andreas Hartig
Andreas Hartig - MVP - Cloud and Datacenter Management, Microsoft Azure

Related Posts

Gemini Generated Image 3pcu7n3pcu7n3pcu

Azure Bastion Developer SKU: Secure Access Without the “Bastion Tax”

In the past, securing your Azure Virtual Machines (VMs) often felt like a trade-off between security and budget. If you wanted to avoid the risks of exposing RDP or SSH … Read more

Spread the knowledge
Read more
How to Uninstall AzureArcSetup 2026

How to Uninstall Azure Arc from Windows Server 2026

Why do we need to Uninstall Azure Arc or Azure Arc Setup? Windows Server 2025 ships with the Azure Arc Setup feature baked in. You’ll notice a new tray icon … Read more

Spread the knowledge
Read more
IT Network Dragon and show the Unifi Gateway Config and the Azure Portal on a Dual Screen

VPN Ubiquiti UniFi UDM to Azure (2026 Edition)

Update: This guide replaces my original article located here with this VPN Ubiquiti UniFi UDM to Azure (2026 Edition). In the past, we relied on the Basic VPN Gateway and … Read more

Spread the knowledge
Read more
Dragon IT Operations logfile tailing using Klogg

Tail for log files with Windows – 2026 Edition

I view a lot of log files—probably more than I’d like to admit. Whether it’s troubleshooting a hybrid infrastructure issue or debugging a cloud deployment, I always look for the … Read more

Spread the knowledge
Read more
IT Operations Dragon happy about QoL on Servers

Automation using Group Policy – Quality of Life GPO

Quality of Life GPOs. Finally. My favorite settings. In our previous articles, we established the Group Policies Foundation and discussed the Background of Automation. We also implemented some important GPOs. … Read more

Spread the knowledge
Read more
dragon it security happy world time clock

Automation using Group Policy – Configure Time Zone using GPOs

Setting the time zone on a server was often a manual step during the “Out of Box Experience” (OOBE). Let’s Configure Time Zone using GPOs as it might be something … Read more

Spread the knowledge
Read more