Skip to content

Instantly share code, notes, and snippets.

@likamrat
Created February 13, 2023 00:41
Show Gist options
  • Save likamrat/cae833a6e5b3461709f14c093c21c293 to your computer and use it in GitHub Desktop.
Save likamrat/cae833a6e5b3461709f14c093c21c293 to your computer and use it in GitHub Desktop.
Installing Winget om Windows Server 2019/2022
Write-Information "This script needs be run on Windows Server 2019 or 2022"
If ($PSVersionTable.PSVersion.Major -ge 7){ Write-Error "This script needs be run by version of PowerShell prior to 7.0" }
# Define environment variables
$downloadDir = "C:\WinGet"
$gitRepo = "microsoft/winget-cli"
$msiFilenamePattern = "*.msixbundle"
$licenseFilenamePattern = "*.xml"
$releasesUri = "https://api.github.com/repos/$gitRepo/releases/latest"
# Preparing working directory
New-Item -Path $downloadDir -ItemType Directory
Push-Location $downloadDir
# Downloaing artifacts
function Install-Package {
param (
[string]$PackageFamilyName
)
Write-Host "Querying latest $PackageFamilyName version and its dependencies..."
$response = Invoke-WebRequest `
-Uri "https://store.rg-adguard.net/api/GetFiles" `
-Method "POST" `
-ContentType "application/x-www-form-urlencoded" `
-Body "type=PackageFamilyName&url=$PackageFamilyName&ring=RP&lang=en-US" -UseBasicParsing
Write-Host "Parsing response..."
$regex = '<td><a href=\"([^\"]*)\"[^\>]*\>([^\<]*)<\/a>'
$packages = (Select-String $regex -InputObject $response -AllMatches).Matches.Groups
$result = $true
for ($i = $packages.Count - 1; $i -ge 0; $i -= 3) {
$url = $packages[$i - 1].Value;
$name = $packages[$i].Value;
$extCheck = @(".appx", ".appxbundle", ".msix", ".msixbundle") | % { $x = $false } { $x = $x -or $name.EndsWith($_) } { $x }
$archCheck = @("x64", "neutral") | % { $x = $false } { $x = $x -or $name.Contains("_$($_)_") } { $x }
if ($extCheck -and $archCheck) {
# Skip if package already exists on system
$currentPackageFamilyName = (Select-String "^[^_]+" -InputObject $name).Matches.Value
$installedVersion = (Get-AppxPackage "$currentPackageFamilyName*").Version
$latestVersion = (Select-String "_(\d+\.\d+.\d+.\d+)_" -InputObject $name).Matches.Value
if ($installedVersion -and ($installedVersion -ge $latestVersion)) {
Write-Host "${currentPackageFamilyName} is already installed, skipping..." -ForegroundColor "Yellow"
continue
}
try {
Write-Host "Downloading package: $name"
$tempPath = "$(Get-Location)\$name"
Invoke-WebRequest -Uri $url -Method Get -OutFile $tempPath
Add-AppxPackage -Path $tempPath
Write-Host "Successfully installed:" $name
} catch {
$result = $false
}
}
}
return $result
}
Write-Host "`n"
function Install-Package-With-Retry {
param (
[string]$PackageFamilyName,
[int]$RetryCount
)
for ($t = 0; $t -le $RetryCount; $t++) {
Write-Host "Attempt $($t + 1) out of $RetryCount..." -ForegroundColor "Cyan"
if (Install-Package $PackageFamilyName) {
return $true
}
}
return $false
}
$licenseDownloadUri = ((Invoke-RestMethod -Method GET -Uri $releasesUri).assets | Where-Object name -like $licenseFilenamePattern ).browser_download_url
$licenseFilename = ((Invoke-RestMethod -Method GET -Uri $releasesUri).assets | Where-Object name -like $licenseFilenamePattern ).name
$licenseJoinPath = Join-Path -Path $downloadDir -ChildPath $licenseFilename
Invoke-WebRequest -Uri $licenseDownloadUri -OutFile ( New-Item -Path $licenseJoinPath -Force )
$result = @("Microsoft.DesktopAppInstaller_8wekyb3d8bbwe") | ForEach-Object { $x = $true } { $x = $x -and (Install-Package-With-Retry $_ 3) } { $x }
$msiFilename = ((Get-ChildItem -Path $downloadDir) | Where-Object name -like $msiFilenamePattern ).name
$msiJoinPath = Join-Path -Path $downloadDir -ChildPath $msiFilename
# Installing winget
Add-ProvisionedAppPackage -Online -PackagePath $msiJoinPath -LicensePath $licenseJoinPath -Verbose
Write-Host "`n"
# Test if winget has been successfully installed
if ($result -and (Test-Path -Path "$env:LOCALAPPDATA\Microsoft\WindowsApps\winget.exe")) {
Write-Host "Congratulations! Windows Package Manager (winget) $(winget --version) installed successfully" -ForegroundColor "Green"
} else {
Write-Host "Oops... Failed to install Windows Package Manager (winget)" -ForegroundColor "Red"
}
# Cleanup
Push-Location $HOME
Remove-Item $downloadDir -Recurse -Force
@ikhansa812
Copy link

@cheema-corellian
Copy link

This script did not work for me.

Attempt 1 out of 3...
Querying latest Microsoft.DesktopAppInstaller_8wekyb3d8bbwe version and its dependencies...
Parsing response...
Microsoft.VCLibs.140.00 is already installed, skipping...
Microsoft.VCLibs.140.00 is already installed, skipping...
Microsoft.VCLibs.140.00.UWPDesktop is already installed, skipping...
Microsoft.VCLibs.140.00.UWPDesktop is already installed, skipping...
Microsoft.UI.Xaml.2.7 is already installed, skipping...
Microsoft.DesktopAppInstaller is already installed, skipping...
Microsoft.DesktopAppInstaller is already installed, skipping...
Microsoft.DesktopAppInstaller is already installed, skipping...
Add-ProvisionedAppPackage : PackagePath must point to a package, not a directory
At C:\users\cheema\WinGet_WinSrv.ps1:94 char:1
+ Add-ProvisionedAppPackage -Online -PackagePath $msiJoinPath -LicenseP ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Add-AppxProvisionedPackage], PSArgumentException
    + FullyQualifiedErrorId : Add-AppxProvisionedPackage,Microsoft.Dism.Commands.AddAppxProvisionedPackageCommand



Program 'winget.exe' failed to run: No applicable app licenses foundAt C:\users\cheema\WinGet_WinSrv.ps1:100 char:69
+ ... ulations! Windows Package Manager (winget) $(winget --version) instal ...
+                                                  ~~~~~~~~~~~~~~~~.
At C:\users\cheema\WinGet_WinSrv.ps1:100 char:69
+ ... ulations! Windows Package Manager (winget) $(winget --version) instal ...
+                                                  ~~~~~~~~~~~~~~~~
    + CategoryInfo          : ResourceUnavailable: (:) [], ApplicationFailedException
    + FullyQualifiedErrorId : NativeCommandFailed

Congratulations! Windows Package Manager (winget)  installed successfully


PS C:\Users\cheema> winget
Program 'winget.exe' failed to run: No applicable app licenses foundAt line:1 char:1
+ winget
+ ~~~~~~.
At line:1 char:1
+ winget
+ ~~~~~~
    + CategoryInfo          : ResourceUnavailable: (:) [], ApplicationFailedException
    + FullyQualifiedErrorId : NativeCommandFailed

@garzamSEA
Copy link

Add-ProvisionedAppPackage : PackagePath must point to a package, not a directory
At C:\users\cheema\WinGet_WinSrv.ps1:94 char:1

  • Add-ProvisionedAppPackage -Online -PackagePath $msiJoinPath -LicenseP ...
  •   + CategoryInfo          : InvalidArgument: (:) [Add-AppxProvisionedPackage], PSArgumentException
      + FullyQualifiedErrorId : Add-AppxProvisionedPackage,Microsoft.Dism.Commands.AddAppxProvisionedPackageCommand
    

Hello @ikhansa812 and @cheema-corellian . I am getting the exact same error (minus the C:\Users directory). I've tried running with and without admin privs. However, I still get the error message "Add-ProvisionedAppPackage : PackagePath must point to a package, not a directory". Should I manually create the C:\WinGet directory? It seems that the script is not creating the $downloadDir and/or not downloading the packages from the repo. It is completely possible that I am misunderstanding what the script is trying to do though.

Thank you for providing this script. Looking forward to getting WinGet on my server :-)

@clayrosenthal
Copy link

Is there a modified version of this to make this work with sysprep?

@DaveidWeba
Copy link

DaveidWeba commented Jul 19, 2023

@garzamSEA If you are still struggling, this is the easiest way to get WinGet installed on Server 2019 or 2022:

# Install Chocolately Package Manager
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
$env:Path = [System.Environment]::ExpandEnvironmentVariables([System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User"))

# Install WinGet from Chocolatey
choco install winget
choco install winget.powershell

# Fix Permissions
TAKEOWN /F "C:\Program Files\WindowsApps" /R /A /D Y
ICACLS "C:\Program Files\WindowsApps" /grant Administrators:F /T

# Add Environment Path
$ResolveWingetPath = Resolve-Path "C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_*_x64__8wekyb3d8bbwe"
if ($ResolveWingetPath) {
	$WingetPath = $ResolveWingetPath[-1].Path
}
$ENV:PATH += ";$WingetPath"
$SystemEnvPath = [System.Environment]::GetEnvironmentVariable('PATH', [System.EnvironmentVariableTarget]::Machine)
$SystemEnvPath += ";$WingetPath;"
setx /M PATH "$SystemEnvPath"

If you prefer to do it manually without the assistance of Chocolatey:

# Create WinGet Folder
New-Item -Path C:\WinGet -ItemType directory -ErrorAction SilentlyContinue

# Install VCLibs
Invoke-WebRequest -Uri https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx -OutFile "C:\WinGet\Microsoft.VCLibs.x64.14.00.Desktop.appx"
Add-AppxPackage "C:\WinGet\Microsoft.VCLibs.x64.14.00.Desktop.appx"

# Install Microsoft.UI.Xaml from NuGet
Invoke-WebRequest -Uri https://www.nuget.org/api/v2/package/Microsoft.UI.Xaml/2.7.3 -OutFile "C:\WinGet\Microsoft.UI.Xaml.2.7.3.zip"
Expand-Archive "C:\WinGet\Microsoft.UI.Xaml.2.7.3.zip" -DestinationPath "C:\WinGet\Microsoft.UI.Xaml.2.7.3"
Add-AppxPackage "C:\WinGet\Microsoft.UI.Xaml.2.7.3\tools\AppX\x64\Release\Microsoft.UI.Xaml.2.7.appx"

# Install latest WinGet from GitHub
Invoke-WebRequest -Uri https://github.com/microsoft/winget-cli/releases/latest/download/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle -OutFile "C:\WinGet\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle"
Add-AppxPackage "C:\WinGet\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle"

# Fix Permissions
TAKEOWN /F "C:\Program Files\WindowsApps" /R /A /D Y
ICACLS "C:\Program Files\WindowsApps" /grant Administrators:F /T

# Add Environment Path
$ResolveWingetPath = Resolve-Path "C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_*_x64__8wekyb3d8bbwe"
if ($ResolveWingetPath) {
	$WingetPath = $ResolveWingetPath[-1].Path
}
$ENV:PATH += ";$WingetPath"
$SystemEnvPath = [System.Environment]::GetEnvironmentVariable('PATH', [System.EnvironmentVariableTarget]::Machine)
$SystemEnvPath += ";$WingetPath;"
setx /M PATH "$SystemEnvPath"

With either method, you should have a working installation of WinGet on your server. Good luck!
image

@TheBigBear
Copy link

BTW @asheroto has a repo with a working installer working on Windows 10, Windows 11, Server 2022 along with a nice bit.ly alias
https://github.com/asheroto/winget-installer
https://bit.ly/winget-installer

@tristanbarcelon
Copy link

tristanbarcelon commented Jul 24, 2023

@DaveidWeba , I followed the script you provided without using chocolatey but it doesn't seem to work even though it installed properly.

image

Executing winget gives me this nondescript error, as if winget doesn't have permission to execute.

image

It has a newer version of winget based on FileVersion data.

image

Suspecting this to be a permission issue, I reran and added to path. It works now.

TAKEOWN /F "C:\Program Files\WindowsApps" /R /A /D Y
ICACLS "C:\Program Files\WindowsApps" /grant Administrators:F /T

@vrichv
Copy link

vrichv commented Jul 25, 2023

thanks,it works.

@Karl-WE
Copy link

Karl-WE commented Sep 24, 2023

can confirm https://github.com/asheroto/winget-install is so far the best solution available. Rock solid.
thank you @TheBigBear
cc @likamrat

@asheroto
Copy link

asheroto commented Sep 25, 2023

I installed Windows 10, Windows 11, and Server 2022 on Virtual Machines, then ran the install over and over again for several hours one morning and concluded that the newer versions of the prerequisites do not function on Windows 10 and Server 2022. On those OS's, they seem to like version 14.00 of VCLibs and version 2.7.3 of UI.Xaml. I'm not sure if there's a fix for that or if it's truly just a compatibility issue. This is just what I found in testing.

In summary, the store.rg-adguard.net method will probably not work on Windows 10 or Server 2022 because it gets a version of the prerequisites that are too new for those OS's. That method will likely only work on Windows 11+. I could not get Server 2019 to work at all but if someone finds an older prerequisite version that works then maybe we can update the scripts.

This area details the functionality that seems to work:
https://github.com/asheroto/winget-install#script-functionality

@o0101
Copy link

o0101 commented Jan 8, 2024

Thanks @DaveidWeba your comment (no Choco version) is working! I use it here

@autb
Copy link

autb commented Mar 5, 2024

Thanks @DaveidWeba. In one OS (Microsoft Windows Server 2019 Standard), I used the version with chocolatey and also the scripts linked to TAKEOWN and ICACLS, but when running winget command an error came indicating that VCRUNTIME140.DLL and MSVCP140.DLL were not found. Then I downloaded and installed the both x86 and x64 versions of the libs vc_redis : x86 && x64 and all running well now.

@Karl-WE
Copy link

Karl-WE commented Mar 7, 2024

The easiest thing is currently to use the "predeploy" package of Microsoft Terminal which comes with similar prereqs installing these and then continueing with winget msix.

@cheema-corellian
Copy link

The easiest thing is currently to use the "predeploy" package of Microsoft Terminal which comes with similar prereqs installing these and then continueing with winget msix.

@Karl-WE I don't mean to sound ungrateful, but why not provide a link to the said "predeploy" package? And yes, I did Google. And did find various different pieces of software that could be considered relevant. None were called "predeploy" package for MS Terminal.

@aweedman
Copy link

aweedman commented Mar 9, 2024

Hi had winget working for a while on Server 2019. I installed the different packages manually. At some point recently winget stopped working. I tried the non-Chocately script above. It seemed to run currently. Getting when I run winget:

Program 'winget.exe' failed to run: The file cannot be accessed by the systemAt line:1 char:1

  • winget upgrade --all

At line:1 char:1

  • winget upgrade --all
  •   + CategoryInfo          : ResourceUnavailable: (:) [], ApplicationFailedException
      + FullyQualifiedErrorId : NativeCommandFailed
    
    

@Karl-WE
Copy link

Karl-WE commented Mar 12, 2024

@cheema-corellian understand your point. No worries.

Head to Microsoft Terminal releases >Release Version
https://github.com/microsoft/terminal/releases

Use the files from the preinstall kit they contain files also required for winget.

These can be installed on Windows Server 2019/2022 (unsupported), Windows Server 2025 has winget inbox.

Example
Microsoft.WindowsTerminal_1.19.10302.0_8wekyb3d8bbwe.msixbundle_Windows10_PreinstallKit.zip

One can argue that by today some prerequisites are available for download via public webpage, offered by Microsoft like vc redist msix packages.

The hardest part is certainly to get the the package manager running that's a requirement for winget and MSIX.

@pariswells
Copy link

@garzamSEA If you are still struggling, this is the easiest way to get WinGet installed on Server 2019 or 2022:

# Install Chocolately Package Manager
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
$env:Path = [System.Environment]::ExpandEnvironmentVariables([System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User"))

# Install WinGet from Chocolatey
choco install winget
choco install winget.powershell

# Fix Permissions
TAKEOWN /F "C:\Program Files\WindowsApps" /R /A /D Y
ICACLS "C:\Program Files\WindowsApps" /grant Administrators:F /T

# Add Environment Path
$ResolveWingetPath = Resolve-Path "C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_*_x64__8wekyb3d8bbwe"
if ($ResolveWingetPath) {
	$WingetPath = $ResolveWingetPath[-1].Path
}
$ENV:PATH += ";$WingetPath"
$SystemEnvPath = [System.Environment]::GetEnvironmentVariable('PATH', [System.EnvironmentVariableTarget]::Machine)
$SystemEnvPath += ";$WingetPath;"
setx /M PATH "$SystemEnvPath"

If you prefer to do it manually without the assistance of Chocolatey:

# Create WinGet Folder
New-Item -Path C:\WinGet -ItemType directory -ErrorAction SilentlyContinue

# Install VCLibs
Invoke-WebRequest -Uri https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx -OutFile "C:\WinGet\Microsoft.VCLibs.x64.14.00.Desktop.appx"
Add-AppxPackage "C:\WinGet\Microsoft.VCLibs.x64.14.00.Desktop.appx"

# Install Microsoft.UI.Xaml from NuGet
Invoke-WebRequest -Uri https://www.nuget.org/api/v2/package/Microsoft.UI.Xaml/2.7.3 -OutFile "C:\WinGet\Microsoft.UI.Xaml.2.7.3.zip"
Expand-Archive "C:\WinGet\Microsoft.UI.Xaml.2.7.3.zip" -DestinationPath "C:\WinGet\Microsoft.UI.Xaml.2.7.3"
Add-AppxPackage "C:\WinGet\Microsoft.UI.Xaml.2.7.3\tools\AppX\x64\Release\Microsoft.UI.Xaml.2.7.appx"

# Install latest WinGet from GitHub
Invoke-WebRequest -Uri https://github.com/microsoft/winget-cli/releases/latest/download/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle -OutFile "C:\WinGet\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle"
Add-AppxPackage "C:\WinGet\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle"

# Fix Permissions
TAKEOWN /F "C:\Program Files\WindowsApps" /R /A /D Y
ICACLS "C:\Program Files\WindowsApps" /grant Administrators:F /T

# Add Environment Path
$ResolveWingetPath = Resolve-Path "C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_*_x64__8wekyb3d8bbwe"
if ($ResolveWingetPath) {
	$WingetPath = $ResolveWingetPath[-1].Path
}
$ENV:PATH += ";$WingetPath"
$SystemEnvPath = [System.Environment]::GetEnvironmentVariable('PATH', [System.EnvironmentVariableTarget]::Machine)
$SystemEnvPath += ";$WingetPath;"
setx /M PATH "$SystemEnvPath"

With either method, you should have a working installation of WinGet on your server. Good luck! image

You need to use the latest version of .UI.Xaml for this to work now

Install Microsoft.UI.Xaml from NuGet

Invoke-WebRequest -Uri https://www.nuget.org/api/v2/package/Microsoft.UI.Xaml/2.8.6 -OutFile "C:\WinGet\Microsoft.UI.Xaml.2.8.6.zip"
Expand-Archive "C:\WinGet\Microsoft.UI.Xaml.2.8.6.zip" -DestinationPath "C:\WinGet\Microsoft.UI.Xaml.2.8.6"
Add-AppxPackage "C:\WinGet\Microsoft.UI.Xaml.2.8.6\tools\AppX\x64\Release\Microsoft.UI.Xaml.2.8.appx"

@pariswells
Copy link

The Invoke-WebRequest looks like its triggering Cloudflares Bot Captcha now for me so I had to use @garzamSEA method

document.createElement('script');cpo.src =
'/cdn-cgi/challenge-platform/h/b/orchestrate/chl_page/v1?ray=87303dcae82cdfab';window._cf_chl_opt.cOgUHash =
location.hash === '' && location.href.indexOf('#') !== -1 ? '#' : location.hash;window._cf_chl_opt.cOgUQuery =
location.search === '' && location.href.slice(0, location.href.length -
window._cf_chl_opt.cOgUHash.length).indexOf('?') !== -1 ? '?' : location.search;if (window.history &&

@Karl-WE
Copy link

Karl-WE commented Apr 16, 2024

you might want to use start-bitstransfer instead of invoke-webrequest for better performance.
i am currently working on a "side quest" to enable a customer with Windows Server 2022 and winget and so far the best automation experience for this unsupported scenario is undoubtly this project:

https://github.com/asheroto/winget-install

@cquresphere
Copy link

My summary:

# Create download directory
if (-not $(Test-Path -Path "C:\WinGet")) {
    New-Item -Path "C:" -Name "WinGet" -ItemType Directory -Force
}

# Dependencies
## Microsoft.UI.Xaml
$UIXamlPath = "C:\WinGet\Microsoft.UI.Xaml.zip"
$downloadUIXamlUri = "https://www.nuget.org/api/v2/package/Microsoft.UI.Xaml/2.8.6"
(New-Object System.Net.WebClient).DownloadFile($downloadUIXamlUri, $UIXamlPath)
Unblock-File -Path $UIXamlPath
Expand-Archive -Path $UIXamlPath -DestinationPath "C:\WinGet\Microsoft.UI.Xaml.2.8.6"
$UIXamlAppxPath = "C:\WinGet\Microsoft.UI.Xaml.2.8.6\tools\AppX\x64\Release\Microsoft.UI.Xaml.2.8.appx"
Add-AppxPackage -Path $UIXamlAppxPath

## Microsoft.VCLibs.x64.14.00.Desktop
$VCLibsPath = "C:\WinGet\Microsoft.VCLibs.x64.14.00.Desktop.appx"
$downloadVClibsUri = "https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx"
(New-Object System.Net.WebClient).DownloadFile($downloadVClibsUri, $VCLibsPath)
Unblock-File -Path $VCLibsPath
Add-AppxPackage -Path $VCLibsPath

# Main Package
# Get the newest WinGet's version the download URL
$assetPattern = "*Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle"
$releasesUri = "https://api.github.com/repos/microsoft/winget-cli/releases/latest"
$asset = (Invoke-RestMethod -Uri $releasesUri -Method Get -ErrorAction stop).assets | Where-Object name -like $assetPattern
$downloadAssetUri = $asset.browser_download_url

# Download newest version of WinGet
$installerPath = "C:\WinGet\$($asset.name)"
(New-Object System.Net.WebClient).DownloadFile($downloadAssetUri, $installerPath)
Unblock-File -Path $installerPath

# Get the newest WinGet's license file download URL
$licensePattern = "*_License1.xml"
$license = (Invoke-RestMethod -Uri $releasesUri -Method Get -ErrorAction stop).assets | Where-Object name -like $licensePattern
$downloadLicenseUri = $license.browser_download_url

# Download license file
$licensePath = "C:\WinGet\$($license.name)"
(New-Object System.Net.WebClient).DownloadFile($downloadLicenseUri, $licensePath)
Unblock-File -Path $licensePath

# Install Package
Add-AppxPackage $installerPath

# Register Package with License
Try {
    Add-AppxProvisionedPackage -Online -PackagePath $installerPath -LicensePath $licensePath -Verbose -LogPath "C:\WinGet\DesktopAppInstaller_Install.log" #-DependencyPackagePath "$UIXamlAppxPath", "$VCLibsPath"
}
Catch {
    try {
        Add-AppxPackage -Path $installerPath -DependencyPath "$UIXamlAppxPath", "$VCLibsPath" -InstallAllResources
    }
    catch {
        Write-Output $_.Exception.Message
        Write-Output $Error[0]
    }
}

# Fix Permissions (S-1-5-32-544) Local Administrators Group (Language independent)
TAKEOWN /F "C:\Program Files\WindowsApps" /R /A /D Y
ICACLS "C:\Program Files\WindowsApps" /grant "*S-1-5-32-544:(F)" /T

# Add Environment Path
$ResolveWingetPath = Resolve-Path "C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_*_x64__8wekyb3d8bbwe"
if ($ResolveWingetPath) {
    $WingetPath = $ResolveWingetPath[-1].Path
}
$ENV:PATH += ";$WingetPath"
$SystemEnvPath = [System.Environment]::GetEnvironmentVariable('PATH', [System.EnvironmentVariableTarget]::Machine)
$SystemEnvPath += ";$WingetPath;"

@Karl-WE
Copy link

Karl-WE commented May 22, 2024

not sure if all of this is really required. Can you check your approach with the one done with the linked GitHub @cquresphere

@ksidirop-laerdal
Copy link

The most recent versions of powershell don't work well with .DownloadFile() so I had to resort to 'Invoke-WebRequest'

# inspired by https://gist.github.com/likamrat/cae833a6e5b3461709f14c093c21c293?permalink_comment_id=5065503#gistcomment-5065503 

# Create download directory
if (-not $(Test-Path -Path "C:\WinGet")) {
    New-Item -Path "C:" -Name "WinGet" -ItemType Directory -Force
}



# Dependencies

Remove-Item "C:\WinGet\" -Recurse -Force
New-Item -Path "C:\WinGet" -ItemType Directory -Force

## Microsoft.UI.Xaml
$UIXamlPath = "C:\WinGet\Microsoft.UI.Xaml.zip"
$downloadUIXamlUri = "https://www.nuget.org/api/v2/package/Microsoft.UI.Xaml/2.8.6"
Invoke-WebRequest $downloadUIXamlUri -outfile $UIXamlPath # (New-Object System.Net.WebClient).DownloadFile($downloadUIXamlUri, $UIXamlPath)
Unblock-File -Path $UIXamlPath
Expand-Archive -Path $UIXamlPath -DestinationPath "C:\WinGet\Microsoft.UI.Xaml.2.8.6"
$UIXamlAppxPath = "C:\WinGet\Microsoft.UI.Xaml.2.8.6\tools\AppX\x64\Release\Microsoft.UI.Xaml.2.8.appx"
Add-AppxPackage -Path $UIXamlAppxPath

## Microsoft.VCLibs.x64.14.00.Desktop
$VCLibsPath = "C:\WinGet\Microsoft.VCLibs.x64.14.00.Desktop.appx"
$downloadVClibsUri = "https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx"
Invoke-WebRequest $downloadVClibsUri -outfile $VCLibsPath # (New-Object System.Net.WebClient).DownloadFile($downloadVClibsUri, $VCLibsPath)
Unblock-File -Path $VCLibsPath
Add-AppxPackage -Path $VCLibsPath

# Main Package
# Get the newest WinGet's version the download URL
$assetPattern = "*Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle"
$releasesUri = "https://api.github.com/repos/microsoft/winget-cli/releases/latest"
$asset = (Invoke-RestMethod -Uri $releasesUri -Method Get -ErrorAction stop).assets | Where-Object name -like $assetPattern
$downloadAssetUri = $asset.browser_download_url

# Download newest version of WinGet
$installerPath = "C:\WinGet\$($asset.name)"
Invoke-WebRequest $downloadAssetUri -outfile $installerPath # (New-Object System.Net.WebClient).DownloadFile($downloadAssetUri, $installerPath)
Unblock-File -Path $installerPath

# Get the newest WinGet's license file download URL
$licensePattern = "*_License1.xml"
$license = (Invoke-RestMethod -Uri $releasesUri -Method Get -ErrorAction stop).assets | Where-Object name -like $licensePattern
$downloadLicenseUri = $license.browser_download_url

# Download license file
$licensePath = "C:\WinGet\$($license.name)"
Invoke-WebRequest $downloadLicenseUri -outfile $licensePath # (New-Object System.Net.WebClient).DownloadFile($downloadLicenseUri, $licensePath)
Unblock-File -Path $licensePath

# Install Package
Add-AppxPackage $installerPath

# Register Package with License
Try {
    Add-AppxProvisionedPackage -Online -PackagePath $installerPath -LicensePath $licensePath -Verbose -LogPath "C:\WinGet\DesktopAppInstaller_Install.log" #-DependencyPackagePath "$UIXamlAppxPath", "$VCLibsPath"
}
Catch {
    try {
        Add-AppxPackage -Path $installerPath -DependencyPath "$UIXamlAppxPath", "$VCLibsPath" -InstallAllResources
    }
    catch {
        Write-Output $_.Exception.Message
        Write-Output $Error[0]
    }
}

# Fix Permissions (S-1-5-32-544) Local Administrators Group (Language independent)
TAKEOWN /F "C:\Program Files\WindowsApps" /R /A /D Y
ICACLS "C:\Program Files\WindowsApps" /grant "*S-1-5-32-544:(F)" /T

# Add Environment Path
$ResolveWingetPath = Resolve-Path "C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_*_x64__8wekyb3d8bbwe"
if ($ResolveWingetPath) {
    $WingetPath = $ResolveWingetPath[-1].Path
}
$ENV:PATH += ";$WingetPath"
$SystemEnvPath = [System.Environment]::GetEnvironmentVariable('PATH', [System.EnvironmentVariableTarget]::Machine)
$SystemEnvPath += ";$WingetPath;"

@cheema-corellian
Copy link

As of Oct 3rd, 2024, none of the scripts on this page work for me. However, the github link provided by @Karl-WE https://github.com/asheroto/winget-install does work. I had to use the "winget-install -Force" option after installing the nuget package in method 1.

@cquresphere
Copy link

The link provided by @Karl-WE is really good, but I recently added some adjustments due to some errors.
To handle them I use these two lines:

Add-AppxPackage -RegisterByFamilyName -MainPackage Microsoft.Winget.Source_8wekyb3d8bbwe

Add-AppPackage -path "https://cdn.winget.microsoft.com/cache/source.msix."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment