Update-InboxApp.ps1
<#PSScriptInfo
.VERSION 1.0 .GUID 71904827-7092-4941-9a1f-32c207e65075 .AUTHOR Michael Niehaus .COMPANYNAME .COPYRIGHT .TAGS Windows .LICENSEURI https://github.com/mtniehaus/Update-InboxApp/LICENSE .PROJECTURI https://github.com/mtniehaus/Update-InboxApp .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES v1.0.0 - Initial version #> <# .SYNOPSIS This script will tell Windows to update one or more in-box apps, using the available UWP APIs for doing this. .DESCRIPTION This script will tell Windows to update one or more in-box apps, using the available UWP APIs for doing this. .PARAMETER PackageFamilyName One or more app IDs that should be updated (e.g. "Microsoft.DesktopAppInstaller_8wekyb3d8bbwe") .EXAMPLE .\Update-InboxApp.ps1 -PackageFamilyName Microsoft.DesktopAppInstaller_8wekyb3d8bbwe .EXAMPLE Get-AppxPackage | .\Update-InboxApp.ps1 .NOTES See https://oofhours.com for more information. #> [CmdletBinding()] param( [Parameter(Mandatory = $False, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True, Position = 0)] [String[]] $PackageFamilyName ) Begin { Add-Type -AssemblyName System.Runtime.WindowsRuntime $asTaskGeneric = ([System.WindowsRuntimeSystemExtensions].GetMethods() | ? { $_.Name -eq 'AsTask' -and $_.GetParameters().Count -eq 1 -and $_.GetParameters()[0].ParameterType.Name -eq 'IAsyncOperation`1' })[0] function Await($WinRtTask, $ResultType) { $asTask = $asTaskGeneric.MakeGenericMethod($ResultType) $netTask = $asTask.Invoke($null, @($WinRtTask)) $netTask.Wait(-1) | Out-Null $netTask.Result } } Process { [Windows.ApplicationModel.Store.Preview.InstallControl.AppInstallManager,Windows.ApplicationModel.Store.Preview,ContentType=WindowsRuntime] | Out-Null $appManager = New-Object -TypeName Windows.ApplicationModel.Store.Preview.InstallControl.AppInstallManager foreach ($app in $PackageFamilyName) { try { Write-Verbose "Requesting an update for $app..." $updateOp = $appManager.UpdateAppByPackageFamilyNameAsync($app) $updateResult = Await $updateOp ([Windows.ApplicationModel.Store.Preview.InstallControl.AppInstallItem]) while ($true) { if ($null -eq $updateResult) { Write-Verbose "No update available for app: $app" break } if ($null -eq $updateResult.GetCurrentStatus()) { Write-Debug "Unxpected: Current status is null." break } Write-Host $updateResult.GetCurrentStatus().PercentComplete if ($updateResult.GetCurrentStatus().PercentComplete -eq 100) { Write-Verbose "App update completed: $app" break } Start-Sleep -Seconds 3 } } catch [System.AggregateException] { # If the thing is not installed, we can't update it. In this case, we get an # ArgumentException with the message "Value does not fall within the expected # range." I cannot figure out why *that* is the error in the case of "app is # not installed"... perhaps we could be doing something different/better, but # I'm happy to just let this slide for now. $problem = $_.Exception.InnerException # we'll just take the first one if ($problem.GetType() -eq [System.IO.FileNotFoundException]) { Write-Warning "App is not available on the Microsoft Store: $app" } else { Write-Warning "Error updating app $app (perhaps it is not installed): $problem" } } catch { Write-Warning "Unexpected error updating app $app : $_" } } } |