How to deliver your MSIX applications with App Volumes

Recently I’ve made a number of MSIX packages to test things out. I’ve known for a while that it’s possible to offer MSIX App Attach packages to endpoints with VMware App Volumes, but hadn’t actually done anything with this yet. I thought it would be fun to find out how I can deliver these MSIX applications with App Volumes to an endpoint. And since I’m a lazy administrator, I decided to largely automate this process using some lines of PowerShell code. In this blog I would like to show you how can convert and deliver your current (and off course your new) MSIX packages with VMware App Volumes.


But before the first .msix package can be converted to an MSIX App Attach package and finally imported in the App Volumes Manager some things need to be prepared.


App Volumes Manager

  • Create a file share. See Configure VHD In-Guest Storage (vmware.com)
  • Install App Volumes Manager. I used 2103 during writing this blog. In my lab I installed the manager with the SQL Express option. In a production environment consider to use more App Volumes Managers and and SQL cluster setup for High Availability.
  • Configure App Volumes Manager (I will show you how to configure the App Volumes Manager (in VHD-Guest Services) later in this blog)
  • Upload the templates to the file share (This will be done by some lines of PowerShell code later in this blog)

Package Machine

To prepare the package machine the following steps have to be performed on a Windows 10 Operating System. I used a 21h1 OS.

  • Install Hyper-V-module for PowerShell
  • Get the MSIX Packaging utility and install it on your packaging VM Download Here!
  • Download MSIXMGR here! and unzip and copy the files to a  folder on your packaging VM. I created c:\msixmgr.
  • Install App Volumes Tools (appcapture.exe) on your packaging VM. These can be installed by running the setup.exe on the VMware_App_Volumes_xxxxx.iso

Configuring the App Volumes Manager

After installing the App Volumes Manager Server by running the setup.exe it is time to configure it using the wizard.

  • Select “Get Started”

  • Upload your license file and select “Next”

  • Register your Active Directory Domain and select “Register”

  • Assign an Active Directory Group to the Administrator role and select “Assign”

Select [VHD] In_Guest Services

Select “Add a File Share”

Search for your share and select “Add”

Select your Share(s) and select them and press “Next”

Select “Set Defaults”.  The templates will no be uploaded to your fileshare



Putting it al together

When the App Volumes Manager is installed and configured and when the package machine has all the required tools installed it is time convert the MSIX so it can be imported in App Volumes.  This process is fully automated  as you can see in the following section. After importing this MSIX vhd  the application can be assigned to a user or group using the App Volumes way.

(Flow chart of the steps in the PowerShell script)


1 Starting point is a .MSIX file which is created using the MSIX Packaging tool.

2 First these variables have to be filled

#### Credentials used for connecting to the MSIX_APP_ATTACH file share ####
$Cred = Get-Credential 

##### MSIX Information ####
$Application = '<Application Name>' # for example KeePass
$Version = '<Application Version>' # for example
$MSIX = '<MSIX_Name>' #for example KeePass_1.0.0.0_x64__t3jj2ebmqsc7y#
$MSIXSource = '<MSIX_Source>' # for exampleC:\users\admin\Desktop\KeePass_1.0.0.0_x64__t3jj2ebmqsc7y.msix

$MSIXAPPATTACHSHARE = '\\<your_share>\<share_name>\appvolumes\packages'

#### MSIXMGR ####
$MSIXMGRLocation = '<MSIXMGR_Install_Location>' # for example C:\msixmgr\x64

#### VHD Variables ####
$VHD = '<location_to_store_your_vhds.vhd>' # for example c:\temp\' + $Application + '_' + $Version + '.vhd'

#### App Volumes Manager ####
$AppVolServer   = '<App_Volumes_Manager_FQDN or IP>'
$AppVolUser     = '<App Volumes Username>'
$AppVolPassword = '<App Volumes Password>'
$AppVol_Datastore    = '<App Volumes Datastore>' # for example this was mine'\\CS-01\MSIX_APP_ATTACH||'
$AppVol_Path         = 'appvolumes/packages'
$AppVol_Datadelay    = 'true'


3 With Powershell a VHD is created and prepared for use. Hyper-V powershell tools needs to be installed on the machine.

#### Creating and Preparing VHD ####
Write-Host "Creating VHD" -ForegroundColor Green
New-VHD -SizeBytes 1024MB -Path $VHD -Dynamic -Confirm:$false
$VHDObject = Mount-VHD $VHD -Passthru
$Disk = Initialize-disk -PassThru -Number $VHDObject.Number
$Partition = New-Partition -AssignDriveLetter -UseMaximumSize -DiskNumber $Disk.Number
Format-Volume -FileSystem NTFS -Confirm:$false -DriveLetter $Partition.Driveletter -Force

4 – With PowerShell the .MSIX copied from the source location to the location where also msixmgr.exe is located.

– A folder is created on the .VHD. This is required because the MSIX package needs to have a parent folder to work properly (Source)

– msixmgr.exe will unpack the .MSIX to the VHD

– The VHD will be unmounted.

Write-Host "Creating MSIX APP ATTACH .vhd" -ForegroundColor Green
# Copy MSIX to MSIXMGR folder
Copy-Item -Path $MSIXSource -Destination $MSIXMGRLocation
# Create a folder on the VHD. This is neccesary according to the documentation
New-Item -Path $PartitionPath -Name $MSIX -ItemType Directory 
# MSIXMGR Magic!!!!
cd $MSIXMGRLocation
$MSIXPath =  '.\' + $MSIX + '.msix'
$PartitionPath = $Partition.DriveLetter + ':\'
$MSIXMGRDestination = (get-childitem -Path $PartitionPath).FullName 
.\msixmgr.exe -Unpack -PackagePath $MSIXPath -destination $MSIXMGRDestination -applyacls
Dismount-VHD $VHD -Confirm:$false

5 Running appcapture.exe using PowerShell to create the metadata (.JSON) file.

#### Running AppCapture to create JSON ####
Write-Host "Creating MSIX Metadata" -ForegroundColor Green
$MSIXMeta = $MSIX + '\' + $MSIX
cd 'C:\Program Files (x86)\VMware\AppCapture'
.\appcapture.exe /addmeta $VHD /msix $MSIXMeta

6 Copy the .vhd and .json to the MSIX_APP_ATTACH file share using PowerShell

#### Copy .VHD and .JSON to MSIX_APP_ATTACH File Share ####
Write-Host "Copy .vhd and .json to MSIX_APP_ATTACH Share" -ForegroundColor Green
$Destination = New-PSDrive -Name MSIX -PSProvider FileSystem -Root $MSIXAPPATTACHSHARE -Credential $cred
Get-ChildItem -Path C:\temp | Copy-Item -Destination $Destination.Root
Remove-PSDrive -Name $Destination.Name

7 Logging in to App Volumes Manager

#Logging on to App Volumes Server
Write-Host "Logging in to App Volumes Manager" -ForegroundColor Green
$Body = @{
        username = $AppVolUser
        password = $AppVolPassword

#Ignore Certificate errors while I am not trusting the default App Volumes certificate
add-type @"
    using System.Net;
    using System.Security.Cryptography.X509Certificates;
    public class TrustAllCertsPolicy : ICertificatePolicy {
        public bool CheckValidationResult(
            ServicePoint srvPoint, X509Certificate certificate,
            WebRequest request, int certificateProblem) {
            return true;
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

$LoggingIn = Invoke-WebRequest -SessionVariable Login -Method Post -Uri https://$AppVolServer/cv_api/sessions -Body $Body 
Write-Host $LoggingIn.Content -ForegroundColor Green
Set-Variable -Name Login -Value $Login -Scope global

8 Importing the application/package in to App Volumes Manager and wait until this task is finished

#### Import the Application into the App Volumes Manager ####
write-host "Importing Application/Package from datastore to App Volumes Manager" -ForegroundColor Green
$AVDatacenter  = 'data[datacenter]'
$AVDatastore   = 'data[datastore]'
$Path          = 'data[path]' 
$Delay         = 'data[delay]'

$Body = @{
        $AVDatacenter = ''
        $AVDatastore  = $AppVol_Datastore
        $Path         = $AppVol_Path
        $Delay        = $AppVol_Datadelay
$Import = Invoke-WebRequest -WebSession $Login -Method Post -Uri https://$AppVolServer/app_volumes/app_products/import -Body $Body
Write-Host $Import.Content -ForegroundColor Green

#Importing Application and Package from Datastore
Write-Host "Application and Package are being imported in App Volumes Manager" -ForegroundColor Green
DO {$pending_jobs = ((Invoke-WebRequest -WebSession $Login -Method Get -Uri "https://$AppVolServer/cv_api/jobs/pending").content | ConvertFrom-Json)
   }UNTIL($pending_jobs.pending -eq "0")
write-host "Application and Package are succesfully imported in App Volumes Manager" -ForegroundColor Green

Since I’m only using this in my lab environment at the moment, I haven’t added any error handling to this code. It is recommended that you do this if you continue with this.

Checking if the import in App Volumes Manager was really successful!

First I would like to see if the application is really imported in the App Volumes Manager.

When logging in to the App Volumes Manager GUI the application is listed (FileZilla in this case).

The MSIX package is also successfully created and ready to assign!

Let’s test the application!!

After assigning the application to a user group and logging in to a desktop the Application is added succesfully.

This is also visible in Settings -> App & Features

The App Volumes Agent creates a MSIXAppAttach.log in c:\Program Files(x86)\CloudVolumes\Agent\Logs.

The log file looks like this.

And finally the  application starts succesfully:-)


It was really nice to be introduced to a different way of delivering applications through App Volumes this way. The script only takes a few minutes (2.5 minutes in my case) and saves you a lot of manual actions and therefore the risk of making mistakes. It all works flawlessly and if something goes wrong, the log files (msixappattach.log) provide enough information to continue working with this.

Thanks for reading.

Roderik de Block



Used resources:

Learn how to configure MSIX app attach (via the Azure Portal) packages containers on Windows 10 Enterprise multi and single-session for Azure Virtual Desktop | christiaanbrinkhoff.com – Sharing Cloud and Virtualization Knowledge

Azure Virtual Desktop prepare MSIX app attach image – Azure | Microsoft Docs






Roderik de Block

Leave a Reply

Your email address will not be published. Required fields are marked *