Public/Software/Install-Winget.ps1
|
function Install-Winget { <# .SYNOPSIS Installs winget (Windows Package Manager) if it is not already installed on the system. .DESCRIPTION The `Install-Winget` function checks if winget is installed on the system by attempting to retrieve its version. If winget is not installed, the function will download and install the App Installer package from Microsoft, which includes winget. If winget is already installed, it outputs the current version. .EXAMPLE Install-Winget This example checks if winget is installed on the system. If it is not, the function installs winget. If it is already installed, it prints the installed version of winget. .NOTES Author: Michiel VH Requires: Internet connection for downloading App Installer if it is not already installed. Requires: Windows 10 version 1809 or later, or Windows 11. Administrator privileges may be required for installing AppX packages. .LINK https://learn.microsoft.com/en-us/windows/package-manager/winget/ Learn more about winget and Windows Package Manager. #> # Check if winget is already installed $wingetCommand = Get-Command -Name winget -ErrorAction SilentlyContinue if ($wingetCommand) { try { $wingetVersion = winget --version 2>&1 Write-Output "winget is already installed. Version: $wingetVersion" return } catch { # If version check fails, winget might be a stub, so continue with installation Write-Warning "winget command found but version check failed. Attempting installation..." } } Write-Output "winget will be installed" try { # Check Windows version (winget requires Windows 10 1809+ or Windows 11) $osInfo = Get-CimInstance -ClassName Win32_OperatingSystem $osVersion = [Version](($osInfo.Version -split '\.')[0..1] -join '.') if ($osVersion -lt [Version]"10.0") { throw "winget requires Windows 10 version 1809 or later, or Windows 11. Current OS version: $($osInfo.Version)" } # Download App Installer package (includes winget) Write-Output "Downloading App Installer package..." $appInstallerPath = Join-Path -Path $env:TEMP -ChildPath "Microsoft.DesktopAppInstaller.msixbundle" # Try the official Microsoft download link $appInstallerUrl = "https://aka.ms/getwinget" try { Invoke-WebRequest -Uri $appInstallerUrl -OutFile $appInstallerPath -ErrorAction Stop } catch { # Alternative: Download from GitHub releases if official link fails Write-Warning "Failed to download from official source. Trying alternative method..." $releasesUrl = "https://api.github.com/repos/microsoft/winget-cli/releases/latest" $release = Invoke-RestMethod -Uri $releasesUrl -ErrorAction Stop $msixAsset = $release.assets | Where-Object { $_.name -like "*.msixbundle" } | Select-Object -First 1 if ($msixAsset) { Write-Output "Downloading from GitHub releases..." Invoke-WebRequest -Uri $msixAsset.browser_download_url -OutFile $appInstallerPath -ErrorAction Stop } else { throw "Could not find App Installer package to download" } } # Install App Installer package Write-Output "Installing App Installer package..." Add-AppxPackage -Path $appInstallerPath -ErrorAction Stop Write-Output "winget has been successfully installed." # Verify installation Start-Sleep -Seconds 2 $wingetCommand = Get-Command -Name winget -ErrorAction SilentlyContinue if ($wingetCommand) { try { $wingetVersion = winget --version 2>&1 Write-Output "Verified: winget version $wingetVersion is now available." } catch { Write-Warning "winget was installed but version check failed. You may need to restart your terminal." } } else { Write-Warning "winget installation completed, but command not yet available. Please restart your terminal." } } catch { Write-Error "Failed to install winget: $_" throw } finally { # Clean up downloaded file if (Test-Path $appInstallerPath) { Remove-Item -Path $appInstallerPath -Force -ErrorAction SilentlyContinue } } } |