Last active
October 12, 2023 17:00
-
-
Save mavaddat/26146d111abf62f6160b1bd02a392ba8 to your computer and use it in GitHub Desktop.
This correctly downloads neutral and x64 packages but untested for arm and 32bit systems. The path must point to a folder.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Usage (for one URI): | |
<# | |
Import-Module -Name Invoke-DownloadAppxPackage.ps1 | |
$URI = 'https://www.microsoft.com/store/productId/9P6RC76MSMMJ' # From Windows Store 'share' | |
if( Get-Command -Name Get-AppxPackageDownload -CommandType Function ) { | |
Get-AppxPackageDownload -Uri $URI -Path $env:TEMP # Use -Force to skip confirmation | |
} else { | |
Write-Host 'Get-AppxPackageDownload function not found' | |
} | |
#> | |
# Usage (for multiple URIs): | |
<# | |
Import-Module -Name Invoke-DownloadAppxPackage.ps1 | |
$URIs = @('https://www.microsoft.com/store/productId/9P6RC76MSMMJ', 'https://www.microsoft.com/store/productId/9N0866FS04W8', 'https://www.microsoft.com/store/productId/9NH2GPH4JZS4') | |
if( Get-Command -Name Get-AppxPackageDownload -CommandType Function ) { | |
$URIs | ForEach-Object { | |
Get-AppxPackageDownload -Uri $_ -Path $env:TEMP -Force # Use -Force to skip confirmation | |
} | |
} else { | |
Write-Host 'Get-AppxPackageDownload function not found' | |
} | |
#> | |
function Invoke-DownloadAppxPackage | |
{ | |
[CmdletBinding(SupportsShouldProcess)] | |
param ( | |
[Parameter(Mandatory, ValueFromPipeline)] | |
[ValidateScript({ [uri]::TryCreate($_, [UriKind]::Absolute, [ref]$null) })] | |
[string]$Uri, | |
[ValidateScript({ Test-Path -Path $_ -PathType Container })] | |
[string]$OutputDir = $env:TEMP | |
) | |
process | |
{ | |
if ($WhatIfPreference) | |
{ | |
$OutputDir = $env:TEMP | |
} | |
else | |
{ | |
$OutputDir = (Resolve-Path -Path $OutputDir).Path | |
} | |
#Get Urls to download | |
$WebResponse = Invoke-WebRequest -Uri 'https://store.rg-adguard.net/api/GetFiles' -Method Post -Body "type=url&url=$Uri&ring=Retail" -ContentType 'application/x-www-form-urlencoded' | |
$LinksMatch = $WebResponse.Links | Where-Object { $_ -like '*.appx*' } | Where-Object { $_ -like '*_neutral_*' -or $_ -like '*_' + $env:PROCESSOR_ARCHITECTURE.Replace('AMD', 'X').Replace('IA', 'X') + '_*' } | Select-String -Pattern '(?<=a href=").+(?=" r)' | Select-Object -ExpandProperty Matches | |
$DownloadLinks = $LinksMatch.Value | |
function private:Resolve-NameConflict | |
{ | |
#Accepts Path to a FILE and changes it so there are no name conflicts | |
param( | |
[string]$OutputDir | |
) | |
$newPath = $OutputDir | |
if (Test-Path $OutputDir -PathType Leaf) | |
{ | |
$i = 0 | |
$item = (Get-Item $OutputDir) | |
while ( (Test-Path $newPath -PathType Leaf) -and ($i -lt [int]([math]::Sqrt([int]::MaxValue)))) | |
{ | |
$i += 1 | |
$newPath = Join-Path $item.DirectoryName ($item.BaseName + "($i)" + $item.Extension) | |
} | |
} | |
return $newPath | |
} | |
$InstallQueue = [System.Collections.Generic.Queue[string]]::new(($DownloadLinks.Count)) | |
#Download Urls | |
foreach ($url in $DownloadLinks) | |
{ | |
$FileRequest = $null | |
try | |
{ | |
$FileRequest = Invoke-WebRequest -Uri $url -ErrorAction SilentlyContinue | |
} | |
catch | |
{ | |
Write-Warning "Failed to download '$url' - $_" | |
} | |
$AppxFileName = ($FileRequest.Headers['Content-Disposition'] | Select-String -Pattern '(?<=filename=).+').Matches.Value | |
$AppxFilePath = Join-Path -Path $OutputDir -ChildPath $AppxFileName | |
$AppxFilePath = Resolve-NameConflict -OutputDir $OutputDir | |
try{ | |
[System.IO.File]::WriteAllBytes($AppxFilePath, $FileRequest.Content) | Out-Null | |
} | |
catch{ | |
Write-Warning "Failed to write to '$AppxFilePath' - $_" | |
} | |
if ( -not $ConfirmPreference -or $PSCmdlet.ShouldProcess($AppxFileName, 'Add Appx Package')) | |
{ | |
try { Add-AppxPackage -Path $AppxFilePath -ErrorAction SilentlyContinue } catch { $InstallQueue.EnQueue($AppxFilePath) } | |
} | |
} | |
while ($InstallQueue.Count -gt 0) | |
{ | |
Write-Verbose "Retrying Add-AppxPackage on '$($InstallQueue.Peek())'" | |
Add-AppxPackage -Path ($InstallQueue.DeQueue()) | |
} | |
} | |
} |
i think have found the issue, although i have no idea how do i fix it
$AppxFileName = ($FileRequest.Headers['Content-Disposition'] | Select-String -Pattern '(?<=filename=).+').Matches.Value
$AppxFileName in your script is not storing any value whatsoever
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Ah good to know, gonna test the new script now. I feel bit safe in first checking all the downloaded packages before installing them manually. Maybe you can add a parameter to skip download like say
Download-AppxPackage -Uri "$URL" -OutputDir"$PATH" -skipinstall
i tried tinkering around with the script to only have it download the packages
i am getting these errors
i didn't got these errors in the earlier version of the script