MSIX App Attach: Walkthru (Walk Before You Run)
MSIX App Attach: How do you do it? Find out in this blog.
That being said, let's first understand the problem MSIX App Attach tries to solve:
For a long time, golden images were used with a myriad of applications... leading to a myriad of golden images.
NOT a great way to streamline. Images can quickly become bloated and the task of updating and maintaining them is cumbersome and overly time consuming. VDI and application streaming has been another alternative, but these require complex infrastructure that has to be implemented and maintained. Now with remote work on everyone's mind, we need an easier way deliver applications.
As such, Microsoft recently unveiled their new MSIX App Attach solution and is positioning it as their main technology for modern application packaging and provisioning. As its name implies, it allows you to attach an application to the OS. Some of the benefits of MSIX App Attach include:
- No special deployment servers are needed
- No agents: Everything is just "built into Windows" natively.
- You can use existing MSIX packages without altering or repackaging them.
- There is ultra-low / no performance impact.
- Can be used on-premise or cloud
To help you get started with this new methodology approach to application delivery, I have composed a called “MSIX: Walk before you run” to help you get familiar with the basic approach of how it works. To keep things simple, we aren’t going to create any MSIX packages here but will use existing ones just to show how to implement an MSIX App Attach solution.
Then you can use the material below to "follow along" and try this yourself.
Step 1: Get a compatible OS
So first and foremost, you need an OS that supports it all. That means getting a copy of Windows 2004 which is the latest version of Windows 10. Then you need to upgrade to Build 19631 which at this time may require you to utilize the Windows Insider Program to get it.
Step 2: Get MSIX packages
So of course we need some MSIX packages. Now we could use the MSIX Packaging Tool that you can download from Microsoft, but I am skipping that step for take advantage of some existing packages already available. There is a great Microsoft repository site called Github Winget Package Manifest Page that features all types of prepackaged applications. Pull the page up in a browser and do a search for MSIX. In my video, I then chose MSIX Commander as my feature application and copied it’s URL in order to download it. Now I have an MSIX package that I can use for my example. Place it and all other downloads in a separate folder. In my video, I am using a directory called “Demo.”
Step 3: Using the Script
I went and logged on my local my machine as a domain admin in order to perform the remaining tasks. Throughout my video I refer to a conglomerated script that I pieced together for you. I obtained the script from several sources. I got some from the official Microsoft Setup Document which guides you along in much the same format that I take in the video. I also used several scripts made available by Tom Hickling’s Github page. I then cobbled all of these scripts together and I have included the final script in its entirety at the end of this blog. Now let’s go through the script.
Step 4: Create a VHD Package
While you see MSIX App Attach associated with Azure and WVD a lot, keep in mind that what we are doing can be performed on local desktops or laptops as well as VDI and WVD machines. I am doing everything locally in this video. You will need to download the MSIXMGR Tool and place it in the same directory as your MSIX file (in my case MSIX Commander). Now we need to utilize the script to create the VHD. To do this, I used Tom Hickling’s script. Since he was using VLC as his package, I modified it to accommodate MSIX Commander. Go create the VHD, I am using the section titled “Make an MSIX into a VHD”
Open an elevated PowerShell session and go to the directory that contains all of the required files I mentioned earlier. Then paste the VHD script and let PowerShell do its thing. Now your MSIX VHD file is created with your MSIX file expanded into the VHD. The VHD will already be mounted. In my case it mounted as drive E so you can browser its contents. Be sure to view the package name and copy that name and paste it into Notepad for future reference. You will also need to know the Volume ID of the VHD file which you can find by using the “mountvol” command. Then paste in your Notepad as well.
Step 5: Package Staging
In this video, I chose to skip the Certificate section for simplicity which takes us to the next step called Staging. First go ahead and unmount the VHD. You will find that the Stage section of the script is broken down into regions. I advise you to paste the script into PowerShell region by region. For first region, you will need to modify the VHD name, package name and volume ID you recorded earlier. Below is what my first region looked like:
#MSIXCOMMANDER
$vhdSrc="c:\ApplicationVHDs\MSIXCOMMANDER.vhdx"
$parentFolder = "MSIXCOMMANDER"
$packageName = "PascalBerger.MSIXCommander_1.0.7.5_x64__ajjbhed1xnq88"
$parentFolder = "\" + $parentFolder + "\"
$volumeGuid = "5f51883c-6f50-4c6a-9afb-9513c6e7c565"
#NOTE: GET VOLUMEGUID after mounting VHD then use MOUNTVOL command to get volume GUID. Remove {}
$msixJunction = "C:\temp\AppAttach\"
The second region will mount the disk and the third region will perform what is called the junction. The final “stage region” will perform the actual attaching.
Step 6: Register Script
So now we have attached the app, but we don’t have it within the user space. I have the variables assigned to the values I mentioned earlier to run MSIX Commander so let’s copy the Register region and paste it into PS. Once completed, you will then see MSIX Commander in the Windows Start Menu like in the video. If I log on another user, in this case a standard user, I can’t see the MSIX app because the register script only applied to the user account I was logged on at the time. So for this demonstration, I will simply open PowerShell logged on as a standard user and paste the Register region script in once again. While I may have to dig a little through the Start menu to see it, it now appears for the user at hand.
Step 7: Undoing the MSIX App Attach Environment
Any MSIX package that can be registered can be deregistered as well. To do so, simply copy the De-Reregister region of the script and paste it into PowerShell and run it. Now the app will disappear from the start menu. In the video, I switched over to my original domain admin account and ran the deregistering process as well. The final step of undoing everything will be to de-stage it so it cannot be applied to users any longer.
That completes the demonstration. Go ahead and use the script I have included. Just remember to modify the mentioned variables within the script when working with other MSIX files and such. With a few run-throughs, you will be running in no time.
Jeremy’s Compiled Script below for reference... !
Make an MSIX into a VHD
#Go and package your app using the MSIX App packager
#Generate a VHD or VHDX package for MSIX
#vlc
new-vhd -sizebytes 2048MB -path C:\ApplicationVHDs\MSICOMMANDER.vhdx -dynamic -confirm:$false
$vhdObject = Mount-VHD C:\ApplicationVHDs\MSIXCOMMANDER.vhdx -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
#Create a folder with your Appname as the name of the folder in root drive mounted above
new-item -path 'E:\MSIXCOMMANDER' -ItemType Directory
#Expand MSIX in CMD in Admin cmd prompt - Get the full package name
.\msixmgr.exe -Unpack -packagePath ".\MSIX Commander-x64.msix" -destination "E:\MSIXCOMMANDER" -applyacls
#Cert
New-SelfSignedCertificate -Type CodeSigningCert -Subject "CN=JeremyTest"
1. STAGE
---
#MSIXCOMMANDER
$vhdSrc="c:\ApplicationVHDs\MSIXCOMMANDER.vhdx"
$parentFolder = "MSIXCOMMANDER"
$packageName = "PascalBerger.MSIXCommander_1.0.7.5_x64__ajjbhed1xnq88"
$parentFolder = "\" + $parentFolder + "\"
$volumeGuid = "5f51883c-6f50-4c6a-9afb-9513c6e7c565"
#NOTE: GET VOLUMEGUID after mounting VHD then use MOUNTVOL command to get volume GUID. Remove {}
$msixJunction = "C:\temp\AppAttach\"
#endregion
#region mountvhd
try
{
Mount-Diskimage -ImagePath $vhdSrc -NoDriveLetter -Access ReadOnly
Write-Host ("Mounting of " + $vhdSrc + " was completed!") -BackgroundColor Green
}
catch
{
Write-Host ("Mounting of " + $vhdSrc + " has failed!") -BackgroundColor Red
}
#endregion
#region makelink
$msixDest = "\\?\Volume{" + $volumeGuid + "}\"
if (!(Test-Path $msixJunction))
{
md $msixJunction
}
$msixJunction = $msixJunction + $packageName
cmd.exe /c mklink /j $msixJunction $msixDest
#endregion
#region stage
[Windows.Management.Deployment.PackageManager,Windows.Management.Deployment,ContentType=WindowsRuntime] | Out-Null
Add-Type -AssemblyName System.Runtime.WindowsRuntime
$asTask = ([System.WindowsRuntimeSystemExtensions].GetMethods() | Where { $_.ToString() -eq 'System.Threading.Tasks.Task`1[TResult] AsTask[TResult,TProgress](Windows.Foundation.IAsyncOperationWithProgress`2[TResult,TProgress])'})[0]
$asTaskAsyncOperation = $asTask.MakeGenericMethod([Windows.Management.Deployment.DeploymentResult], [Windows.Management.Deployment.DeploymentProgress])
$packageManager = [Windows.Management.Deployment.PackageManager]::new()
$path = $msixJunction + $parentFolder + $packageName # needed if we do the pbisigned.vhd
$path = ([System.Uri]$path).AbsoluteUri
$asyncOperation = $packageManager.StagePackageAsync($path, $null, "StageInPlace")
$task = $asTaskAsyncOperation.Invoke($null, @($asyncOperation))
$task
#endregion
2. REGISTER
----
#MSIX app attach registration sample
#region variables
#PBI
#$packageName = "PowerBI_1.0.0.0_x64__74tjgdb1s5w2y"
#MSICOMMANDER
$packageName = "PascalBerger.MSIXCommander_1.0.7.5_x64__ajjbhed1xnq88"
$path = "C:\Program Files\WindowsApps\" + $packageName + "\AppxManifest.xml"
#$path = "E:\VLC\" + $packageName + "\AppxManifest.xml"
#endregion
#region register
Add-AppxPackage -Path $path -DisableDevelopmentMode -Register
#endregion
3. DE-REGISTER
---
#MSIX app attach deregistration sample
#region variables
$packageName = "PascalBerger.MSIXCommander_1.0.7.5_x64__ajjbhed1xnq88"
#endregion
#region deregister
Remove-AppxPackage -PreserveRoamableApplicationData $packageName
#endregion
4. De-stage
--
#MSIX app attach de staging sample
#region variables
$packageName = "PascalBerger.MSIXCommander_1.0.7.5_x64__ajjbhed1xnq88"
$msixJunction = "C:\temp\AppAttach\"
#endregion
#region deregister
Remove-AppxPackage -AllUsers -Package $packageName
cd $msixJunction
rmdir $packageName -Force -Verbose
#endregion