Es una herramienta muy útil en particular para quien (como yo) tenga completamente capada la Microsoft Store y sus funcionalidades en el sistema operativo, y necesite una forma de poder instalar paquetes de aplicaciones (*.appx, *.appxbundle, *.msixbundle) descargadas de forma local desde la Microsoft Store.
Código
# --------------------------------------------- # # Automated AppX Package Installer - by Elektro # # --------------------------------------------- # # This script will find any AppX package files within the current directory (without recursion), # print info about the package, print a message in case of the package is already installed, # and install the package in case of it is not installed, handling errors during installation. # --------------------------------------------------------------------- # Takes a string argument that points to an AppX package name or file, # then it uses a regular expression to match the package string pattern # and returns a custom object with the Name, Version, Architecture, # PublisherId and other properties. # # Parameters: # -PackageString: A string that points to the file name # or full path of an AppX package file. # # Returns: # A PSCustomObject object with these properties defined: # [String] Name # [String] Version # [String] Architecture # [String] PublisherId # [String] FullName function Get-AppXPackageInfo { param ( [Parameter(Mandatory=$true)] [string]$PackageString ) #$dirname = [System.IO.Path]::GetDirectoryName($PackageString) #if ([string]::IsNullOrEmpty($dirname)) { # $dirname = $PWD #} $filename = [System.IO.Path]::GetFileName($PackageString) -replace "(?i)\.appxbundle$", "" -replace "(?i)\.msixbundle$", "" -replace "(?i)\.appx$", "" $regex = '^(?<Name>.+?)_(?<Version>.+?)_(?<Architecture>.+?)_(?<chars>~)?_(?<PublisherId>.+)$' $match = $filename -match $regex if (!$match) { throw "Unable to parse the string package: '$PackageString'" } [string]$packageName = $matches['Name'] [string]$packageVersion = $matches['Version'] [string]$packageArchitecture = $matches['Architecture'] [string]$packagePublisherId = $matches['PublisherId'] [string]$chars = $matches['chars'] [string]$packageFullName = "${packageName}_${packageVersion}_${packageArchitecture}_${chars}_${packagePublisherId}" #[string]$packageFullPath = [System.IO.Path]::Combine($dirname, "$filename.Appx") [PSCustomObject]@{ Name = $packageName Version = $packageVersion Architecture = $packageArchitecture PublisherId = $packagePublisherId FullName = $packageFullName #FullPath = $packageFullPath } } # Determines whether an Appx package matching the specified # name, version and architecture is installed in the system. # # Parameters: # -Name........: The package name. # -Version.....: The package version. # -Architecture: The package architecture ("x86", "x64"). # # Returns: # $true if the AppX package is installed in the system, # $false otherwise. function IsAppxPackageInstalled() { param ( [Parameter(Mandatory=$true)] [string]$name, [Parameter(Mandatory=$true)] [string]$version, [Parameter(Mandatory=$true)] [string]$architecture ) if ($architecture -eq "neutral") { $architecture = [System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture } $packages = Get-AppxPackage "$($name)*" -ErrorAction Stop | Where-Object { $_.Name.ToLower() -eq $name.ToLower() -and $_.Version.ToLower() -eq $version.ToLower() -and "$($_.Architecture)".ToLower() -eq $architecture.ToLower() } return ($packages.Count -gt 0) } <# =========================================================================================== | | | Main | | | =========================================================================================== #> [System.Console]::Title = "Automated AppX Package Installer - by Elektro" [CultureInfo]::CurrentUICulture = "en-US" try { Set-ExecutionPolicy -ExecutionPolicy "Unrestricted" -Scope "Process" } catch { } # Hides the progress-bar for 'Add-AppxPackage' cmdlet in this script. # Thanks to @Santiago Squarzon for the tip: https://stackoverflow.com/questions/75716867 # https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables?view=powershell-7.3#progresspreference $ProgressPreference = "Ignore" Do { Clear-Host Write-Output "" Write-Output " $($host.ui.RawUI.WindowTitle)" Write-Output " +=====================================================+" Write-Output " | |" Write-Output " | This script will find any AppX package files |" Write-Output " | within the current directory (without recursion), |" Write-Output " | print info about the package, print a message |" Write-Output " | in case of the package is already installed, |" Write-Output " | and install the package in case of it is |" Write-Output " | not installed, handling errors during installation. |" Write-Output " | |" Write-Output " +=====================================================+" Write-Output "" Write-Host " -Continue? (Y/N)" $key = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") $char = $key.Character.ToString().ToUpper() if ($char -ne "Y" -and $char -ne "N") { [console]::beep(1500, 500) } } while ($char -ne "Y" -and $char -ne "N") if ($char -eq "N") {Exit(1)} else {Clear-Host} $appxFiles = Get-ChildItem -Path "$PWD" -Filter "*.appx*" if ($appxFiles.Count -eq 0) { Write-Warning "No Appx files were found in the current directory." Write-Host "" $LastExitCode = 2 } else { $appxFiles | ForEach-Object { # The AppX package string. It can be a file name (with or without extension), or a full path. $packageString = $_.FullName $packageInfo = Get-AppXPackageInfo -PackageString $packageString $nameVerArch = "$($packageInfo.Name) v$($packageInfo.Version) ($($packageInfo.Architecture))" Write-Host "Package Info.:" -ForegroundColor Gray Write-Host ($packageInfo | Format-List | Out-String).Trim() -ForegroundColor DarkGray Write-Host "" $isInstalled = IsAppxPackageInstalled -Name $packageInfo.Name -Version $packageInfo.Version -Architecture $packageInfo.Architecture if ($isInstalled) { Write-Warning "Package $nameVerArch is already installed." Write-Warning "Installation is not needed." } else { Write-Host "Package $nameVerArch is ready to install." Write-Host "Installing package..." try { Add-AppxPackage -Path "$($_.FullName)" -ErrorAction Stop Write-Host "Package $nameVerArch has been successfully installed." -BackgroundColor Black -ForegroundColor Green } catch { Write-Host "Error installing package $nameVerArch" -BackgroundColor Black -ForegroundColor Red Write-Host "" Write-Error -Message ($_.Exception | Format-List * -Force | Out-String) $LastExitCode = 1 Break } } Write-Host "" $LastExitCode = 0 } } Write-Host "Program will terminate now with exit code $LastExitCode. Press any key to exit..." $key = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") Exit($LastExitCode)