Przejdź do głównej treści

Winget w Windows 11: Pożegnaj nieaktualne oprogramowanie

Masz dość nieaktualnego oprogramowania? Odkryj, jak Winget wprowadza znane z Linuxa zarządzanie pakietami do systemu Windows 11. Dowiedz się, jak instalować, wyświetlać i automatyzować aktualizacje aplikacji za pomocą skryptów PowerShell oraz usługi Intune, aby już dziś cieszyć się profesjonalnym systemem działającym w trybie ustaw i zapomnij!
Zawartość

Jestem fanem Linuxa od młodości. Moimi ulubionymi dystrybucjami są te oparte na Debianie. Choć nigdy oficjalnie nie przesiadłem się na niego całkowicie, Linux jest częścią mojego codziennego życia – i Twojego również.

Na co dzień korzystam z Windowsa 11, jednak moim głównym systemem jest macOS, który wywodzi się z Unixa. macOS wykazuje wiele podobieństw do Linuxa, a dzięki potędze terminala mogę robić znacznie więcej, niż tylko polegać na aplikacjach z graficznym interfejsem użytkownika (GUI).

Z drugiej strony, wszystkie moje pozostałe urządzenia opierają się na Linuxie. Mój router bazuje na tym systemie (OpenWrt), mam mały serwer z Ubuntu, który pomaga mi w testowaniu różnych rozwiązań, oraz kilka Raspberry Pi tu i tam.

Funkcją, którą najbardziej cenię w systemach operacyjnych opartych na Linuxie, jest możliwość zarządzania pakietami (oprogramowaniem) zainstalowanymi w systemie. Za pomocą kilku poleceń przy użyciu apt (Debian) lub opkg (używanego nadal w OpenWrt) mogę szybko zaktualizować wszystko, czego aktualnie używam w systemie.

To właśnie tej funkcji najbardziej brakuje mi w Windowsie. Aby zadbać o to, by moje aplikacje były zawsze aktualne, korzystałem z różnych programów. Niektóre są beznadziejne, inne nieźle wywiązują się ze swojego zadania – jak na przykład UCheck – ale żaden z nich nie oferuje wszystkiego.

Odkąd Microsoft zaczął kłaść większy nacisk na Microsoft Store w Windowsie, pojawia się tam coraz więcej aplikacji. Większość programów, które zazwyczaj instaluje się bezpośrednio ze stron deweloperów, trafia również tam – często nawet w formie bezpośrednich odnośników do instalatorów.

W przeciwieństwie do tego, co napisałem wcześniej, z perspektywy użytkownika Maca jestem rozczarowany tym, jak Apple podchodzi do swojego App Store na macOS. O ile iPhone’y polegają na App Store w 99% przypadków, o tyle w wersji na macOS brakuje mnóstwa rzeczy, co jest dość deprymujące.

Dzięki temu, że w Microsoft Store pojawia się coraz więcej aplikacji, można je szybko i bez żadnego wysiłku aktualizować, co jest świetne. Jednak to wciąż nie rozwiązuje wszystkich problemów.

Wciąż mamy w systemie inne zainstalowane oprogramowanie, które wymaga aktualizacji, i tutaj z pomocą przychodzi winget (Windows Package Manager).

Zapomnij o drogim oprogramowaniu do utrzymywania aktualności aplikacji i w pierwszej kolejności wypróbuj to rozwiązanie.

Mały spoiler: niektóre pakiety udostępniane przez Winget mogą być o wersję lub dwie do tyłu względem najnowszych wydań. Czasami jednak to dobrze – system ten stawia bardziej na stabilność niż na posiadanie zawsze najświeższej, ale niekoniecznie najbardziej dopracowanej wersji.

WinGet to narzędzie wiersza poleceń, które umożliwia użytkownikom wyszukiwanie, instalowanie, aktualizowanie, usuwanie oraz konfigurowanie aplikacji w systemie Windows.

Jest ono tak użyteczne i tak bardzo przypomina mi korzystanie z sudo apt update && sudo apt upgrade w Linuxie, że zdecydowałem się wdrożyć je jako element automatyzacji na wszystkich komputerach w moim miejscu pracy.

W środowisku biznesowym dbanie o aktualność systemu operacyjnego nie stanowi problemu, jednak utrzymywanie najnowszych wersji aplikacji to już zupełnie inna bajka. Jako administrator globalny w infrastrukturze Microsoft 365 uważam, że pomoc ze strony winget będzie przełomem (tzw. game-changerem) w dbałości o aktualizacje u użytkowników.

Pobieranie WinGet

W najnowszej wersji systemu Windows 11 narzędzie winget powinno być już domyślnie dostępne. Warto jednak uruchomić Microsoft Store, przejść do sekcji Biblioteka (Pobieranie), sprawdzić dostępność aktualizacji i zainstalować je. Może to wymusić pobranie aktualizacji do Instalatora aplikacji (App Installer), który jest częścią narzędzia winget, z którego będziemy korzystać.

Jeśli z jakiegoś powodu polecenie winget nie działa (w starszych wersjach Windows 11), musisz zainstalować je ręcznie. W tym celu przejdź do oficjalnego repozytorium Winget CLI na GitHubie i z sekcji Assets pobierz plik z rozszerzeniem .msixbundle (Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle).

Winget w Terminalu (Administrator)

Kliknijmy prawym przyciskiem myszy na menu Start i uruchommy Terminal (Administrator), aby wypróbować winget i przekonać się o jego potędze.

Korzystając z WinGet bez uprawnień administratora (w zwykłym Terminalu użytkownika), niektóre aplikacje mogą wymagać podniesienia uprawnień do instalacji. W razie potrzeby system wyświetli odpowiedni komunikat.

Aby sprawdzić, jakie oprogramowanie jest zainstalowane na Twoim komputerze, wystarczy uruchomić następujące polecenie:

winget list

Zauważ, że lista może być długa i nie wszystkie aplikacje można zaktualizować za pomocą Winget; większość oprogramowania jednak na to pozwala i właśnie na tym się skoncentrujemy.

Aby szybko sprawdzić, które nieaktualne aplikacje można zaktualizować, po prostu uruchom:

winget upgrade

Jeśli chcesz zaktualizować konkretną aplikację z wygenerowanej listy, po prostu dopisz jej nazwę do powyższego polecenia. Jeżeli natomiast chcesz przeprowadzić aktualizację wszystkich aplikacji naraz, użyj następującej komendy:

winget upgrade --all

To najszybsza metoda, aby zaktualizować wszystko jednocześnie.

Jeśli po uruchomieniu parametru --all niektóre aplikacje nadal nie zostały zaktualizowane, może to wynikać ze sposobu, w jaki zostały pierwotnie zainstalowane. Ale nawet na to istnieje rozwiązanie.

W takim przypadku odinstalowanie programu (winget uninstall) i ponowna jego instalacja (winget install) rozwiąże problem na przyszłość, umożliwiając późniejsze aktualizacje przez winget upgrade.

Winget posiada wiele dostępnych poleceń, ale nie będę się tutaj na nich skupiać. Możesz zapoznać się ze wszystkimi poleceniami Winget, korzystając z oficjalnych materiałów Microsoft.

Chcę się natomiast skoncentrować na utrzymywaniu aktualności aplikacji poprzez zautomatyzowane zadanie (w Harmonogramie zadań), abyśmy mogli je skonfigurować i o nim zapomnieć.

Jest to niezwykle przydatne, ponieważ w środowisku biznesowym Microsoft 365 można takie rozwiązanie wdrożyć poprzez portal Intune na wszystkich komputerach z systemem Windows 11. To właśnie na tym skupię się w dalszej części.

Niektórzy z Was mogą preferować ręczne uruchamianie winget upgrade --all, jednak dla większości zwykłych użytkowników podejście typu „ustaw i zapomnij” będzie lepszym wyjściem.

Jeśli uruchamiasz winget upgrade po raz pierwszy, możesz zostać poproszony o zaakceptowanie warunków źródłowych. Chcąc uruchamiać to polecenie automatycznie przez harmonogram zadań, będziesz musiał również zmodyfikować system, aby zezwolić na wykonywanie skryptów. Wszystko to zawrzemy w jednym poleceniu.

Wdrażanie skryptu aktualizacji Winget i planowanie zadania

Pracowałem nad skryptem, który zostanie wdrożony na komputerze użytkownika, skonfiguruje wszystkie niezbędne elementy, zaplanuje zadanie i wykona je o określonej godzinie.

Zanim wszystko zaczęło działać zgodnie z planem, musiałem wziąć pod uwagę kilka kwestii. Przeanalizujmy krok po kroku, co zawiera ten skrypt.

Jeśli interesuje Cię tylko końcowy skrypt PowerShell, przejdź bezpośrednio do sekcji Skrypt końcowy.

Krok 1. Upewnij się, że zasady wykonywania (Execution Policy) zezwalają na uruchamianie skryptów

Skrypt – niezależnie od tego, czy jest wdrażany przez usługę Intune w środowisku biznesowym, czy uruchamiany ręcznie – wymaga włączenia możliwości wykonywania skryptów przez użytkowników. Funkcja ta nie jest domyślnie włączona i wymaga wykonania poniższych linii w terminalu PowerShell.

Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope CurrentUser -Force
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope LocalMachine -Force

Krok 2: Sprawdź, czy program Winget jest zainstalowany

Jeśli w Twoim środowisku nie ma narzędzia winget i nie udało Ci się go zainstalować wcześniej zgodnie z opisem, skrypt sprawdzi jego obecność, a w razie potrzeby pobierze najnowszą wersję i ją zainstaluje.

Krok 3: Zapisz pełną treść skryptu aktualizacji

W folderze profilu użytkownika (%userprofile%) skrypt utworzy plik, który będzie później wykorzystywany przez Harmonogram zadań do uruchamiania i aktualizowania aplikacji. Plik otrzyma nazwę winget_upgrade_all.ps1 i domyślnie będzie działał w trybie cichym (silent mode).

Podczas pracy nad tym plikiem natknąłem się na problemy z niektórymi aplikacjami, które nie pozwalają na uruchomienie w tle (w trybie cichym). W takim przypadku, po wykryciu błędu, zadanie zostanie uruchomione ponownie, a użytkownik zostanie poproszony o postępowanie zgodnie z instrukcjami wyświetlanymi na ekranie.

Jeśli wszystko pójdzie pomyślnie i nie zostaną znalezione żadne kolejne nieudane aktualizacje, skrypt zakończy działanie, a zadanie zostanie uruchomione ponownie przy następnej zaplanowanej okazji.

Wewnątrz skryptu uwzględniłem automatyczną akceptację regulaminów źródeł oraz pakietów, które pojawiają się przy pierwszym uruchomieniu komendy winget. W przeciwnym razie proces zakończyłby się niepowodzeniem, szczególnie podczas pracy w trybie cichym.

Krok 4: Utwórz lub zaktualizuj zaplanowane zadanie (harmonogram tygodniowy od poniedziałku do piątku)

Ostatnim krokiem było utworzenie zadania w Harmonogramie zadań, które będzie automatycznie sprawdzać aktualizacje codziennie o godzinie 13:00, od poniedziałku do piątku.

Tutaj ponownie natknąłem się na kilka kwestii, które musiałem wziąć pod uwagę. Jeśli zadanie już istniało, chciałem mieć pewność, że zostanie ono zaktualizowane. Nawet wtedy napotkałem pewne trudności, więc uznałem, że jeśli aktualizacja zadania się nie powiedzie, skrypt je usunie i doda ponownie.

Skrypt końcowy

Ostatecznie przygotowałem skrypt, który można uruchomić ręcznie w terminalu, aby utworzyć niezbędny plik aktualizacji oraz zadanie w Harmonogramie zadań, bądź też wdrożyć go za pomocą portalu Intune.

W portalu Intune dodałem go w sekcji Urządzenia > Skrypty i korygowanie (Devices > Scripts and remediations) w ramach Skryptów platformy (Platform Scripts), wybierając następujące opcje:

  • Uruchom ten skrypt przy użyciu poświadczeń zalogowanego użytkownika: Tak (Yes)
  • Wymuszaj sprawdzanie podpisu skryptu: Nie (No)
  • Uruchom skrypt w 64-bitowym hoście PowerShell: Tak (Yes)

Nie korzystałem z opcji Korygowanie (Remediations), ponieważ nie wszystkie licencje moich użytkowników na to pozwalają.

# ============================================
# Deploy Winget Update Script and Schedule Task
# ============================================

# Step 1: Ensure Execution Policy allows script execution
Write-Host "Setting Execution Policy to Bypass..."
powershell.exe Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope CurrentUser -Force
powershell.exe Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope LocalMachine -Force
powershell.exe Get-ExecutionPolicy -List

# Define paths
$UserFolder = $env:USERPROFILE
$ScriptPath = Join-Path $UserFolder "winget_upgrade_all.ps1"
$TaskName = "WingetAutoUpgrade"

# Step 2: Check if Winget is installed
if (-not (Get-Command winget.exe -ErrorAction SilentlyContinue)) {
    Write-Host "Winget not found. Downloading App Installer from GitHub..."
    $WingetUrl = "https://github.com/microsoft/winget-cli/releases/latest/download/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle"
    $WingetPath = "$env:TEMP\AppInstaller.msixbundle"

    try {
        Invoke-WebRequest -Uri $WingetUrl -OutFile $WingetPath -UseBasicParsing
        if (Test-Path $WingetPath) {
            Write-Host "Installing App Installer..."
            Add-AppxPackage -Path $WingetPath
            Write-Host "App Installer installed successfully."
        } else {
            Write-Host "Failed to download App Installer package."
        }
    } catch {
        Write-Host "Error installing App Installer: $($_.Exception.Message)"
    }
} else {
    Write-Host "Winget is already installed."
}

# Step 3: Write the full update script content
$ScriptContent = @'
# ============================================
# Winget Advanced Upgrade Script
# ============================================

$LogPath = "$env:TEMP\WingetAdvancedUpgradeLog.txt"
Write-Host "Starting Winget upgrade process..." -ForegroundColor Cyan
Write-Host "Logging to $LogPath" -ForegroundColor Cyan
Add-Content -Path $LogPath -Value "`n===== Upgrade Run: $(Get-Date) =====`n"

if (-not (Get-Command winget -ErrorAction SilentlyContinue)) {
    Write-Host "Winget is not installed or not in PATH." -ForegroundColor Red
    Add-Content -Path $LogPath -Value "Winget not found."
    exit 1
}

Write-Host "Running silent upgrade for all apps..." -ForegroundColor Yellow
$SilentResult = winget upgrade --all --silent --accept-source-agreements --accept-package-agreements
Add-Content -Path $LogPath -Value "`nSilent Upgrade Output:`n$SilentResult"

Write-Host "Checking for failed apps..." -ForegroundColor Yellow
$FailedApps = ($SilentResult | Select-String "Installer failed" | ForEach-Object {
    if ($_ -match '\[(.*?)\]') { $Matches[1] }
}) | Where-Object { $_ -ne "" }

if ($FailedApps.Count -gt 0) {
    Write-Host "Retrying failed apps interactively (no --silent)..." -ForegroundColor Yellow
    foreach ($App in $FailedApps) {
        Write-Host "Retrying $App..." -ForegroundColor Cyan
        Add-Content -Path $LogPath -Value "`nRetrying ${App}:`n"
        winget upgrade $App --accept-source-agreements --accept-package-agreements | Out-File -Append $LogPath
    }
} else {
    Write-Host "No failed apps detected." -ForegroundColor Green
    Add-Content -Path $LogPath -Value "`nNo failed apps detected.`n"
}
'@

# Save the script to user folder
Set-Content -Path $ScriptPath -Value $ScriptContent -Force

# Step 4: Create or update scheduled task (Weekly trigger for Mon–Fri)
$Action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$ScriptPath`""
$Trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Monday,Tuesday,Wednesday,Thursday,Friday -At 13:00
$Principal = New-ScheduledTaskPrincipal -UserId $env:USERNAME -LogonType Interactive -RunLevel Highest

if (Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue) {
    try {
        Write-Host "Scheduled task '$TaskName' already exists. Attempting update..."
        Set-ScheduledTask -TaskName $TaskName -Action $Action -Trigger $Trigger
    } catch {
        Write-Host "Update failed. Removing and recreating task..."
        Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false
        Register-ScheduledTask -TaskName $TaskName -Action $Action -Trigger $Trigger -Principal $Principal
    }
} else {
    Write-Host "Creating new scheduled task '$TaskName'..."
    Register-ScheduledTask -TaskName $TaskName -Action $Action -Trigger $Trigger -Principal $Principal
}

Write-Host "Deployment complete: Script saved to $ScriptPath and scheduled task '$TaskName' created or updated."

W ten oto sposób, dzięki narzędziu winget, wdrożyłem skuteczniejszy sposób na utrzymywanie aktualności oprogramowania na urządzeniach moich oraz moich użytkowników.

Udostępnij na Threads
Udostępnij na Bluesky
Udostępnij na Linkedin
Udostępnij przez WhatsApp
Udostępnij przez Email

Komentarze i Reakcje

Kategorie