Repair Appx V3
Repair Appx V3
Repair Appx V3
com
# AppX tool intendeed for troubleshooting purposes only
# This tool is provided AS IS, no support nor warranty of any kind is provided for
its usage.
param (
[string]$package,
[string]$action = "repair",
[switch]$force = $false,
[switch]$verbose = $false,
[switch]$no_download = $false,
[switch]$no_change = $false,
[switch]$no_deps = $false
)
$VERSION = "v1.81"
$SLEEP_DELAY = 1000
$global:mainPFNs = @()
$global:userRights = $false
$global:canInstallForAllUsers = $false
$global:allUsersSwitch = "-AllUsers"
$global:repairSucceeded = $false
[Windows.Management.Deployment.PackageManager,Windows.Management.Deployment,Content
Type=WindowsRuntime] | Out-Null
[Windows.ApplicationModel.Store.Preview.InstallControl.AppInstallManager,Windows.Ap
plicationModel.Store.Preview.InstallControl,ContentType=WindowsRuntime] | Out-Null
Add-Type -AssemblyName System.Runtime.WindowsRuntime
$asTaskGeneric = ([System.WindowsRuntimeSystemExtensions].GetMethods() | Where-
Object { $_.Name -eq 'AsTask' -and $_.GetParameters().Count -eq 1 -and
$_.GetParameters()[0].ParameterType.Name -eq 'IAsyncOperation`1' })[0]
"Couldn't look for apps update, check connectivity to the Microsoft Store."
" Exception Type: $($_.Exception.GetType().FullName)"
" Exception Message: $($_.Exception.Message)"
""
$host.ui.RawUI.ForegroundColor = $savedForegroundColor
$host.ui.RawUI.BackgroundColor = $savedBackgroundColor
}
}
function ShowUsage()
{
"USAGE:"
"------"
" .\RepairAppx.ps1 -action <Action> <PACKAGE_NAME>"
""
""
"EXAMPLE:"
"--------"
" Repair Microsoft Photo app:"
" .\RepairAppx.ps1 *Photo*"
""
" Look for packages binaries corruption:"
" .\RepairAppx.ps1 -action verify *ExperiencePack*"
""
" Set Calc and its dependencies to modified appmodel state"
" .\RepairAppx.ps1 -action setstate *Calc*"
""
" List packages that depepnd on .NET Native framework 2.2"
" .\RepairAppx.ps1 -action depends *NET.Native.Runtime.2.2"
""
"PARAMETERS:"
"-----------"
" -action <Action>"
" repair - [Default] Try to repair app package(s) and their dependencies
by downloading them again"
" register - Registers app package(s) and dependencies for the current
user but doesn't repair files"
" verify - Verify package(s) consistency by comparing the on-disk files
with package declaration"
""
" setstate - Sets package(s) and dependencies to modified state, to
prepare downloaing them again"
" resetstate - Clears the modified state of package(s) and dependencies to
get back to normal state"
""
" config - Shows config settings related to AppStore, GPO and Windows
Update"
" depends - List dependees and dependencies of specified main package(s)
or framework(s)"
""
" queue - List active items in the download queue"
" cancel - Cancels the inprogress download queue"
function CheckConfig()
{
"Checking Store and Windows Update configuration:"
"------------------------------------------------"
$privatestore = $false
$nostoreaccess = $false
""
try {
$val = $appInstallManager.AutoUpdateSetting
}
catch {
$val = "N/A"
}
" - AutoUpdateSetting `t`t`t`t`t $val"
try {
if (Await
($appInstallManager.IsStoreBlockedByPolicyAsync("Microsoft.WindowsStore",
"CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington,
C=US")) ([bool]))
{
$nostoreaccess = true
$val = "blocked"
}
else {
$val = "NOT blocked"
}
}
catch {
$val = "N/A"
}
" - IsStoreBlockedByPolicy`t`t`t`t $val"
""
" Group Policies:"
$key = "RemoveWindowsStore"
$val = (Get-ItemProperty -Path HKLM:\Software\Policies\Microsoft\WindowsStore\
-Name $key -ErrorAction SilentlyContinue).$key
if ($val) {$msg = " - $key `t`t`t`t is set to $($val) in HKLM"} else {$msg = "
- $key `t`t`t`t is not set in HKLM"}
$val = (Get-ItemProperty -Path HKCU:\Software\Policies\Microsoft\WindowsStore\
-Name $key -ErrorAction SilentlyContinue).$key
if ($val) {$msg += "`t and is set to $($val) in HKCU"} else {$msg += "`t and is
not set in HKCU"}
"$msg"
$key = "RequirePrivateStoreOnly"
$val = (Get-ItemProperty -Path HKLM:\Software\Policies\Microsoft\WindowsStore\
-Name $key -ErrorAction SilentlyContinue).$key
if ($val) {$msg = " - $key `t`t`t`t is set to $($val) in HKLM"; $privatestore =
$true} else {$msg = " - $key `t`t`t`t is not set in HKLM"}
$val = (Get-ItemProperty -Path HKCU:\Software\Policies\Microsoft\WindowsStore\
-Name $key -ErrorAction SilentlyContinue).$key
if ($val) {$msg += "`t and is set to $($val) in HKCU"; $privatestore = $true}
else {$msg += "`t and is not set in HKCU"}
"$msg"
$key = "DisableStoreApps"
$val = (Get-ItemProperty -Path HKLM:\Software\Policies\Microsoft\WindowsStore\
-Name $key -ErrorAction SilentlyContinue).$key
if ($val) {$msg = " - $key `t`t`t`t`t is set to $($val) in HKLM"; $privatestore
= $true} else {$msg = " - $key `t`t`t`t`t is not set in HKLM"}
$val = (Get-ItemProperty -Path HKCU:\Software\Policies\Microsoft\WindowsStore\
-Name $key -ErrorAction SilentlyContinue).$key
if ($val) {$msg += "`t and is set to $($val) in HKCU"; $privatestore = $true}
else {$msg += "`t and is not set in HKCU"}
"$msg"
$key = "NoUseStoreOpenWith"
$val = (Get-ItemProperty -Path
HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer\ -Name $key -ErrorAction
SilentlyContinue).$key
if ($val) {$msg = " - $key `t`t`t`t is set to $($val) in HKLM"} else {$msg = "
- $key `t`t`t`t is not set in HKLM"}
$val = (Get-ItemProperty -Path
HKCU:\SOFTWARE\Policies\Microsoft\Windows\Explorer\ -Name $key -ErrorAction
SilentlyContinue).$key
if ($val) {$msg += "`t and is set to $($val) in HKCU"} else {$msg += "`t and is
not set in HKCU"}
"$msg"
$key = "AutoDownload"
$val = (Get-ItemProperty -Path HKLM:\Software\Policies\Microsoft\WindowsStore\
-Name $key -ErrorAction SilentlyContinue).$key
if ($val) {$msg = " - $key `t`t`t`t `t is set to $($val) in HKLM"} else {$msg =
" - $key `t`t`t`t`t is not set in HKLM"}
$val = (Get-ItemProperty -Path HKCU:\Software\Policies\Microsoft\WindowsStore\
-Name $key -ErrorAction SilentlyContinue).$key
if ($val) {$msg += "`t and is set to $($val) in HKCU"} else {$msg += "`t and is
not set in HKCU"}
"$msg"
$key = "SetDisableUXWUAccess"
$val = (Get-ItemProperty -Path HKLM:\Software\Policies\Microsoft\WindowsStore\
-Name $key -ErrorAction SilentlyContinue).$key
if ($val) {$msg = " - $key `t`t`t`t is set to $($val) in HKLM"} else {$msg = "
- $key `t`t`t`t is not set in HKLM"}
$val = (Get-ItemProperty -Path HKCU:\Software\Policies\Microsoft\WindowsStore\
-Name $key -ErrorAction SilentlyContinue).$key
if ($val) {$msg += "`t`t and is set to $($val) in HKCU"} else {$msg += "`t and is
not set in HKCU"}
"$msg"
$key = "DoNotConnectToWindowsUpdateInternetLocations"
$val = (Get-ItemProperty -Path HKLM:\Software\Policies\Microsoft\WindowsStore\
-Name $key -ErrorAction SilentlyContinue).$key
if ($val) {$msg = " - $key`t is set to $($val) in HKLM"; $nostoreaccess = true}
else {$msg = " - $key`t is not set in HKLM"}
$val = (Get-ItemProperty -Path HKCU:\Software\Policies\Microsoft\WindowsStore\
-Name $key -ErrorAction SilentlyContinue).$key
if ($val) {$msg += "`t`t and is set to $($val) in HKCU"; $nostoreaccess = true}
else {$msg += "`t and is not set in HKCU"}
"$msg"
""
if ($privatestore) { "WARNING: You use the private store, please ensure you have
added the apps there for the repair to work."; "" }
if ($nostoreaccess) { "WARNING: Your settings block Windows Update from accessing
internet, the script will likely not be able to re-download apps and fix file
corruptions."; "" }
}
function CleanupUpdateQueue()
{
$queuedApps = $appInstallManager.AppInstallItems
function ListUpdateQueue()
{
$queuedApps = $appInstallManager.AppInstallItems
function SetPackageToModifiedState()
{
$packages = Invoke-Expression "Get-AppXPackage $global:allUsersSwitch
-PackageTypeFilter Main $package"
$packageManager = New-Object Windows.Management.Deployment.PackageManager
if ($no_deps)
{
" - [No dependencies processing was requested]"
}
else
{
ForEach ($dependencies in (Get-AppxPackageManifest
$p.PackageFullName).package.dependencies.packagedependency.name)
{
$dep = Invoke-Expression "Get-AppXPackage $global:allUsersSwitch
-PackageTypeFilter Framework $dependencies"
ForEach ($d in $dep)
{
" - " + $d.PackageFullName
$packageManager.SetPackageStatus($d.PackageFullName,
[Windows.Management.Deployment.PackageStatus]::Modified)
}
}
}
}
""
}
function ClearPackageFromModifiedState()
{
$packages = Invoke-Expression "Get-AppXPackage $global:allUsersSwitch
-PackageTypeFilter Main $package"
$packageManager = New-Object Windows.Management.Deployment.PackageManager
if ($no_deps)
{
" - [No dependencies processing was requested]"
}
else
{
ForEach ($dependencies in (Get-AppxPackageManifest
$p.PackageFullName).package.dependencies.packagedependency.name)
{
$dep = Invoke-Expression "Get-AppXPackage $global:allUsersSwitch
-PackageTypeFilter Framework $dependencies"
ForEach ($d in $dep)
{
" - " + $d.PackageFullName
$packageManager.ClearPackageStatus($d.PackageFullName,
[Windows.Management.Deployment.PackageStatus]::Modified)
}
}
}
}
""
}
function RegisterPackageAndDeps()
{
$packages = Invoke-Expression "Get-AppXPackage $global:allUsersSwitch $package"
function SearchForPFNUpdates()
{
$global:ProgressPreference = 'Continue'
$finished = $true
foreach($packageFamilyName in $global:mainPFNs)
{
"Looking for available Apps Store updates:"
"-----------------------------------------"
try
{
$finished = $true
$appinstalls = Await
($appInstallManager.UpdateAppByPackageFamilyNameAsync($packageFamilyName))
([Windows.ApplicationModel.Store.Preview.InstallControl.AppInstallItem])
if ($appinstalls.Length -eq 0)
{
"Package Manager didn't return any package to download for this family
name!"
""
SearchForAllUpdates
}
else
{
foreach($appinstall in $appinstalls)
{
if ($appinstall.PackageFamilyName)
{
try { $appstoreaction = "to " +
([Windows.ApplicationModel.Store.Preview.InstallControl.AppInstallType]
$appinstall.InstallType) } catch { $appstoreaction = "" }
" - Requesting $($appinstall.PackageFamilyName) $appstoreaction"
Start-Sleep -Milliseconds $SLEEP_DELAY
$finished = $false
}
}
""
"Running the update process:"
"---------------------------"
while (!$finished)
{
$finished = $true
for ($index=0; $index -lt $appinstalls.Length; $index++)
{
$appUpdate = $appinstalls[$index]
$packageFamilyName = $appUpdate.PackageFamilyName
$status = $appUpdate.GetCurrentStatus()
$currentstate =
[Windows.ApplicationModel.Store.Preview.InstallControl.AppInstallState]
$status.InstallState
if ($finished)
{
$finished = $false
}
}
}
Start-Sleep -Milliseconds $SLEEP_DELAY
}
for ($index=0; $index -lt $appinstalls.Length; $index++)
{
$appUpdate = $appinstalls[$index]
$packageFamilyName = $appUpdate.PackageFamilyName
$status = $appUpdate.GetCurrentStatus()
$currentstate =
[Windows.ApplicationModel.Store.Preview.InstallControl.AppInstallState]
$status.InstallState
# "Trying to open the Microsoft Store, please check the ongoing downloads
and try to update it there."
# Invoke-Expression "ms-windows-store://pdp/?PFN=$($global:mainPFN)"
""
"Going to reset package status to get back to a normal state"
$host.ui.RawUI.ForegroundColor = $savedForegroundColor
$host.ui.RawUI.BackgroundColor = $savedBackgroundColor
""
}
}
}
function SearchForAllUpdates()
{
$global:ProgressPreference = 'Continue'
$finished = $true
try
{
$appinstalls = Await ($appInstallManager.SearchForAllUpdatesAsync())
([System.Collections.Generic.IReadOnlyList[Windows.ApplicationModel.Store.Preview.I
nstallControl.AppInstallItem]])
if ($appinstalls.Length -eq 0)
{
"Package Manager didn't return any package to download for the machine!"
}
else
{
foreach($appinstall in $appinstalls)
{
if ($appinstall.PackageFamilyName)
{
try { $appstoreaction = "to " +
([Windows.ApplicationModel.Store.Preview.InstallControl.AppInstallType]
$appinstall.InstallType) } catch { $appstoreaction = "" }
" - Requesting $($appinstall.PackageFamilyName) $appstoreaction"
Start-Sleep -Milliseconds $SLEEP_DELAY
$finished = $false
}
}
""
"Running the update process:"
"---------------------------"
while (!$finished)
{
$finished = $true
for ($index=0; $index -lt $appinstalls.Length; $index++)
{
$appUpdate = $appinstalls[$index]
$packageFamilyName = $appUpdate.PackageFamilyName
$status = $appUpdate.GetCurrentStatus()
$currentstate =
[Windows.ApplicationModel.Store.Preview.InstallControl.AppInstallState]
$status.InstallState
if ($finished)
{
$finished = $false
}
}
}
Start-Sleep -Milliseconds $SLEEP_DELAY
}
for ($index=0; $index -lt $appinstalls.Length; $index++)
{
$appUpdate = $appinstalls[$index]
$packageFamilyName = $appUpdate.PackageFamilyName
$status = $appUpdate.GetCurrentStatus()
$currentstate =
[Windows.ApplicationModel.Store.Preview.InstallControl.AppInstallState]
$status.InstallState
if ($status.PercentComplete -eq 100)
{
Write-Progress -Id $index -Activity $packageFamilyName -Status "Completed"
-Completed
" -> $packageFamilyName ended as $currentstate $(if
($status.ReadyForLaunch) {"and reports now to be READY FOR LAUNCH!"} Else {"and is
NOT ready for launch"})"
$global:repairSucceeded = $true
}
elseif ($status.ErrorCode)
{
" -> $packageFamilyName failed with Error $status.ErrorCode /
$currentstate"
Write-Progress -Id $index -Activity $packageFamilyName -Status $msg
-Completed
}
}
""
"The store apps update process ended for $($appinstalls.Length) packages"
""
}
}
catch
{
$savedForegroundColor = $host.ui.RawUI.ForegroundColor
$savedBackgroundColor = $host.ui.RawUI.BackgroundColor
$host.ui.RawUI.ForegroundColor = "Red"
$host.ui.RawUI.BackgroundColor = "Black"
# "Trying to open the Microsoft Store, please check the ongoing downloads and
try to update it there."
# Invoke-Expression "ms-windows-store://pdp/?PFN=$($global:mainPFN)"
""
"Going to reset package status to get back to a normal state"
$host.ui.RawUI.ForegroundColor = $savedForegroundColor
$host.ui.RawUI.BackgroundColor = $savedBackgroundColor
""
}
}
function ReinstallStore()
{
try {
$appinstalls = Await ($appInstallManager.StartAppInstallAsync("9WZDNCRFJBMP",
"", $true, $true))
([Windows.ApplicationModel.Store.Preview.InstallControl.AppInstallItem])
if ($appinstalls.Length -eq 0)
{
"Package Manager didn't return any package to download for this reinstall"
""
}
else
{
foreach($appinstall in $appinstalls)
{
if ($appinstall.PackageFamilyName)
{
try { $appstoreaction = "to " +
([Windows.ApplicationModel.Store.Preview.InstallControl.AppInstallType]
$appinstall.InstallType) } catch { $appstoreaction = "" }
" - Requesting $($appinstall.PackageFamilyName) $appstoreaction"
Start-Sleep -Milliseconds $SLEEP_DELAY
$finished = $false
}
}
""
"Running the update process:"
"---------------------------"
while (!$finished)
{
$finished = $true
for ($index=0; $index -lt $appinstalls.Length; $index++)
{
$appUpdate = $appinstalls[$index]
$packageFamilyName = $appUpdate.PackageFamilyName
$status = $appUpdate.GetCurrentStatus()
$currentstate =
[Windows.ApplicationModel.Store.Preview.InstallControl.AppInstallState]
$status.InstallState
if ($finished)
{
$finished = $false
}
}
}
Start-Sleep -Milliseconds $SLEEP_DELAY
}
for ($index=0; $index -lt $appinstalls.Length; $index++)
{
$appUpdate = $appinstalls[$index]
$packageFamilyName = $appUpdate.PackageFamilyName
$status = $appUpdate.GetCurrentStatus()
$currentstate =
[Windows.ApplicationModel.Store.Preview.InstallControl.AppInstallState]
$status.InstallState
# "Trying to open the Microsoft Store, please check the ongoing downloads
and try to update it there."
# Invoke-Expression "ms-windows-store://pdp/?PFN=$($global:mainPFN)"
""
"Going to reset package status to get back to a normal state"
$host.ui.RawUI.ForegroundColor = $savedForegroundColor
$host.ui.RawUI.BackgroundColor = $savedBackgroundColor
""
}
}
function VerifyPackagesConsistency()
{
"Checking packages consistency:"
"------------------------------"
if (!$package)
{
$package = "*"
}
if ($packagesIndex -eq 0)
{
"==> NO PACKAGE FOUND TO CHECK <=="
"Please review your package name and rerun with -verbose"
}
elseif ($invalidPackages -eq 0)
{
"==> NO ERROR FOUND IN " + $packagesIndex + " PACKAGES CHECKED <=="
}
else
{
""
"!!! $invalidPackages INVALID PACKAGES WERE FOUND IN $packagesIndex PACKAGES
CHECKED !!!"
}
""
}
function LookForDependencies()
{
$dependees = Invoke-Expression "Get-AppXPackage $global:allUsersSwitch $package"
function LookForDependees()
{
$dependencies = Invoke-Expression "Get-AppXPackage $global:allUsersSwitch
$package"
function CheckAdminRights()
{
$isAdmin = $false
try {
$bytes = New-Object -TypeName byte[](4)
$hToken =
([System.ServiceModel.PeerNode].Assembly.GetType('System.ServiceModel.Channels.AppC
ontainerInfo')).GetMethod('GetCurrentProcessToken', $BindingFlags).Invoke($null,
@())
([System.ServiceModel.PeerNode].Assembly.GetType('System.ServiceModel.Activation.Ut
ility')).GetMethod('GetTokenInformation', $BindingFlags).Invoke($null, @($hToken,
18, [byte[]]$bytes))
if ($bytes[0] -eq 1)
{
$GetTokenInformation.Invoke($null, @($hToken, 20, [byte[]]$bytes)) #
TokenElevation
if ($bytes[0]) { $global:userRights = "UAC disabled but token elevated
(Build-in Admin)"; $isAdmin = $true}
else { $global:userRights = "UAC is disabled and not
elevated" }
}
if ($bytes[0] -eq 2) { $global:userRights = "UAC enabled and token elevated
(Run As Admin)"; $isAdmin = $true }
if ($bytes[0] -eq 3) { $global:userRights = "UAC enabled and token NOT
elevated" }
}
catch {
$currentPrincipal = New-Object
Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurren
t())
if
($currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
) {
$global:userRights = "Administrator"
$isAdmin = $true
}
else {
$global:userRights = "NOT Administrator"
}
}
try {
$global:canInstallForAllUsers = $appInstallManager.CanInstallForAllUsers
}
catch {
$global:canInstallForAllUsers = "N/A"
}
finally {
if (($global:canInstallForAllUsers -ne $true) -and (!$isAdmin))
{ $global:allUsersSwitch = ""}
}
}
""
"RepairAppx $VERSION - Repair & troubleshooting tool for AppX packages"
"This tool is provided AS IS, no support nor warranty of any kind is provided for
its usage."
""
$appInstallManager = New-Object
Windows.ApplicationModel.Store.Preview.InstallControl.AppInstallManager
CheckAdminRights
switch ( $action )
{
"config" { CheckConfig; exit }
"verify" { VerifyPackagesConsistency; exit }
"setstate" { SetPackageToModifiedState; exit }
"resetstate" { ClearPackageFromModifiedState; exit }
"depends" { LookForDependencies; LookForDependees; exit }
"queue" { ListUpdateQueue; exit }
"cancel" { CleanupUpdateQueue; exit }
"update" { CheckConfig; SearchForUpdates; exit }
"updateall" { CheckConfig; SearchForAllUpdates; exit }
"register" { RegisterPackageAndDeps; exit }
"repair" {
if (!$package) { ShowUsage; exit }
if (!$no_check) { CheckConfig } else { "No config check
was requested." }
if (!$no_cancel) { CleanupUpdateQueue } else { "No active queue
cleanup was requested." }
if (!$no_change) { SetPackageToModifiedState } else { "No package state
change was requested." }
if (!$no_download) { SearchForPFNUpdates } else { "No package
download was requested." }
if ($force -and !$global:repairSucceeded)
{
$savedForegroundColor = $host.ui.RawUI.ForegroundColor
$savedBackgroundColor = $host.ui.RawUI.BackgroundColor
$host.ui.RawUI.ForegroundColor = "Red"
# $host.ui.RawUI.BackgroundColor = "Black"
New-ItemProperty -Path
"HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\InstallService\State" -Name
"AutoUpdateLastSuccessTime" -Value "2010-01-01 00:00:00" -PropertyType STRING
-Force | Out-Null
New-ItemProperty -Path
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\InstallService\State" -Name
"AutoUpdateLastSuccessTime" -Value "2010-01-01 00:00:00" -PropertyType STRING
-Force | Out-Null
New-ItemProperty -Path
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\InstallService\State" -Name
"HasFrameworkUpdates" -Value 1 -PropertyType DWORD -Force | Out-Null