Windows System

Winget Teil 17 – Winget in DevOps und CI/CD: GitHub Actions, Azure DevOps, Build-Server und automatisierte Bereitstellung

Winget ist nicht nur ein praktischer Paketmanager für Windows, sondern auch ein vielseitiges Werkzeug für DevOps und CI/CD. Dieser Artikel zeigt, wie sich Entwicklungsumgebungen, Build-Server und Windows-Images automatisiert vorbereiten lassen. Wir erklären die Integration in GitHub Actions und Azure DevOps, den Einsatz auf Self-hosted Runnern sowie die Möglichkeiten von Winget Configure. Außerdem betrachten wir Windows-Container, PowerShell-Automatisierung, Sicherheit und Best Practices für reproduzierbare Build-Prozesse.

17 min Lesezeit
Winget in DevOps und CI/CD: Automatisierte Softwarebereitstellung mit GitHub, Azure DevOps und Windows-Images.

Die moderne Softwareentwicklung lebt von Automatisierung. Anwendungen werden nicht mehr ausschließlich manuell entwickelt, getestet und veröffentlicht. Stattdessen übernehmen automatisierte Prozesse immer mehr Aufgaben: Quellcode wird kompiliert, Abhängigkeiten werden installiert, Tests ausgeführt und fertige Anwendungen bereitgestellt.

Hier kommen DevOps und Continuous Integration beziehungsweise Continuous Delivery (CI/CD) ins Spiel.

Mit Winget steht unter Windows ein Paketmanager zur Verfügung, der sich auch in solche Prozesse integrieren lässt. Entwickler können damit benötigte Werkzeuge installieren, Build-Server vorbereiten und Entwicklungsumgebungen standardisieren.

Besonders interessant ist die Kombination mit GitHub Actions, Azure DevOps und PowerShell. Dadurch lassen sich Softwareinstallationen in automatisierte Workflows einbinden und wiederkehrende Einrichtungsarbeiten reduzieren.

Allerdings bringt der Einsatz von Winget in CI/CD-Umgebungen einige Besonderheiten mit sich. Nicht jeder Build-Agent verfügt über Winget, nicht jeder Installer unterstützt unbeaufsichtigte Installationen und nicht jeder Container eignet sich für die Ausführung klassischer Windows-Anwendungen.

In diesem siebzehnten Teil unserer Winget-Serie zeigen wir, wie sich der Windows Package Manager in moderne DevOps-Prozesse integrieren lässt. Wir betrachten GitHub Actions, Azure DevOps, Build-Server, Windows-Container, Entwicklerarbeitsplätze und die Erstellung standardisierter Windows-Images.

1. Welche Rolle spielt Winget in DevOps?

DevOps verfolgt das Ziel, Softwareentwicklung und IT-Betrieb enger miteinander zu verbinden.

Ein wichtiger Bestandteil ist die Automatisierung wiederkehrender Aufgaben.

Dazu gehören insbesondere die Einrichtung von Entwicklungsumgebungen, die Bereitstellung von Build-Werkzeugen und die Ausführung automatisierter Tests.

Winget kann diese Aufgaben unterstützen, indem benötigte Windows-Anwendungen über eindeutige Paketkennungen installiert werden.

Ein einfaches Beispiel:

winget install --id Git.Git --exact


Damit lässt sich Git auf einem Windows-System installieren.

Weitere Entwicklungswerkzeuge können auf ähnliche Weise bereitgestellt werden:

winget install --id Microsoft.VisualStudioCode --exact
winget install --id Python.Python.3.13 --exact
winget install --id Microsoft.PowerShell --exact

Die konkrete Verfügbarkeit einzelner Paketversionen sollte vor der Verwendung geprüft werden.

Warum ist das für DevOps interessant?

In klassischen Entwicklungsumgebungen werden benötigte Werkzeuge häufig manuell installiert.

Dadurch entstehen Unterschiede zwischen einzelnen Rechnern.

Ein Entwickler verwendet möglicherweise eine andere Python-Version als ein Kollege. Ein Build-Server besitzt eine ältere Git-Version, während auf einem Testsystem bereits eine neuere Version installiert ist.

Solche Unterschiede können zu schwer nachvollziehbaren Fehlern führen.

Mit Winget lassen sich Installationsvorgänge standardisieren.

Wichtig: Winget ermöglicht reproduzierbare Installationsabläufe. Eine vollständig reproduzierbare Entwicklungsumgebung erfordert zusätzlich festgelegte Versionen, kontrollierte Installationsquellen und eine geeignete Verwaltung der übrigen Abhängigkeiten.

2. CI/CD-Pipelines verstehen

Eine CI/CD-Pipeline besteht aus mehreren automatisierten Verarbeitungsschritten.

Typischerweise beginnt sie mit einer Änderung am Quellcode.

Anschließend wird die Anwendung kompiliert, getestet und gegebenenfalls veröffentlicht.

Beispiel einer CI/CD-Pipeline mit Winget

  • Quellcode
  • GitHub oder Azure Repos
  • Build-Agent vorbereiten
  • Winget installiert benötigte Werkzeuge
  • Build
  • Anwendung kompilieren
  • Automatisierte Tests
  • Funktion und Qualität überprüfen
  • Artefakte
  • Ergebnisse versioniert bereitstellen
  • Deployment
  • Freigegebene Version veröffentlichen

Winget wird dabei hauptsächlich für die Vorbereitung der Ausführungsumgebung verwendet.

Es installiert beispielsweise Compiler, Kommandozeilenwerkzeuge oder andere benötigte Anwendungen.

Die eigentliche Steuerung der Pipeline übernimmt weiterhin die CI/CD-Plattform.

3. Winget mit GitHub Actions verwenden

GitHub Actions ermöglicht die Automatisierung von Entwicklungs- und Veröffentlichungsprozessen direkt innerhalb eines GitHub-Repositorys.

Workflows werden als YAML-Dateien definiert.

Diese Dateien befinden sich üblicherweise im Verzeichnis:

.github/workflows/


Ein Workflow kann beispielsweise bei jedem Push oder Pull Request ausgeführt werden.

Windows-Runner verwenden

GitHub Actions bietet Windows-basierte Runner an.

Ein einfacher Workflow sieht folgendermaßen aus:

name: Windows Build

on:
  push:
  workflow_dispatch:

jobs:
  build:
    runs-on: windows-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: PowerShell prüfen
        shell: pwsh
        run: |
          $PSVersionTable.PSVersion

Dieser Workflow verwendet einen Windows-Runner und führt einen einfachen PowerShell-Befehl aus.

Winget-Verfügbarkeit prüfen

Bevor Winget verwendet wird, sollte überprüft werden, ob es im Runner verfügbar ist.

- name: Winget prüfen
  shell: pwsh
  run: |
    $winget = Get-Command winget -ErrorAction SilentlyContinue

    if (-not $winget) {
        throw "Winget ist auf diesem Runner nicht verfügbar."
    }

    winget --version

Diese Prüfung ist wichtig, weil die Ausstattung von Runner-Images Änderungen unterliegt.

Außerdem kann Winget zwar auf dem System vorhanden sein, aber im aktuellen Ausführungskontext nicht ordnungsgemäß funktionieren.

Warum GitHub-hosted Runner problematisch sein können

GitHub-hosted Runner sind kurzlebige virtuelle Maschinen.

Nach Abschluss eines Jobs wird die jeweilige Umgebung verworfen.

Zusätzlich ist Winget von der Windows-App-Installer-Infrastruktur abhängig.

Bei nicht interaktiven Dienstkontexten kann dies zu Einschränkungen führen.

Deshalb sollte Winget auf GitHub-hosted Runnern nicht ungeprüft als garantiert verfügbarer Installationsmechanismus vorausgesetzt werden.

Für stabile Produktionspipelines sind bereits vorbereitete Runner-Images oder dedizierte Self-hosted Runner häufig besser geeignet.

4. GitHub Actions mit einem Self-hosted Runner

Für Winget-basierte Build-Prozesse sind selbst verwaltete Windows-Runner besonders interessant.

Ein Self-hosted Runner ist ein Windows-Rechner oder eine virtuelle Maschine, auf dem die GitHub-Actions-Runner-Software installiert ist.

Die Organisation kontrolliert dabei selbst, welche Anwendungen vorhanden sind und wie die Umgebung konfiguriert wird.

Vorteile

Ein Self-hosted Runner kann dauerhaft mit den benötigten Werkzeugen ausgestattet werden.

Dadurch müssen Compiler, SDKs und andere größere Anwendungen nicht bei jedem Pipeline-Durchlauf neu installiert werden.

Außerdem lassen sich interne Paketquellen und Netzwerkressourcen einbinden.

Beispiel eines Workflows

Das folgende Beispiel setzt einen vorbereiteten Windows-Runner voraus, auf dem Winget im Runner-Kontext getestet wurde.

name: Winget Build Pipeline

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  build:
    runs-on: [self-hosted, Windows, X64]

    steps:
      - name: Repository herunterladen
        uses: actions/checkout@v4

      - name: Winget prüfen
        shell: pwsh
        run: |
          $winget = Get-Command winget -ErrorAction Stop
          & $winget.Source --version

      - name: Git bereitstellen
        shell: pwsh
        run: |
          winget install `
            --id Git.Git `
            --exact `
            --source winget `
            --silent `
            --disable-interactivity `
            --accept-package-agreements `
            --accept-source-agreements

          if ($LASTEXITCODE -ne 0) {
              throw "Winget-Installation fehlgeschlagen."
          }

      - name: Build starten
        shell: pwsh
        run: |
          Write-Host "Starte Buildprozess..."
          # Hier den projektspezifischen Buildbefehl ausführen

Der letzte Schritt ist bewusst ein Platzhalter. Erst ein echter Buildbefehl macht daraus eine vollständige Build-Pipeline.

Wichtige Einschränkung

Ein Runner-Dienst kann unter einem anderen Benutzerkonto laufen als eine interaktive Administratorsitzung.

Deshalb sollte Winget bereits bei der Einrichtung des Runners im tatsächlichen Dienstkontext geprüft werden.

Ein weiterer wichtiger Punkt: Self-hosted Runner sind nicht automatisch isoliert. Bei nicht vertrauenswürdigem Quellcode, insbesondere aus externen Pull Requests, können erhebliche Sicherheitsrisiken entstehen.

Für solche Szenarien sollten kurzlebige, isolierte Runner verwendet werden.

5. Winget in Azure DevOps integrieren

Neben GitHub Actions gehört Azure DevOps zu den verbreiteten Plattformen für automatisierte Softwareentwicklung.

Azure Pipelines ermöglicht die Definition von Build- und Deploymentprozessen über YAML-Dateien.

Auch hier kann Winget zur Vorbereitung der Windows-Umgebung verwendet werden.

Microsoft-hosted und Self-hosted Agents

Azure DevOps unterscheidet zwischen verschiedenen Agenttypen.

Microsoft-hosted Agents werden von Microsoft bereitgestellt und verwaltet. Sie eignen sich besonders für standardisierte Builds, bei denen die vorhandenen Werkzeuge ausreichen.

Self-hosted Agents werden auf eigenen Servern oder virtuellen Maschinen betrieben.

Diese bieten mehr Kontrolle über die installierte Software, die Netzwerkverbindungen und den Ausführungskontext.

Microsoft weist ausdrücklich darauf hin, dass Self-hosted Agents besonders für Umgebungen geeignet sind, in denen zusätzliche Softwareabhängigkeiten selbst verwaltet werden müssen.

Microsoft Learn+1

Beispiel einer Azure-Pipeline

Die folgende Pipeline verwendet einen vorbereiteten Self-hosted Windows-Agent im Pool Windows-Build.

trigger:
  - main

pool:
  name: Windows-Build

steps:
  - checkout: self

  - task: PowerShell@2
    displayName: "Winget prüfen"
    inputs:
      targetType: inline
      pwsh: true
      script: |
        $winget = Get-Command winget -ErrorAction Stop
        & $winget.Source --version

  - task: PowerShell@2
    displayName: "Entwicklungswerkzeuge installieren"
    inputs:
      targetType: inline
      pwsh: true
      script: |
        winget install `
          --id Git.Git `
          --exact `
          --source winget `
          --silent `
          --disable-interactivity `
          --accept-package-agreements `
          --accept-source-agreements

        if ($LASTEXITCODE -ne 0) {
            throw "Installation fehlgeschlagen."
        }

  - task: PowerShell@2
    displayName: "Build ausführen"
    inputs:
      targetType: inline
      pwsh: true
      script: |
        Write-Host "Buildumgebung vorbereitet."
        # Projektspezifischen Buildbefehl ergänzen

Was passiert in der Pipeline?

Zunächst wird der Quellcode aus dem Repository ausgecheckt.

Danach überprüft PowerShell die Verfügbarkeit von Winget.

Im nächsten Schritt wird Git als Beispiel für ein Entwicklungswerkzeug bereitgestellt.

Anschließend kann der eigentliche Buildprozess beginnen.

Microsoft-hosted Agents

Auf Microsoft-hosted Agents sollte zunächst geprüft werden, ob das benötigte Werkzeug bereits installiert ist.

Microsoft stellt für seine Agent-Images umfangreiche Softwarelisten bereit.

Häufig sind Git, Visual Studio, verschiedene SDKs und weitere Entwicklungswerkzeuge bereits vorhanden.

Eine erneute Installation über Winget wäre in solchen Fällen unnötig.

Außerdem werden Microsoft-hosted Agents nach Abschluss eines Jobs verworfen. Änderungen an der Umgebung sind somit nicht dauerhaft.

Microsoft Learn

6. Build-Server mit Winget vorbereiten

Ein Build-Server ist ein System, das automatisiert Anwendungen kompiliert, testet oder Installationspakete erzeugt.

Solche Systeme benötigen häufig zahlreiche Werkzeuge.

Dazu gehören Compiler, SDKs, Versionsverwaltungssysteme, Paketmanager und Testprogramme.

Winget kann bei der Erstkonfiguration eines Windows-Build-Servers helfen.

Beispiel einer Werkzeugliste

$Packages = @(
    "Git.Git",
    "Microsoft.PowerShell",
    "Microsoft.VisualStudioCode",
    "7zip.7zip"
)

foreach ($Package in $Packages) {

    winget install `
        --id $Package `
        --exact `
        --source winget `
        --silent `
        --disable-interactivity `
        --accept-package-agreements `
        --accept-source-agreements

    if ($LASTEXITCODE -ne 0) {
        throw "Installation fehlgeschlagen: $Package"
    }
}

Das Skript eignet sich als Ausgangspunkt für die Einrichtung einer Build-Umgebung.

Allerdings sollte ein produktiver Build-Server nicht bei jedem Pipeline-Durchlauf sämtliche Werkzeuge neu installieren.

Warum feste Werkzeugversionen wichtig sind

Ein Build muss möglichst reproduzierbar sein.

Wenn heute eine andere Compiler- oder SDK-Version verwendet wird als gestern, können unterschiedliche Ergebnisse entstehen.

Deshalb empfiehlt es sich, für wichtige Build-Werkzeuge feste Versionen vorzugeben.

Winget unterstützt dafür den Parameter --version.

Beispielsweise:

winget install `
    --id Git.Git `
    --exact `
    --version "<FREIGEGEBENE_VERSION>"

Der Platzhalter muss durch eine tatsächlich verfügbare und getestete Version ersetzt werden.

Eine bestimmte Version lässt sich nur installieren, wenn die entsprechende Paketdefinition und der Installer verfügbar sind.

Build-Server nicht unkontrolliert aktualisieren

Der Befehl

winget upgrade --all


ist für produktive Build-Server in der Regel keine geeignete Standardstrategie.

Unkontrollierte Aktualisierungen können die Reproduzierbarkeit von Builds beeinträchtigen.

Besser ist ein geregelter Prozess, bei dem neue Werkzeugversionen zunächst getestet und anschließend freigegeben werden.

7. Windows-Container und Winget

Container spielen in DevOps-Umgebungen eine wichtige Rolle.

Sie ermöglichen die Bereitstellung standardisierter Laufzeitumgebungen.

Allerdings muss zwischen Linux-Containern und Windows-Containern unterschieden werden.

Winget ist ein Werkzeug für Windows.

In gewöhnlichen Linux-Containern kann Winget daher nicht als nativer Linux-Paketmanager verwendet werden.

Windows-Container

Windows-Container basieren auf Windows-Container-Images, beispielsweise Windows Server Core oder Nano Server.

Diese Umgebungen unterscheiden sich von einer vollständigen Windows-Desktopinstallation.

Insbesondere stehen nicht sämtliche Windows-Komponenten und AppX-/MSIX-Funktionen zur Verfügung.

Das ist für Winget relevant, weil der Paketmanager eng mit der App-Installer-Infrastruktur verbunden ist.

Warum Winget in Windows-Containern problematisch ist

Klassische Windows-Container besitzen normalerweise keine vollständige Desktopumgebung.

Auch die Paketregistrierung und verschiedene Installationsmechanismen unterscheiden sich von einem normalen Windows-Arbeitsplatz.

Deshalb sollte nicht davon ausgegangen werden, dass sich Winget innerhalb eines Windows-Containers einfach installieren und verwenden lässt.

Für viele Container-Szenarien ist der direkte Einbau der benötigten Anwendung in das Container-Image die zuverlässigere Lösung.

Beispiel eines Windows-Dockerfiles

FROM mcr.microsoft.com/windows/servercore:ltsc2022

SHELL ["powershell", "-NoProfile", "-Command"]

COPY tools/ C:/tools/

RUN Write-Host 'Werkzeuge wurden in das Image kopiert.'

WORKDIR C:/app

COPY app/ C:/app/

Dieses Beispiel setzt voraus, dass die benötigten Dateien in den lokalen Verzeichnissen tools und app vorhanden sind.

Es zeigt bewusst keine Winget-Installation im Container.

Die verwendete Windows-Container-Basis muss zur Hostumgebung und zur gewählten Isolationsart passen.

Empfehlung

Winget eignet sich in erster Linie zur Vorbereitung vollständiger Windows-Systeme und geeigneter Build-Hosts.

Für Container sollten bevorzugt die nativen Mechanismen des jeweiligen Container-Ökosystems verwendet werden.

8. Entwicklerrechner automatisch einrichten

Ein besonders interessantes Einsatzgebiet für Winget ist die standardisierte Einrichtung von Entwicklerarbeitsplätzen.

Gerade beim Einstieg neuer Mitarbeiter oder beim Austausch von Hardware müssen häufig zahlreiche Anwendungen installiert werden.

Ohne Automatisierung kann diese Einrichtung viel Zeit beanspruchen.

Mit Winget lässt sich ein großer Teil davon standardisieren.

Beispiel: Entwicklerarbeitsplatz vorbereiten

Ein einfaches PowerShell-Skript könnte folgendermaßen aussehen:

$Packages = @(
    "Git.Git",
    "Microsoft.VisualStudioCode",
    "Microsoft.PowerShell",
    "Python.Python.3.13",
    "7zip.7zip"
)

foreach ($Package in $Packages) {

    Write-Host "Installiere $Package"

    winget install `
        --id $Package `
        --exact `
        --source winget `
        --silent `
        --disable-interactivity `
        --accept-package-agreements `
        --accept-source-agreements

    if ($LASTEXITCODE -ne 0) {
        Write-Warning "Fehler bei $Package"
    }
}

Das Skript installiert die definierten Anwendungen nacheinander.

Für den produktiven Einsatz sollten die Paketkennungen und Versionen geprüft und freigegeben werden.

Unterschiedliche Entwicklerprofile

Nicht jeder Entwickler benötigt dieselben Werkzeuge.

Ein Webentwickler arbeitet möglicherweise mit Node.js, Git und Visual Studio Code.

Ein .NET-Entwickler benötigt dagegen häufig Visual Studio und passende .NET-SDKs.

Für Python-Projekte können wiederum Python, Git und zusätzliche Entwicklungswerkzeuge erforderlich sein.

Es empfiehlt sich daher, unterschiedliche Entwicklungsprofile zu definieren.

Diese können beispielsweise als JSON-Dateien oder Winget-Konfigurationsdateien verwaltet werden.

9. Winget Configure für reproduzierbare Entwicklungsumgebungen

Für komplexere Entwicklungsumgebungen bietet Microsoft mit Winget Configure einen besonders interessanten Ansatz.

Winget Configure verwendet deklarative Konfigurationsdateien, um den gewünschten Zustand eines Windows-Systems zu beschreiben.

Dabei geht es nicht nur um die Installation einzelner Programme.

Auch weitere Systemeinstellungen können über geeignete Konfigurationsressourcen berücksichtigt werden.

Unterschied zwischen Skripten und deklarativer Konfiguration

Ein klassisches PowerShell-Skript beschreibt normalerweise einzelne Aktionen.

Beispielsweise:

winget install --id Git.Git --exact


Eine deklarative Konfiguration beschreibt dagegen den gewünschten Systemzustand.

Das Konfigurationssystem versucht anschließend, diesen Zustand herzustellen.

Winget Configure verwendet dafür PowerShell Desired State Configuration (DSC) und passende Ressourcen.

Konfiguration ausführen

Angenommen, eine geprüfte Konfigurationsdatei liegt unter folgendem Pfad:

C:\DevSetup\configuration.winget


Dann kann sie folgendermaßen ausgeführt werden:

winget configure --file "C:\DevSetup\configuration.winget"


Vorher empfiehlt sich eine Validierung:

winget configure validate `
    --file "C:\DevSetup\configuration.winget"

Auch eine Prüfung des aktuellen Systemzustands ist möglich:

winget configure test `
    --file "C:\DevSetup\configuration.winget"

Die genaue Unterstützung einzelner Konfigurationsressourcen hängt von den installierten Modulen und der verwendeten Winget-Version ab.

Vorteile für Entwicklerteams

Mit Winget Configure können Entwicklungsumgebungen als versionierte Konfigurationsdateien gepflegt werden.

Dadurch lassen sich neue Arbeitsplätze schneller einrichten.

Auch Änderungen an der Entwicklungsumgebung können nachvollziehbar dokumentiert werden.

Microsoft empfiehlt Winget Configure ausdrücklich für die Einrichtung reproduzierbarer Entwicklungsumgebungen.

Microsoft for Developers+1

10. Winget Export und Import in Entwicklungsprojekten

Für einfachere Anwendungsfälle können Softwarelisten exportiert und später importiert werden.

Softwareliste exportieren

winget export `
    --output "C:\DevSetup\packages.json"

Softwareliste importieren

winget import `
    --import-file "C:\DevSetup\packages.json" `
    --accept-package-agreements `
    --accept-source-agreements

Das ist beispielsweise hilfreich, wenn mehrere Entwickler eine ähnliche Grundausstattung benötigen.

Grenzen

Der Export enthält keine vollständige Beschreibung sämtlicher Systemeinstellungen.

Auch Benutzerprofile, Erweiterungen und projektbezogene Abhängigkeiten werden nicht automatisch vollständig erfasst.

Für komplexere Entwicklungsumgebungen ist Winget Configure daher häufig besser geeignet.

Der Import verarbeitet die enthaltenen Paketdefinitionen nacheinander.

Microsoft Learn

11. Windows-Images mit Winget vorbereiten

Neben einzelnen Entwicklerrechnern können auch vollständige Windows-Images automatisiert vorbereitet werden.

Solche Images werden beispielsweise für virtuelle Maschinen, Testumgebungen oder standardisierte Arbeitsplatzbereitstellungen verwendet.

Winget kann dabei helfen, die benötigte Software auf einem vorbereiteten Windows-System zu installieren.

Typischer Ablauf

Zunächst wird eine Windows-Referenz-VM erstellt.

Danach werden Betriebssystemupdates installiert und die benötigten Komponenten eingerichtet.

Anschließend erfolgt die Installation freigegebener Anwendungen.

Nach erfolgreichen Tests kann die VM als Grundlage für weitere Bereitstellungen dienen.

Beispiel: Software auf einer Referenz-VM installieren

$Packages = @(
    "Git.Git",
    "7zip.7zip",
    "Microsoft.PowerShell"
)

foreach ($Package in $Packages) {

    winget install `
        --id $Package `
        --exact `
        --source winget `
        --silent `
        --disable-interactivity `
        --accept-package-agreements `
        --accept-source-agreements

    if ($LASTEXITCODE -ne 0) {
        throw "Fehler bei $Package"
    }
}

Nach der Installation müssen die Anwendungen überprüft werden.

Für die Bereitstellung klassischer Windows-Images sind außerdem die jeweiligen Microsoft-Vorgaben zur Generalisierung und Bereitstellung zu beachten.

Golden Images

Ein sogenanntes Golden Image ist eine vorbereitete Systemvorlage.

Diese enthält bereits definierte Betriebssystemeinstellungen und gegebenenfalls Standardsoftware.

Der Vorteil besteht darin, dass neue virtuelle Maschinen nicht vollständig von Grund auf eingerichtet werden müssen.

Allerdings können solche Images schnell veralten.

Deshalb sollten sie regelmäßig neu erstellt und getestet werden.

Wichtig: Winget ersetzt keine Imaging- oder Provisioning-Lösung. Es übernimmt lediglich einen Teil der Softwarebereitstellung.

12. Winget mit Packer und Image-Build-Prozessen kombinieren

HashiCorp Packer ist ein Werkzeug zur automatisierten Erstellung von Maschinen-Images.

Damit lassen sich beispielsweise virtuelle Maschinen vorbereiten und als wiederverwendbare Images bereitstellen.

Winget kann in einen solchen Prozess integriert werden, wenn das Windows-Gastsystem die Voraussetzungen erfüllt.

Grundidee

Packer erstellt zunächst eine virtuelle Maschine.

Anschließend wird Windows konfiguriert.

Danach führt Packer Provisioning-Skripte aus.

Ein solches Skript könnte Winget verwenden, um benötigte Anwendungen zu installieren.

Beispiel eines Provisioning-Skripts

$ErrorActionPreference = "Stop"

$Winget = Get-Command winget -ErrorAction SilentlyContinue

if (-not $Winget) {
    throw "Winget ist nicht verfügbar."
}

& $Winget.Source install `
    --id 7zip.7zip `
    --exact `
    --source winget `
    --silent `
    --disable-interactivity `
    --accept-package-agreements `
    --accept-source-agreements

if ($LASTEXITCODE -ne 0) {
    throw "7-Zip konnte nicht installiert werden."
}

Das Skript kann durch einen geeigneten PowerShell-Provisioner ausgeführt werden.

Einschränkungen

Auch hier ist der Benutzerkontext entscheidend.

Packer-Provisioning erfolgt häufig in nicht interaktiven Sitzungen.

Deshalb muss geprüft werden, ob Winget dort ordnungsgemäß verfügbar ist.

Für Anwendungen, die in diesem Kontext nicht zuverlässig über Winget installiert werden können, sollten alternative Installationsverfahren verwendet werden.

13. Fehlerbehandlung in CI/CD-Pipelines

In automatisierten Build-Prozessen muss jeder Fehler zuverlässig erkannt werden.

Ein Installationsfehler darf nicht dazu führen, dass eine Pipeline anschließend mit einer unvollständigen Umgebung weiterarbeitet.

PowerShell bietet dafür eine Kombination aus strukturierter Fehlerbehandlung und der Auswertung externer Rückgabecodes.

Beispiel einer wiederverwendbaren Funktion

function Install-WingetPackage {
    param(
        [Parameter(Mandatory)]
        [string]$PackageId,

        [string]$Version
    )

    $Arguments = @(
        "install",
        "--id", $PackageId,
        "--exact",
        "--source", "winget",
        "--silent",
        "--disable-interactivity",
        "--accept-package-agreements",
        "--accept-source-agreements"
    )

    if ($Version) {
        $Arguments += @("--version", $Version)
    }

    Write-Host "Installiere: $PackageId"

    & winget @Arguments

    $ExitCode = $LASTEXITCODE

    if ($ExitCode -ne 0) {
        throw "Winget-Fehler bei ${PackageId}: $ExitCode"
    }

    Write-Host "Winget-Befehl erfolgreich: $PackageId"
}

Die Funktion lässt sich anschließend verwenden:

Install-WingetPackage -PackageId "7zip.7zip"


Oder mit einer festgelegten Version:

Install-WingetPackage `
    -PackageId "Git.Git" `
    -Version "<FREIGEGEBENE_VERSION>"

Die Versionsangabe ist durch eine tatsächlich verfügbare Version zu ersetzen.

Warum ist das wichtig?

Wird innerhalb einer Pipeline eine Ausnahme ausgelöst, kann der betreffende Schritt als fehlgeschlagen markiert werden.

Dadurch wird verhindert, dass nachfolgende Build- oder Deploymentprozesse trotz eines erkannten Installationsfehlers unkontrolliert weiterlaufen.

Für besonders anspruchsvolle Pipelines sollte zusätzlich geprüft werden, ob die Anwendung tatsächlich in der erwarteten Version vorhanden ist.

14. Logging und Reporting in DevOps-Prozessen

Eine professionelle CI/CD-Pipeline sollte nachvollziehbar dokumentieren, welche Software während eines Builds verwendet wurde.

Das betrifft insbesondere Compiler, SDKs und weitere Entwicklungswerkzeuge.

Winget-Version protokollieren

winget --version


Installierte Anwendungen anzeigen

winget list


Winget-Diagnoseinformationen ausgeben

winget --info


Ergebnisse in einer Datei speichern

$ReportDirectory = "C:\BuildReports"

New-Item `
    -ItemType Directory `
    -Path $ReportDirectory `
    -Force | Out-Null

$ReportFile = Join-Path $ReportDirectory "winget-report.txt"

winget --info | Out-File $ReportFile -Encoding UTF8

winget list | Out-File `
    $ReportFile `
    -Append `
    -Encoding UTF8

Damit entsteht eine einfache Dokumentation der verwendeten Winget-Umgebung.

Für automatisierte Auswertungen sollten allerdings strukturierte Daten bevorzugt werden.

Die reine Textausgabe von winget list eignet sich nur eingeschränkt als maschinenlesbares Inventar, weil sich Formatierung und Spalten je nach Version und Sprache unterscheiden können.

Reports als Pipeline-Artefakte

GitHub Actions und Azure DevOps ermöglichen es, Dateien als Pipeline-Artefakte bereitzustellen.

Dadurch können Installationsprotokolle und Reports nach Abschluss eines Builds heruntergeladen und ausgewertet werden.

Ein GitHub-Actions-Schritt könnte beispielsweise folgendermaßen aussehen:

- name: Buildberichte veröffentlichen
  if: always()
  uses: actions/upload-artifact@v4
  with:
    name: winget-build-report
    path: C:\BuildReports\
    if-no-files-found: warn

Der Schritt setzt voraus, dass das Verzeichnis auf dem Windows-Runner existiert und die entsprechenden Berichte zuvor erstellt wurden.

In sicherheitskritischen Umgebungen sollten Logs vor der Veröffentlichung auf vertrauliche Informationen überprüft werden.

15. Sicherheit in automatisierten Build-Umgebungen

Die automatisierte Installation von Software stellt besondere Anforderungen an die Sicherheit.

Ein Build-Agent verarbeitet häufig Quellcode und besitzt möglicherweise Zugriff auf interne Repositorys, Zertifikate oder andere geschützte Ressourcen.

Wird ein solcher Agent kompromittiert, können weitreichende Folgen entstehen.

Vertrauenswürdige Paketquellen

Winget sollte in professionellen Pipelines ausschließlich auf kontrollierte Quellen zugreifen.

Ein Installationsbefehl kann die Quelle ausdrücklich festlegen:

winget install `
    --id Git.Git `
    --exact `
    --source winget

Die offizielle Community-Paketquelle ist allerdings nicht mit einer organisationsinternen Softwarefreigabe gleichzusetzen.

Softwareversionen festlegen

Für reproduzierbare Builds sollten wichtige Werkzeugversionen ausdrücklich definiert werden.

Unkontrollierte Aktualisierungen können dazu führen, dass Builds zu unterschiedlichen Zeitpunkten verschiedene Ergebnisse liefern.

Digitale Signaturen

Nach Möglichkeit sollten signierte Installer verwendet werden.

Zusätzlich können Hashwerte und Herstellerinformationen überprüft werden.

Berechtigungen minimieren

Build-Agenten sollten nur die Berechtigungen besitzen, die sie tatsächlich benötigen.

Administrative Rechte sollten nicht pauschal für sämtliche Pipeline-Schritte vergeben werden.

Geheimnisse schützen

API-Schlüssel, Zugangsdaten und Zertifikate dürfen nicht ungeschützt in Skripten oder Repositorys hinterlegt werden.

Dafür sollten die Secret-Management-Funktionen der jeweiligen CI/CD-Plattform verwendet werden.

Self-hosted Runner absichern

Selbst verwaltete Runner benötigen regelmäßige Sicherheitsupdates, kontrollierte Netzwerkzugriffe und eine geeignete Trennung zwischen vertrauenswürdigen und nicht vertrauenswürdigen Workloads.

Besonders bei öffentlich zugänglichen Repositorys sollte die Ausführung fremder Pull-Request-Inhalte auf dauerhaft betriebenen internen Runnern vermieden werden.

16. Winget in Unternehmen und Behörden

Für Unternehmen und öffentliche Verwaltungen kann Winget ein nützlicher Bestandteil standardisierter Entwicklungs- und Bereitstellungsprozesse sein.

Insbesondere bei eigenen Fachanwendungen oder internen Softwareprojekten ist eine nachvollziehbare Build-Umgebung wichtig.

Eine mögliche Architektur könnte aus einem zentralen Git-Repository, einer CI/CD-Plattform, mehreren Windows-Build-Agenten und einer kontrollierten Softwarebereitstellung bestehen.

Beispiel eines internen Entwicklungsprozesses

Ein Entwickler überträgt eine Änderung in das zentrale Repository.

Die CI/CD-Plattform startet daraufhin einen automatisierten Build.

Ein vorbereiteter Windows-Agent stellt die erforderlichen Entwicklungswerkzeuge bereit.

Anschließend wird die Anwendung kompiliert und getestet.

Nach erfolgreicher Prüfung wird das fertige Installationspaket als Artefakt gespeichert.

Die Bereitstellung erfolgt erst nach den vorgesehenen Freigaben.

Vorteile

Ein solcher Prozess verbessert die Nachvollziehbarkeit und reduziert manuelle Arbeitsschritte.

Auch die Wiederherstellung von Entwicklungs- und Build-Umgebungen wird vereinfacht.

Für Organisationen mit erhöhten Sicherheitsanforderungen können dokumentierte Build-Prozesse zudem wichtige Nachweise für interne Kontrollen liefern.

Allerdings ersetzt Winget weder eine vollständige DevSecOps-Plattform noch ein Software-Supply-Chain-Sicherheitskonzept.

17. Best Practices für Winget in DevOps und CI/CD

Für einen zuverlässigen Betrieb empfehlen sich folgende Grundsätze:

  1. Winget-Verfügbarkeit vorab prüfen. Nicht jeder Runner oder Build-Agent unterstützt Winget in seinem Ausführungskontext.
  2. Self-hosted Runner kontrolliert vorbereiten. Wiederkehrende Werkzeuginstallationen sollten möglichst bereits beim Aufbau der Umgebung erfolgen.
  3. Softwareversionen festlegen. Kritische Build-Werkzeuge sollten nicht ungeprüft aktualisiert werden.
  4. Paketquellen ausdrücklich angeben. Dadurch wird die Paketauflösung nachvollziehbarer.
  5. Rückgabecodes auswerten. Fehlgeschlagene Installationen müssen die Pipeline zuverlässig stoppen können.
  6. Installationszustände überprüfen. Ein erfolgreicher Befehl allein ist kein vollständiger Nachweis.
  7. Container und vollständige Windows-Systeme unterscheiden. Winget ist kein universeller Paketmanager für Windows-Container.
  8. Build-Images versionieren. Änderungen an der Build-Umgebung müssen nachvollziehbar bleiben.
  9. Logs und Reports archivieren. Die verwendeten Werkzeuge und Versionen sollten dokumentiert werden.
  10. Sicherheitsanforderungen integrieren. Berechtigungen, Softwareherkunft und der Schutz von Zugangsdaten gehören zum Build-Prozess.

18. Winget als Baustein automatisierter Windows-Entwicklungsumgebungen

Winget bietet interessante Möglichkeiten für den Einsatz in modernen DevOps- und CI/CD-Prozessen.

Besonders bei der Vorbereitung von Windows-Entwicklungsrechnern, Build-Servern und virtuellen Maschinen kann der Paketmanager zahlreiche manuelle Arbeitsschritte ersetzen.

In Verbindung mit PowerShell lassen sich Installationen automatisieren, Fehler auswerten und Ergebnisse dokumentieren.

GitHub Actions und Azure DevOps ermöglichen es, solche Prozesse in umfassendere Build- und Deploymentpipelines einzubinden.

Mit Winget Configure steht darüber hinaus ein deklarativer Ansatz zur Verfügung, um Entwicklungsumgebungen standardisiert aufzubauen.

Allerdings sollte Winget nicht für jede Aufgabe eingesetzt werden.

In kurzlebigen Cloud-Runnern sind bereits vorhandene Werkzeuge häufig die bessere Wahl. Für Container sollten die vorgesehenen Container-Mechanismen verwendet werden. Und bei besonders anspruchsvollen Build-Prozessen sind vorbereitete, versionierte Images oft zuverlässiger als wiederholte Softwareinstallationen während jedes Pipeline-Durchlaufs.

Die größte Stärke von Winget in DevOps liegt deshalb nicht darin, bei jedem Build möglichst viele Programme neu zu installieren. Sie liegt darin, Windows-Entwicklungsumgebungen standardisiert, nachvollziehbar und automatisiert bereitzustellen.

Damit kann Winget einen wichtigen Beitrag zu reproduzierbaren Entwicklungsprozessen und einer effizienteren Zusammenarbeit zwischen Entwicklung und IT-Betrieb leisten.

  • Im nächsten Teil unserer Winget-Serie vergleichen wir Winget, Chocolatey und Scoop. Dabei betrachten wir Architektur, Paketangebot, Automatisierung, Sicherheit, Performance, Unternehmensfunktionen und typische Einsatzszenarien.