Skip to content

Instantly share code, notes, and snippets.

@ittchmh
Last active September 16, 2023 18:29
Show Gist options
  • Select an option

  • Save ittchmh/324f846c0f0ac15a30f837ec81820ee8 to your computer and use it in GitHub Desktop.

Select an option

Save ittchmh/324f846c0f0ac15a30f837ec81820ee8 to your computer and use it in GitHub Desktop.
Install WinGet Preview/Release
[CmdletBinding()]
param (
[Parameter()]
[ValidateSet("RP", "Retail")]
[string]
$Ring = "RP"
)
## Set Execution Policy
$progressPreference = 'silentlyContinue'
## Helper Funcions
## Covert version Function
function Convert-AppVersionFromString {
[CmdletBinding()]
param (
[string]
$Version
)
process {
if ($Version -like "*preview*") {
[version]$AppVersion = $Version -replace '^v\.|^v|(-preview$)', ''
Return [PSCustomObject]@{
Version = $AppVersion
IsRP = $true
}
} else {
[version]$AppVersion = $Version -replace '^v\.|^v', ''
Return [PSCustomObject]@{
Version = $AppVersion
IsRP = $false
}
}
}
}
## Check latest version
function Get-WingetLatestVersion {
[CmdletBinding()]
param (
[Parameter(
Mandatory = $false,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 0)]
[string]
$Ring = "RP"
)
process {
$Uri = [uri]"https://api.github.com/repos/microsoft/winget-cli/releases"
$FileExt = ".msixbundle"
if ($Ring -eq "RP") {
## Latest Pre-release version
## ring=RP (Release Preview)
$LatestDownload = $(Invoke-RestMethod $Uri) `
| Select-Object tag_name, target_commitish,prerelease,created_at,published_at, `
@{n="ver";e={(Convert-AppVersionFromString $_.tag_name).version}}, `
@{n="IsRP";e={(Convert-AppVersionFromString $_.tag_name).IsRP}}, `
@{
n="browser_download_url";
e={
$_.assets.browser_download_url | Where-Object {$_.EndsWith($FileExt)}}
} | Where-Object {$null -ne $_.browser_download_url} `
| Sort-Object ver -Descending | Select-Object -First 1
return [System.Version]$LatestDownload.ver
} else {
## Latest Release version
## ring=Retail
$LatestDownload = $(Invoke-RestMethod $Uri) `
| Select-Object tag_name, target_commitish,prerelease,created_at,published_at, `
@{n="ver";e={(Convert-AppVersionFromString $_.tag_name).version}}, `
@{n="IsRP";e={(Convert-AppVersionFromString $_.tag_name).IsRP}}, `
@{
n="browser_download_url";
e={
$_.assets.browser_download_url | Where-Object {$_.EndsWith($FileExt)}}
} | Where-Object {$_.IsRP -eq $false -and $_.target_commitish -notlike "rc-*" -and $null -ne $_.browser_download_url} `
| Sort-Object ver -Descending | Select-Object -First 1
return [System.Version]$LatestDownload.ver
}
}
}
## Download function
function Get-FilesFromCollection {
[CmdletBinding()]
param (
[Parameter(
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 0)]
[string]
$App,
[Parameter(
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 1)]
[Uri]
$Uri,
[Parameter(
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 2)]
[string]
$Filter,
[Parameter(
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 3)]
[string]
$FileExt,
[Parameter(
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 4)]
[string]
$Kind,
[Parameter(
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 5)]
[string]
$Ring
)
process {
if ($Kind -eq "HTTP") {
$OutFile = Join-Path -Path (Get-Location) -ChildPath $Uri.LocalPath
Invoke-WebRequest -Uri $Uri -OutFile $OutFile
return [System.IO.FileInfo]$OutFile
} elseif ($Kind -eq "GitHub") {
if ($Ring -eq "RP") {
## Latest Pre-release version
## ring=RP (Release Preview)
$LatestDownload = $(Invoke-RestMethod $Uri) `
| Select-Object tag_name, target_commitish,prerelease,created_at,published_at, `
@{n="ver";e={(Convert-AppVersionFromString $_.tag_name).version}}, `
@{n="IsRP";e={(Convert-AppVersionFromString $_.tag_name).IsRP}}, `
@{
n="browser_download_url";
e={
$_.assets.browser_download_url | Where-Object {$_.EndsWith($FileExt)}}
} | Where-Object {$null -ne $_.browser_download_url} `
| Sort-Object ver -Descending | Select-Object -First 1
# $LatestDownload
$OutFile = Join-Path -Path (Get-Location) -ChildPath $LatestDownload.browser_download_url.Split("/")[-1]
Invoke-RestMethod -Uri $LatestDownload.browser_download_url -OutFile $OutFile
return [System.IO.FileInfo]$OutFile
} else {
## Latest Release version
## ring=Retail
$LatestDownload = $(Invoke-RestMethod $Uri) `
| Select-Object tag_name, target_commitish,prerelease,created_at,published_at, `
@{n="ver";e={(Convert-AppVersionFromString $_.tag_name).version}}, `
@{n="IsRP";e={(Convert-AppVersionFromString $_.tag_name).IsRP}}, `
@{
n="browser_download_url";
e={
$_.assets.browser_download_url | Where-Object {$_.EndsWith($FileExt)}}
} | Where-Object {$_.IsRP -eq $false -and $_.target_commitish -notlike "rc-*" -and $null -ne $_.browser_download_url} `
| Sort-Object ver -Descending | Select-Object -First 1
$OutFile = Join-Path -Path (Get-Location) -ChildPath $LatestDownload.browser_download_url.Split("/")[-1]
Invoke-RestMethod -Uri $LatestDownload.browser_download_url -OutFile $OutFile
return [System.IO.FileInfo]$OutFile
}
}
}
}
function Get-StoreAppPackage {
[CmdletBinding()]
param (
[string]$Uri,
[string]$Filter = '.*', #Regex
[string]$Ring = 'RP'
)
process {
$WebResponse = Invoke-WebRequest -UseBasicParsing -Method 'POST' -Uri 'https://store.rg-adguard.net/api/GetFiles' -Body "type=url&url=$Uri&ring=$Ring" -ContentType 'application/x-www-form-urlencoded'
$WebResponse.Links.outerHtml | Where-Object {($_ -like '*.appx*') -or ($_ -like '*.msix*')} | Where-Object {$_ -like '*_neutral_*' -or $_ -like "*_"+$env:PROCESSOR_ARCHITECTURE.Replace("AMD","x").Replace("IA","X")+"_*"} | ForEach-Object {
if ($_ -match '(?<=rel="noreferrer">).+(?=</a>)' ) {
$filename = $matches.Values[0]
}
if ($_ -match '(?<=a href=").+(?=" r)' ) {
$downloadurl = $matches.Values[0]
}
[PSCustomObject]@{
filename = ([System.IO.FileInfo]([System.String]$filename)).name
downloadurl = ([System.Uri]([System.String]$downloadurl)).AbsoluteUri
}
} | Where-Object -Property filename -Match $filter
}
}
## Get installed WinGet version
if (Get-Command winget.exe -ErrorAction SilentlyContinue) {
$WingetVersion = winget --version
if ($WingetVersion) {
$WingetVersion = Convert-AppVersionFromString $WingetVersion
$LatestWingetVer = Get-WingetLatestVersion $Ring
if ($LatestWingetVer -le $WingetVersion.Version) {
Write-Output "Latest WinGet version $($WingetVersion.Version) already installed."
Break
}
}
}
## Check if PowerShell Core available
if (Test-Path -Path (get-command pwsh.exe -ErrorAction SilentlyContinue).Path -ErrorAction SilentlyContinue) {
$pwsh = (get-command pwsh.exe).Path
} else {
$pwsh = "powershell.exe"
}
## Check if running as Administrator and restart as Administrator if not
if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
if ($MyInvocation.BoundParameters.keys.count -gt 0) {
$boundParameters = ""
$MyInvocation.BoundParameters.keys | ForEach-Object {
$boundParameters += "-$($_) '$($PSBoundParameters.Item($_))' "
}
$arguments = "& '" + $myinvocation.mycommand.definition + "' $boundParameters"
} else {
$arguments = "& '" + $myinvocation.mycommand.definition + "'"
}
Start-Process $pwsh -Verb runAs -ArgumentList $arguments
Break
}
## Downloads collection
$Downloads = @(
@{
App = "Microsoft.VCLibs"
Uri = [uri]"https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx"
Kind = "HTTP"
Filter = "Microsoft.VCLibs.x64.14.00.Desktop"
FileExt = ".appx"
Ring = "Retail"
}
@{
App = "winget-cli"
Uri = [uri]"https://api.github.com/repos/microsoft/winget-cli/releases"
Kind = "GitHub"
Filter = "Microsoft.DesktopAppInstaller_8wekyb3d8bbwe"
FileExt = ".msixbundle"
Ring = $Ring
}
@{
App = "winget-cli-License"
Uri = [uri]"https://api.github.com/repos/microsoft/winget-cli/releases"
Filter = "Microsoft.DesktopAppInstaller_8wekyb3d8bbwe"
FileExt = ".xml"
Kind = "GitHub"
Ring = $Ring
}
)
# @{
# App = "Microsoft.UI.Xaml"
# Uri = [uri]"https://api.github.com/repos/microsoft/microsoft-ui-xaml/releases"
# Kind = "GitHub"
# Filter = "Microsoft.UI.Xaml"
# FileExt = ".x64.appx"
# Ring = "Retail"
# }
## Set location to temp folder
Get-Location | Push-Location
$TempFolder = New-Item -Path "$env:TEMP\winget" -Force -Confirm:$false -ItemType Directory -ErrorAction SilentlyContinue
Set-Location -Path $TempFolder
$FilesToInstall = @()
foreach ($Download in $Downloads) {
$FilesToInstall += Get-FilesFromCollection @Download
}
## Microsoft.UI.Xaml.2.7.x64.appx
## WinGet Microsoft Store Link
$StoreLink = 'https://apps.microsoft.com/store/detail/app-installer/9NBLGGH4NNS1'
$StorePackage = Get-StoreAppPackage -Uri $StoreLink -Filter "Microsoft.UI.Xaml" -Ring $Ring
Invoke-WebRequest -Uri $StorePackage.downloadurl -OutFile $StorePackage.filename
## Install winget and dependencies
Add-AppxProvisionedPackage -Online -PackagePath $FilesToInstall[1] -LicensePath $FilesToInstall[2] `
-DependencyPackagePath $FilesToInstall[0],$StorePackage.filename
## Install/Update WinGet PowerShell Module
$LocalModule = Get-Module -ListAvailable -Name Microsoft.WinGet.Client -ErrorAction SilentlyContinue
if ($LocalModule) {
$ModuleOnline = Find-Module -Name Microsoft.WinGet.Client -Repository PSGallery -ErrorAction SilentlyContinue
if ($ModuleOnline.Version -gt $LocalModule.Version) {
Update-Module -Name Microsoft.WinGet.Client -Force
}
} else {
Install-Module -Name Microsoft.WinGet.Client -Force
}
## Clean up
Pop-Location
Remove-Item -Path $TempFolder -Force -Recurse
# ## Check Version
# winget --version
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment