How to Install Windows Store Apps via PowerShell: A Scriptable Approach for HEIF Extensions and More


1 views

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:

  1. Starting Fiddler or similar network capture tool
  2. Initiating download via Microsoft Store UI
  3. Capturing the package URL from network traffic
  4. 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