While traditional desktop applications can be easily installed via PowerShell using MSI or EXE installers, Windows Store apps present a unique challenge. The standard Add-AppxPackage
cmdlet requires the physical .appx
or .msix
file, but obtaining these packages directly isn't straightforward.
The common workaround involves:
- Starting Fiddler or similar network capture tool
- Initiating download via Microsoft Store UI
- Capturing the package URL from network traffic
- Manually downloading the file
This method is not only tedious but also unreliable for automation scenarios.
Here's a robust approach combining Winget (Windows Package Manager) and direct Store API calls:
# First, install Winget if not present
if (-not (Get-Command winget -ErrorAction SilentlyContinue)) {
$progressPreference = 'silentlyContinue'
Invoke-WebRequest -Uri https://aka.ms/getwinget -OutFile Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle
Add-AppxPackage -Path Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle
}
# Install HEIF Image Extensions via Winget
winget install Microsoft.HEIFImageExtension --source msstore --accept-package-agreements
# Alternative method using Store REST API
$appx = Invoke-RestMethod -Uri "https://store.rg-adguard.net/api/GetFiles" -Method Post -Body @{
type = "ProductId"
url = "9PMMSR1CGPWG" # Product ID for HEIF Image Extensions
ring = "Retail"
lang = "en-US"
} | Select-Object -ExpandProperty links | Where-Object { $_.url -like "*.appx*" }
Invoke-WebRequest -Uri $appx.url -OutFile HEIFExtensions.appx
Add-AppxPackage -Path HEIFExtensions.appx
Many Store apps have framework dependencies. This script handles them:
# Get all framework dependencies for an app
$dependencies = Get-AppxPackage -Name Microsoft.HEVCVideoExtension | Select-Object -ExpandProperty Dependencies
foreach ($dep in $dependencies) {
$depPackage = Get-AppxPackage -Name $dep.Name
if (-not $depPackage) {
$depUrl = "https://store.rg-adguard.net/api/GetFiles" # API call to get dependency
# Download and install dependency
# ... (implementation similar to above)
}
}
For mass deployment, consider these additional techniques:
- Use
Export-AppxPackage
to create provisioning packages - Leverage Windows Configuration Designer for offline installation
- Implement AppLocker rules for managed environments
After installation, verify with:
Get-AppxPackage -Name *HEIF* | Select-Object Name, Version, InstallLocation
For HEIC file association verification:
Get-ChildItem -Path $env:USERPROFILE\Pictures -Filter *.heic | Select-Object -First 1 | Should -Not -BeNullOrEmpty
Managing Windows Store applications through PowerShell presents unique challenges compared to traditional Win32 applications. While Add-AppxPackage
works well for local .appx
files, there's no native cmdlet to directly download and install Store apps by their package name.
Here are three robust methods to install Store apps programmatically:
Method 1: Using Get-AppxPackage with Winget
The Windows Package Manager (winget) now provides a cleaner alternative:
# First install winget if not available
Install-Module -Name Microsoft.WinGet.Client -Force
# Search for the package
$app = Get-WinGetPackage -Name "HEIF Image Extensions" -Exact
# Install the package
Install-WinGetPackage -Id $app.Id
Method 2: PowerShell with Microsoft Store REST API
For more control, you can query the Store API directly:
# Get product ID from Microsoft Store URL
$productId = "9PMMSR1CGPWG" # HEIF Image Extensions ID
# Download using Store REST API
$url = "https://store.rg-adguard.net/api/GetFiles"
$body = @{
type = "ProductId"
url = $productId
ring = "Retail"
lang = "en-US"
} | ConvertTo-Json
$response = Invoke-RestMethod -Uri $url -Method Post -Body $body -ContentType "application/json"
$downloadUrl = ($response | Where-Object {$_.Name -like "*.appx*"}).Uri
Invoke-WebRequest -Uri $downloadUrl -OutFile "package.appx"
Add-AppxPackage -Path "package.appx"
Method 3: Using Windows Update API
For system components distributed through Store:
# Register the package manager
$session = New-Object -ComObject Microsoft.Update.Session
$searcher = $session.CreateUpdateSearcher()
# Search for available updates
$updates = $searcher.Search("IsInstalled=0 and Type='Software'").Updates
# Find and install specific package
$target = $updates | Where-Object {$_.Title -like "*HEVC*"}
if ($target) {
$downloader = $session.CreateUpdateDownloader()
$downloader.Updates = $target
$downloader.Download()
$installer = $session.CreateUpdateInstaller()
$installer.Updates = $target
$installer.Install()
}
Store apps often require framework packages. This script handles dependencies automatically:
function Install-StoreApp {
param(
[string]$PackageName,
[string]$Publisher = "CN=Microsoft Corporation"
)
$package = Get-AppxPackage | Where-Object {
$_.Name -eq $PackageName -and
$_.Publisher -eq $Publisher
}
if (-not $package) {
$deps = Find-AppxPackageDependencies -PackageName $PackageName
$deps | ForEach-Object {
Install-StoreApp -PackageName $_.Name -Publisher $_.Publisher
}
$productId = Get-StoreProductId -PackageName $PackageName
winget install --id $productId --exact --silent
}
}
For system administrators managing multiple machines:
# Create provisioning package
$manifest = @"
<?xml version="1.0" encoding="utf-8"?>
<Packages>
<Package
xmlns="http://schemas.microsoft.com/appx/2010/manifest"
Publisher="CN=Microsoft Corporation"
Name="Microsoft.HEVCVideoExtension"
ProcessorArchitecture="x64"
Version="1.0.0.0">
</Package>
</Packages>
"@
$manifest | Out-File "hevc.xml"
Export-WindowsDeveloperLicense -Force
Install-ProvisioningPackage -PackagePath .\hevc.xml -ForceInstall