In PowerShell v5.0, how can I display the Add-AppxPackage's cmdlet progressbar at the bottom console window instead of this?:

enter image description here

The progress-bar is hiding information output that I wrote at the start / top of the console.

I asked this question to ChatGPT AI and it was unable to understand the problem.

This is the full code that I'm using (almost all of this code it was generated by ChatGPT):

# AppX Automated Package Installer# Takes a string input of an AppX package name and parses it to extract the name, version, architecture, and publisher ID. # It uses regular expressions to match the package string pattern and returns a custom object with the parsed information. # If the input string cannot be parsed, an error is thrown.function Get-PackageInfo {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)\.Appx$", ""$regex = '^(?<Name>.+?)_(?<Version>.+?)_(?<Architecture>.+?)__(?<PublisherId>.+)$'$match = $filename -match $regexif (!$match) {throw "Unable to parse the string package: '$PackageString'"}$packageName = $matches['Name']$packageVersion = $matches['Version']$packageArchitecture = $matches['Architecture']$packagePublisherId = $matches['PublisherId']$packageFullName = "${packageName}_${packageVersion}_${packageArchitecture}__${packagePublisherId}"$packageFullPath = [System.IO.Path]::Combine($dirname, "$filename.Appx")[PSCustomObject]@{Name = $packageNameVersion = $packageVersionArchitecture = $packageArchitecturePublisherId = $packagePublisherIdFullName = $packageFullNameFullPath = $packageFullPath}}$packageString = "Microsoft.VP9VideoExtensions_1.0.52781.0_x64__8wekyb3d8bbwe.Appx"$sourcePackage = Get-PackageInfo -PackageString $packageStringWrite-Output "Source Package Info:"Write-Output "Package String.....: $packageString"Write-Output "Package Full Path..: $($sourcePackage.FullPath)"Write-Output "Full Name..........: $($sourcePackage.FullName)"Write-Output "Name...............: $($sourcePackage.Name)"Write-Output "Version............: $($sourcePackage.Version)"Write-Output "Architecture.......: $($sourcePackage.Architecture)"Write-Output "Publisher Id.......: $($sourcePackage.PublisherId)"Write-Output ""Write-Output "Checking if source package it is already installed..."Write-Output ""$packages = Get-AppxPackage "$($sourcePackage.Name)*" -ErrorAction SilentlyContinueforeach ($package in $packages) {if ($package.Version -eq $sourcePackage.Version -and $package.Architecture -eq $sourcePackage.Architecture) {Write-Warning "Source package $($sourcePackage.Name) v$($sourcePackage.Version) ($($sourcePackage.Architecture)) is already installed."Write-Warning "Installation is not needed."Write-Output ""Write-Output "Program will terminate now. Press any key to exit..."$Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")Exit 0}}Write-Output "Source package $($sourcePackage.Name) v$($sourcePackage.Version) ($($sourcePackage.Architecture)) is ready to be installed."Write-Output ""Write-Output "Installing source package..."Write-Output ""try {Add-AppxPackage -Path "$($sourcePackage.FullPath)" -ErrorAction StopWrite-Host "The source package $($sourcePackage.Name) v$($sourcePackage.Version) ($($sourcePackage.Architecture)) has been successfully installed." -BackgroundColor Black -ForegroundColor Green Write-Output ""Write-Output "Program will terminate now. Press any key to exit..."$Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")Exit 0}catch {Write-Host "Error installing source package $($sourcePackage.Name) v$($sourcePackage.Version) ($($sourcePackage.Architecture))" -BackgroundColor Black -ForegroundColor RedWrite-Output ""Write-Output ""Write-Error -Message ($_.Exception | Format-List * -Force | Out-String)Write-Output ""Write-Output "Program will terminate now. Press any key to exit..."$Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")Exit 1}
1

Best Answer


Feel free to publish other answer different than this, to mark it as the accepted one.


This is just an update of the code, with @Santiago Squarzon's workaround applied:

# --------------------------------------------- ## AppX Automated 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] FullNamefunction 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)\.Appx$", ""$regex = '^(?<Name>.+?)_(?<Version>.+?)_(?<Architecture>.+?)__(?<PublisherId>.+)$'$match = $filename -match $regexif (!$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]$packageFullName = "${packageName}_${packageVersion}_${packageArchitecture}__${packagePublisherId}"#[string]$packageFullPath = [System.IO.Path]::Combine($dirname, "$filename.Appx")[PSCustomObject]@{Name = $packageNameVersion = $packageVersionArchitecture = $packageArchitecturePublisherId = $packagePublisherIdFullName = $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)$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)}# -----------------------------------------------------------------------------------$host.ui.RawUI.WindowTitle = "AppX Automated Package Installer - by Elektro"# Hides the progress-bar of 'Add-AppxPackage' cmdlet for this script.# Thanks to @Santiago Squarzon for the tip: https://stackoverflow.com/questions/75716867$ProgressPreference = "Ignore"Do {Clear-HostWrite-Output " * * * * * * * * * * * * * * * * * * * * * * * "Write-Output ""Write-Output " AppX Automated Package Installer - by Elektro "Write-Output ""Write-Output " * * * * * * * * * * * * * * * * * * * * * * * "Write-Output ""Write-Output " This script will find any AppX package files within the current directory (without recursion),"Write-Output " print info about the package, print a message in case of the package is already installed,"Write-Output " and install the package in case of it is not installed, handling errors during installation."Write-Output " _________________________________________________________________"Write-Output ""Write-Host "-Continue? (Y/N)"$key = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")$char = $key.Character.ToString().ToUpper()} while ($char -ne "Y" -and $char -ne "N")if ($char -eq "N") {Exit 1} 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-Output ""$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 GrayWrite-Host ($packageInfo | Format-List | Out-String).Trim() -ForegroundColor DarkGrayWrite-Output ""$isInstalled = IsAppxPackageInstalled -Name $packageInfo.Name -Version $packageInfo.Version -Architecture $packageInfo.Architectureif ($isInstalled) {Write-Warning "Package $nameVerArch is already installed."Write-Warning "Installation is not needed."} else {Write-Output "Package $nameVerArch is ready to install."Write-Output "Installing package..."try {Add-AppxPackage -Path "$($_.FullName)" -ErrorAction StopWrite-Host "Package $nameVerArch has been successfully installed." -BackgroundColor Black -ForegroundColor Green } catch {Write-Host "Error installing package $nameVerArch" -BackgroundColor Black -ForegroundColor RedWrite-Output ""Write-Error -Message ($_.Exception | Format-List * -Force | Out-String)$LastExitCode = 1Break}}Write-Output ""$LastExitCode = 0}}Write-Output "Program will terminate now with exit code $LastExitCode. Press any key to exit..."$Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")Exit $LastExitCode