advanced MSI packaging

YOU’RE READING

MSIX Packaging Fundamentals

by Tim Mangan, Bogdan Mitrache & Kevin Kaminski

Download ebook

Get, Add, Remove AppXPackage Cmdlets

The Add-AppXPackage Cmdlet

The Add-AppXPackage cmdlet has several use cases.

Installing a simple package

The most common use case of Add-AppPackage is to install a simple package. As a general best practice, file paths should be enclosed in double quotes to account for spaces in the path and allow for the use of variables in the file path (if needed).

Add-AppXPackage
  -Path “C:\Packages\MyPackage\MyPackage.msix”

Handling package dependency packages

Packages may include a listing of dependency packages in their manifests. These dependencies, which are generally packages with commonly used components like runtimes and frameworks, must be available for the package to be installed. Dependencies of a package may be installed first, prior to this package, or may be installed at the same time using the DependencyPath parameter.

Add-AppXPackage
  -Path
  “C:\Packages\MyPackage\MyPackage.msix”
  -DependencyPath   
  “C:\Packages\MyPackage\MyPackageDependency.msix”

Handling External (Modification or Optional) packages

Modification Packages are examples of how the ExternalPackage option may be used. While the modification package may be installed using the first Add-AppXpackage after the primary package is installed, it may also be installed with the primary package this way. It is important to note that ExternalPackages is an atomic operation which means that if the additional packages fail to install, the whole installation operation is aborted.

The ExternalPackages parameter specifies an array of one or more strings that contain file paths.

Add-AppXPackage
  -Path
  "C:\Packages\MyPackage\MyPackage.msixbundle"
  -ExternalPackages
  "C:\Packages\MyPackage\OptionalPackage.msix",
	"C:\Packages\MyPackage\OptionalPackageBundle
	.msixbundle"

Handing RequiredContentGroups

One feature that a software developer can use to improve installation performance of a large package is to install only the required components and trigger the rest of the components to install later. Microsoft refers to this as application streaming, although it is unrelated to the App-V style of streaming that MSIX does not implement. An example of this may be a game where additional levels are not needed until the user finishes early levels, but optional features that can be triggered by a user-interface component could also be implemented by the developer this way. When such a package is built, the installation can use the RequiredContentGroupOnly parameter, which installs only the required components of the application, leaving the optional components registered in a way that the application can later trigger the download of optional content.

Add-AppXPackage -Path  
  "C:\Packages\MyPackage\MyPackage.msixbundle"
  -RequiredContentGroupOnly

The Get-AppXPackage Cmdlet

The Get-AppXPackage cmdlet allows you to view which applications are installed on a device and is the primary method to identify which applications are installed on a device so that you can manage them using the other PowerShell cmdlets.

Getting the user’s package list

It is common to start with the following command to generate a list that covers applications installed for the logged in user.

Get-AppXPackage

The resulting list will include all kinds of applications, including those that are part of the system, store apps, and developer signed ones. The output will be a list of packages, one of which is shown here:

Name          	: windows.immersivecontrolpanel
Publisher     	: CN=Microsoft Corporation,   
                	O=Microsoft Corporation,  
                	L=Redmond, S=Washington, C=US
Architecture  	: Neutral
ResourceId    	: neutral
Version       	: 10.0.2.1000
PackageFullName   : windows.immersivecontrolpanel
          	_10.0.2.1000_neutral_neutral_cw5n1h2txyewy
InstallLocation   : C:\Windows\ImmersiveControlPanel
IsFramework   	: False
PackageFamilyName : windows.immersivecontrolpanel
                	_cw5n1h2txyewy
PublisherId   	: cw5n1h2txyewy
IsResourcePackage : False
IsBundle      	: False
IsDevelopmentMode : False
NonRemovable  	: True
IsPartiallyStaged : False
SignatureKind 	: System
Status        	: Ok

Sample output generated for an application by Get-AppXPackage

Eliminating System and Store Apps

While the cmdlet directly supports certain types of filters, we can also pipe the output to an external filter to be more creative. For example, the following line would filter only those packages signed by a developer:

Get-AppXPackage   | % {if($_.SignatureKind -eq “developer”){$_.name}}

This produces a list of just the names, but changing “$_.name” to “$_” would show the entire object.

PascalBerger.MSIXCommander
MSIXHero
NotepadPlusPlus-O2004-M2020.824-P430-F
UltraEdit-Class102-O2004
Avogadro-O2004-M2020.824-P430-P
AppPersonalization-Class102
TMurgent-LotsOfFonts-M2020.1006-P4433
23572TimMangan.TMurgent-PsfTooling

Sample output of a filtered list shown package names only

Getting all applications

If you want to see all applications, for each user account registered on a device, so that you can perform a cursor assessment of the applications that are installed on a device, the following cmdlet parameter is available.

et-AppXPackage -AllUsers

NoteTo use the -AllUsers parameter, the PowerShell process must have been elevated using RunAsAdmin. This is true for any AppX PowerShell command that affects more than the current user.

When you run that command, the console output will list all the applications on the machine, including all the specified parameters. The output for a single application is presented in the figure below.

Name                   	: Microsoft.MicrosoftEdge.Stable
Publisher              	: CN=Microsoft Corporation,   
                      	O=Microsoft Corporation,  
                      	L=Redmond, S=Washington, C=US
Architecture           	: Neutral
ResourceId             	:
Version                	: 85.0.564.63
PackageFullName        	: Microsoft.MicrosoftEdge.
           	Stable_85.0.564.63_neutral__8wekyb3d8bbwe
InstallLocation        	: C:\Program Files\WindowsApps\
                     	Microsoft.MicrosoftEdge.
                     	Stable_85.0.564.
                     	63_neutral__8wekyb3d8bbwe
IsFramework            	: False
PackageFamilyName 	: Microsoft.MicrosoftEdge.
                      	Stable_8wekyb3d8bbwe
PublisherId            	: 8wekyb3d8bbwe
PackageUserInformation	: {S-1-5-21-250224505-1589582600-2170371117-1001 [kkaminsk]: Installed}
IsResourcePackage      	: False
IsBundle               	: False
IsDevelopmentMode      	: False
NonRemovable           	: False
IsPartiallyStaged      	: False
SignatureKind          	: Developer
Status                 	: Ok

Sample output generated for an application by Get-AppXPackage -AllUsers

Additional Filtering Options

Once the big picture is assessed, the next step is to begin filtering the application data returned by Get-AppXPackage. You can filter for "application name" by including the Name parameter with a wildcard character.

In the next example, you can see how to use the Get-AppPackage command to filter the results for applications named beginning with “Microsoft.”.

Get-AppXPackage -Name Microsoft.*

You can add in multiple filters to the Get-AppPackage cmdlet. So, for example, most of the time we want to know which applications are assigned to a particular user on a device. Add the User parameter to the previous example along with a user account and Get-AppPackage will return a list of applications published to that user.

Get-AppXPackage -Name Microsoft.ScreenSketch -User 	 
 LocalUser

In some instances, you may need to specify the domain that the user is a part of when a device is joined to Active Directory. However, the domain name is optional when using this parameter.

Get-AppXPackage -Name Microsoft.ScreenSketch -User
   Contoso\DomainUser

The Remove-AppXPackage Cmdlet

Once you understand how to use Get-AppXPackage and Add-AppXPackage, removing a package is straightforward. The Remove-AppXPackage cmdlet is the equivalent to the uninstall feature of the start menu seen in the previous section.

The first step to removing a package with the cmdlet is finding the PackageFullName assigned to the package, which is a composite of other parameters.

You can look up the FullPackageName property for an application using the Get-AppPackage cmdlet (see the above figure: The console output generated for an application by Get-AppXPackage).

The important thing to remember is that the Remove-AppXPackage cmdlet expects the PackageFullName to be passed to the -Package parameter.

Remove-AppXPackage -Package Microsoft.ScreenSketch_10.2008.22.0_x64__8wekyb3d8bbwe

Using Get-AppPackageManifest

The application manifest contains a great deal of metadata about the package. For example, there are times that you need to assess and understand what capabilities the application has registered with the operating system. To search the application manifest for assigned capabilities, try the following:

(Get-AppXPackage -Name "*ZuneMusic*" | Get-AppXPackageManifest).Package.Capabilities)

The Get-AppXPackageManifest cmdlet generates an array of strings with that application’s capabilities.

Capability
----------
{internetClient, privateNetworkClientServer, musicLibrary, removableStorage...}

With a more complicated analysis, it is possible to review other elements that have an effect on user experience such as which applications have startup tasks. For example, if you need to know what applications have registered startup tasks the following bit of PowerShell will collect that information.

# List all the app startups
$startuptasks =
  get-appxpackage -pv app | get-appxpackagemanifest | %
{
if ($_.package.Applications.Application.
   	Extensions.extension.startuptask.taskid)
	{
  	[pscustomobject] @
  	{ PackageFamilyName = $app.PackageFamilyName
    	TaskID = $_.package.Applications.Application.
            	Extensions.extension.startuptask.taskid
  	}
	}
  }
$startuptasks

The output should list off the PackageFamilyName and the tasks that are registered.

PackageFamilyName                 	TaskID
-----------------                 	------
Microsoft.SkypeApp_kzf8qxf38zg5c  	SkypeStartup
Microsoft.549981C3F5F10_8wekyb3d8bbwe CortanaStartupId
SpotifyAB.SpotifyMusic_zpdnekdrzrea0  Spotify
Microsoft.Todos_8wekyb3d8bbwe     	ToDoStartupId
AppleInc.iTunes_nzyj5cx40ttqa    	 
        	{AppleMobileDeviceProcess, iTunesHelper}

Other MSIX/AppX Cmdlets

Additional, less frequently used, PowerShell cmdlets are part of the AppX module. These include cmdlets for provisioned packages (also available using the DISM command described in the next section), and those for Volumes (the location for the MSIX/AppX packages on any given disk partition):

  • Add-AppXProvisionedPackage
  • Get-AppXProvisionedPackage
  • Remove-AppXProvisionedPackage
  • Set-AppXProvisionedDataFile
  • Optimize-AppXProvisionedPackages
  • Add-AppXVolume
  • Get-AppxVolume
  • Mount-AppXVolume
  • Unmount-AppXVolume
  • Remove-AppXVolume
  • Set-AppXDefaultVolume
advanced MSI packaging

YOU’RE READING

MSIX Packaging Fundamentals

by Tim Mangan, Bogdan Mitrache & Kevin Kaminski

Download ebook