elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: ¿Eres nuevo? ¿Tienes dudas acerca del funcionamiento de la comunidad? Lee las Reglas Generales


+  Foro de elhacker.net
|-+  Programación
| |-+  Scripting
| | |-+  [APORTE] [PowerShell] Automated AppX Package Installer
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: [APORTE] [PowerShell] Automated AppX Package Installer  (Leído 1,543 veces)
Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.866



Ver Perfil
[APORTE] [PowerShell] Automated AppX Package Installer
« en: 4 Marzo 2024, 15:19 pm »

El siguiente script desarrollado en Powershell, buscará archivos de paquetes AppX (*.appx, *.appxbundle, *.msixbundle) dentro del directorio actual (sin recursividad), imprimirá información sobre el paquete, imprimirá un mensaje en caso de que el paquete ya esté instalado, e instalará el paquete en caso de que no esté instalado, manejando posibles errores durante instalación.

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
  1. # --------------------------------------------- #
  2. # Automated AppX Package Installer - by Elektro #
  3. # --------------------------------------------- #
  4.  
  5. # This script will find any AppX package files within the current directory (without recursion),
  6. # print info about the package, print a message in case of the package is already installed,
  7. # and install the package in case of it is not installed, handling errors during installation.
  8.  
  9. # ---------------------------------------------------------------------
  10.  
  11. # Takes a string argument that points to an AppX package name or file,
  12. # then it uses a regular expression to match the package string pattern
  13. # and returns a custom object with the Name, Version, Architecture,
  14. # PublisherId and other properties.
  15. #
  16. # Parameters:
  17. #   -PackageString: A string that points to the file name
  18. #                   or full path of an AppX package file.
  19. #
  20. # Returns:
  21. #   A PSCustomObject object with these properties defined:
  22. #     [String] Name
  23. #     [String] Version
  24. #     [String] Architecture
  25. #     [String] PublisherId
  26. #     [String] FullName
  27. function Get-AppXPackageInfo {
  28.    param (
  29.        [Parameter(Mandatory=$true)] [string]$PackageString
  30.    )
  31.  
  32.    #$dirname = [System.IO.Path]::GetDirectoryName($PackageString)
  33.    #if ([string]::IsNullOrEmpty($dirname)) {
  34.    #    $dirname = $PWD
  35.    #}
  36.  
  37.    $filename = [System.IO.Path]::GetFileName($PackageString) -replace "(?i)\.appxbundle$", "" -replace "(?i)\.msixbundle$", "" -replace "(?i)\.appx$", ""
  38.  
  39.    $regex = '^(?<Name>.+?)_(?<Version>.+?)_(?<Architecture>.+?)_(?<chars>~)?_(?<PublisherId>.+)$'
  40.    $match = $filename -match $regex
  41.  
  42.    if (!$match) {
  43.        throw "Unable to parse the string package: '$PackageString'"
  44.    }
  45.  
  46.    [string]$packageName         = $matches['Name']
  47.    [string]$packageVersion      = $matches['Version']
  48.    [string]$packageArchitecture = $matches['Architecture']
  49.    [string]$packagePublisherId  = $matches['PublisherId']
  50.    [string]$chars               = $matches['chars']
  51.    [string]$packageFullName     = "${packageName}_${packageVersion}_${packageArchitecture}_${chars}_${packagePublisherId}"
  52.    #[string]$packageFullPath    = [System.IO.Path]::Combine($dirname, "$filename.Appx")
  53.  
  54.    [PSCustomObject]@{
  55.        Name = $packageName
  56.        Version = $packageVersion
  57.        Architecture = $packageArchitecture
  58.        PublisherId = $packagePublisherId
  59.        FullName = $packageFullName
  60.        #FullPath = $packageFullPath
  61.    }
  62. }
  63.  
  64. # Determines whether an Appx package matching the specified
  65. # name, version and architecture is installed in the system.
  66. #
  67. # Parameters:
  68. #   -Name........: The package name.
  69. #   -Version.....: The package version.
  70. #   -Architecture: The package architecture ("x86", "x64").
  71. #
  72. # Returns:
  73. #   $true if the AppX package is installed in the system,
  74. #   $false otherwise.
  75. function IsAppxPackageInstalled() {
  76.    param (
  77.        [Parameter(Mandatory=$true)] [string]$name,
  78.        [Parameter(Mandatory=$true)] [string]$version,
  79.        [Parameter(Mandatory=$true)] [string]$architecture
  80.    )
  81.  
  82.    if ($architecture -eq "neutral") {
  83.        $architecture = [System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture
  84.    }
  85.  
  86.    $packages = Get-AppxPackage "$($name)*" -ErrorAction Stop | Where-Object {
  87.        $_.Name.ToLower()              -eq $name.ToLower()         -and
  88.        $_.Version.ToLower()           -eq $version.ToLower()      -and
  89.        "$($_.Architecture)".ToLower() -eq $architecture.ToLower()
  90.    }
  91.    return ($packages.Count -gt 0)
  92. }
  93.  
  94. <#
  95. ===========================================================================================
  96. |                                                                                         |
  97. |                                         Main                                            |
  98. |                                                                                         |
  99. ===========================================================================================
  100. #>
  101.  
  102. [System.Console]::Title = "Automated AppX Package Installer - by Elektro"
  103. [CultureInfo]::CurrentUICulture = "en-US"
  104.  
  105. try { Set-ExecutionPolicy -ExecutionPolicy "Unrestricted" -Scope "Process" } catch { }
  106.  
  107. # Hides the progress-bar for 'Add-AppxPackage' cmdlet in this script.
  108. # Thanks to @Santiago Squarzon for the tip: https://stackoverflow.com/questions/75716867
  109. # https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables?view=powershell-7.3#progresspreference
  110. $ProgressPreference = "Ignore"
  111.  
  112. Do {
  113.    Clear-Host
  114.    Write-Output ""
  115.    Write-Output " $($host.ui.RawUI.WindowTitle)"
  116.    Write-Output " +=====================================================+"
  117.    Write-Output " |                                                     |"
  118.    Write-Output " | This script will find any AppX package files        |"
  119.    Write-Output " | within the current directory (without recursion),   |"
  120.    Write-Output " | print info about the package, print a message       |"
  121.    Write-Output " | in case of the package is already installed,        |"
  122.    Write-Output " | and install the package in case of it is            |"
  123.    Write-Output " | not installed, handling errors during installation. |"
  124.    Write-Output " |                                                     |"
  125.    Write-Output " +=====================================================+"
  126.    Write-Output ""
  127.    Write-Host " -Continue? (Y/N)"
  128.    $key = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
  129.    $char = $key.Character.ToString().ToUpper()
  130.    if ($char -ne "Y" -and $char -ne "N") {
  131.        [console]::beep(1500, 500)
  132.    }
  133. } while ($char -ne "Y" -and $char -ne "N")
  134. if ($char -eq "N") {Exit(1)} else {Clear-Host}
  135.  
  136. $appxFiles = Get-ChildItem -Path "$PWD" -Filter "*.appx*"
  137.  
  138. if ($appxFiles.Count -eq 0) {
  139.    Write-Warning "No Appx files were found in the current directory."
  140.    Write-Host ""
  141.    $LastExitCode = 2
  142. } else {
  143.    $appxFiles | ForEach-Object {
  144.        # The AppX package string. It can be a file name (with or without extension), or a full path.
  145.        $packageString = $_.FullName
  146.        $packageInfo = Get-AppXPackageInfo -PackageString $packageString
  147.        $nameVerArch = "$($packageInfo.Name) v$($packageInfo.Version) ($($packageInfo.Architecture))"
  148.        Write-Host "Package Info.:" -ForegroundColor Gray
  149.        Write-Host ($packageInfo | Format-List | Out-String).Trim() -ForegroundColor DarkGray
  150.        Write-Host ""
  151.  
  152.        $isInstalled = IsAppxPackageInstalled -Name $packageInfo.Name -Version $packageInfo.Version -Architecture $packageInfo.Architecture
  153.        if ($isInstalled) {
  154.            Write-Warning "Package $nameVerArch is already installed."
  155.            Write-Warning "Installation is not needed."
  156.        } else {
  157.            Write-Host "Package $nameVerArch is ready to install."
  158.            Write-Host "Installing package..."
  159.            try {
  160.                Add-AppxPackage -Path "$($_.FullName)" -ErrorAction Stop
  161.                Write-Host "Package $nameVerArch has been successfully installed." -BackgroundColor Black -ForegroundColor Green
  162.            } catch {
  163.                Write-Host "Error installing package $nameVerArch" -BackgroundColor Black -ForegroundColor Red
  164.                Write-Host ""
  165.                Write-Error -Message ($_.Exception | Format-List * -Force | Out-String)
  166.                $LastExitCode = 1
  167.                Break
  168.            }
  169.        }
  170.        Write-Host ""
  171.        $LastExitCode = 0
  172.    }
  173. }
  174.  
  175. Write-Host "Program will terminate now with exit code $LastExitCode. Press any key to exit..."
  176. $key = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
  177. Exit($LastExitCode)


« Última modificación: 4 Marzo 2024, 15:20 pm por Eleкtro » En línea



Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.866



Ver Perfil
Re: [APORTE] [PowerShell] Automated AppX Package Installer
« Respuesta #1 en: 5 Abril 2024, 00:13 am »

Una captura de pantalla:



Y una pequeña revisión del código:

Código
  1. # --------------------------------------------- #
  2. # Automated AppX Package Installer - by Elektro #
  3. # --------------------------------------------- #
  4.  
  5. # This script will find any AppX package files within the current directory (without recursion),
  6. # print info about the package, print a message in case of the package is already installed,
  7. # and install the package in case of it is not installed, handling errors during installation.
  8.  
  9. # ---------------------------------------------------------------------
  10.  
  11. # Takes a string argument that points to an AppX package name or file,
  12. # then it uses a regular expression to match the package string pattern
  13. # and returns a custom object with the Name, Version, Architecture,
  14. # PublisherId and other properties.
  15. #
  16. # Parameters:
  17. #   -PackageString: A string that points to the file name
  18. #                   or full path of an AppX package file.
  19. #
  20. # Returns:
  21. #   A PSCustomObject object with these properties defined:
  22. #     [String] Name
  23. #     [String] Version
  24. #     [String] Architecture
  25. #     [String] PublisherId
  26. #     [String] FullName
  27. function Get-AppXPackageInfo {
  28.    param (
  29.        [Parameter(Mandatory=$true)] [string]$PackageString
  30.    )
  31.  
  32.    #$dirname = [System.IO.Path]::GetDirectoryName($PackageString)
  33.    #if ([string]::IsNullOrEmpty($dirname)) {
  34.    #    $dirname = $PWD
  35.    #}
  36.  
  37.    $filename = [System.IO.Path]::GetFileName($PackageString) -replace "(?i)\.appxbundle$", "" -replace "(?i)\.msixbundle$", "" -replace "(?i)\.appx$", ""
  38.    $fileExt  = [System.IO.Path]::GetExtension($PackageString)
  39.  
  40.    $regex = '^(?<Name>.+?)_(?<Version>.+?)_(?<Architecture>.+?)_(?<chars>~)?_(?<PublisherId>.+)$'
  41.    $match = $filename -match $regex
  42.  
  43.    if (!$match) {
  44.        throw "Unable to parse the string package: '$PackageString'"
  45.    }
  46.  
  47.    [string]$packageName         = $matches['Name']
  48.    [string]$packageVersion      = $matches['Version']
  49.    [string]$packageArchitecture = $matches['Architecture']
  50.    [string]$packagePublisherId  = $matches['PublisherId']
  51.    [string]$chars               = $matches['chars']
  52.    [string]$packageFullName     = "${packageName}_${packageVersion}_${packageArchitecture}_${chars}_${packagePublisherId}$fileExt"
  53.    #[string]$packageFullPath    = [System.IO.Path]::Combine($dirname, "$filename$fileExt")
  54.  
  55.    [PSCustomObject]@{
  56.        Name = $packageName
  57.        Version = $packageVersion
  58.        Architecture = $packageArchitecture
  59.        PublisherId = $packagePublisherId
  60.        FullName = $packageFullName
  61.        #FullPath = $packageFullPath
  62.    }
  63. }
  64.  
  65. # Determines whether an Appx package matching the specified
  66. # name, version and architecture is installed in the system.
  67. #
  68. # Parameters:
  69. #   -Name........: The package name.
  70. #   -Version.....: The package version.
  71. #   -Architecture: The package architecture ("x86", "x64").
  72. #
  73. # Returns:
  74. #   $true if the AppX package is installed in the system,
  75. #   $false otherwise.
  76. function IsAppxPackageInstalled() {
  77.    param (
  78.        [Parameter(Mandatory=$true)] [string]$name,
  79.        [Parameter(Mandatory=$true)] [string]$version,
  80.        [Parameter(Mandatory=$true)] [string]$architecture
  81.    )
  82.  
  83.    if ($architecture -match "neutral") {
  84.        $architecture = [System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture
  85.    }
  86.  
  87.    $packages = Get-AppxPackage "$($name)*" -ErrorAction Stop | Where-Object {
  88.        $_.Name.ToLower()              -eq $name.ToLower()         -and
  89.        $_.Version.ToLower()           -eq $version.ToLower()      -and
  90.        "$($_.Architecture)".ToLower() -eq $architecture.ToLower()
  91.    }
  92.    return ($packages.Count -gt 0)
  93. }
  94.  
  95. <#
  96. ===========================================================================================
  97. |                                                                                         |
  98. |                                         Main                                            |
  99. |                                                                                         |
  100. ===========================================================================================
  101. #>
  102.  
  103. [System.Console]::Title = "Automated AppX Package Installer - by Elektro"
  104. [CultureInfo]::CurrentUICulture = "en-US"
  105.  
  106. try { Set-ExecutionPolicy -ExecutionPolicy "Unrestricted" -Scope "Process" } catch { }
  107.  
  108. # Hides the progress-bar for 'Add-AppxPackage' cmdlet in this script.
  109. # Thanks to @Santiago Squarzon for the tip: https://stackoverflow.com/questions/75716867
  110. # https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables?view=powershell-7.3#progresspreference
  111. $ProgressPreference = "Ignore"
  112.  
  113. Do {
  114.    Clear-Host
  115.    Write-Output ""
  116.    Write-Output " $($host.ui.RawUI.WindowTitle)"
  117.    Write-Output " +=====================================================+"
  118.    Write-Output " |                                                     |"
  119.    Write-Output " | This script will find any AppX package files        |"
  120.    Write-Output " | within the current directory (without recursion),   |"
  121.    Write-Output " | print info about the package, print a message       |"
  122.    Write-Output " | in case of the package is already installed,        |"
  123.    Write-Output " | and install the package in case of it is            |"
  124.    Write-Output " | not installed, handling errors during installation. |"
  125.    Write-Output " |                                                     |"
  126.    Write-Output " +=====================================================+"
  127.    Write-Output ""
  128.    Write-Host " -Continue? (Y/N)"
  129.    $key = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
  130.    $char = $key.Character.ToString().ToUpper()
  131.    if ($char -ne "Y" -and $char -ne "N") {
  132.        [console]::beep(1500, 500)
  133.    }
  134. } while ($char -ne "Y" -and $char -ne "N")
  135. if ($char -eq "N") {Exit(1)} else {Clear-Host}
  136.  
  137. $appxFiles = Get-ChildItem -LiteralPath "$PSScriptRoot" -Filter "*.*" -File | Where-Object { $_.Extension -match "appx" -or $_.Extension -match "appxbundle" -or $_.Extension -match "msixbundle"}
  138.  
  139. if ($appxFiles.Count -eq 0) {
  140.    Write-Warning "No Appx files were found in the current directory."
  141.    Write-Host ""
  142.    $LastExitCode = 2
  143. } else {
  144.    $appxFiles | ForEach-Object {
  145.  
  146.        # The AppX package string. It can be a file name (with or without extension), or a full path.
  147.        $packageString = $_.FullName
  148.        $packageInfo = Get-AppXPackageInfo -PackageString $packageString
  149.        $nameVerArch = "$($packageInfo.Name) v$($packageInfo.Version) ($($packageInfo.Architecture))"
  150.        Write-Host "Package Info.:" -ForegroundColor Gray
  151.        Write-Host ($packageInfo | Format-List | Out-String).Trim() -ForegroundColor DarkGray
  152.        Write-Host ""
  153.  
  154.        $isInstalled = IsAppxPackageInstalled -Name $packageInfo.Name -Version $packageInfo.Version -Architecture $packageInfo.Architecture
  155.        if ($isInstalled) {
  156.            Write-Warning "Package $nameVerArch is already installed."
  157.            Write-Warning "Installation is not required. Ignoring..."
  158.        } else {
  159.            Write-Host "Package $nameVerArch is ready to install."
  160.            Write-Host "Installing package..."
  161.            try {
  162.                Add-AppxPackage -Path "$($_.FullName)" -ErrorAction Stop
  163.                Write-Host "Package $nameVerArch has been successfully installed." -BackgroundColor Black -ForegroundColor Green
  164.            } catch {
  165.                Write-Host "Error installing package $nameVerArch" -BackgroundColor Black -ForegroundColor Red
  166.                Write-Host ""
  167.                Write-Error -Message ($_.Exception | Format-List * -Force | Out-String)
  168.                $LastExitCode = 1
  169.                Break
  170.            }
  171.        }
  172.        Write-Host ""
  173.        $LastExitCode = 0
  174.    }
  175. }
  176.  
  177. Write-Host "Program will terminate now with exit code $LastExitCode. Press any key to exit..."
  178. $key = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
  179. Exit($LastExitCode)


« Última modificación: 5 Abril 2024, 00:22 am por Eleкtro » En línea



Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines