Intro
Before beginning, it is important to understand when to use the newest offer AppAttach or go with the older MSIX AppAttach.
Below is a table comparing the two:
In general use AppAttach, as long as you’re running Windows 11 Multi-Session or newer, as it is not available on Windows 10 Multi-Session.
Prerequisites
Install MSIX Packaging Tool
https://learn.microsoft.com/en-us/windows/msix/packaging-tool/tool-overview
This tool is used to package .MSI, .App-V or .EXE into a MSIX package that is signed with a certificate.
Download MSIXMGR tool
https://aka.ms/msixmgr
This tool is used to convert .MSIX packages to .CIM that is required.
Create a Stoage Account in Azure
MSIX packages must be placed in a readable share, that AVD session hosts have acces to.
The best way to do that is using Azure Files.
- Create Storage Account in Azure. Use LRS StorageV2 (General-purpose) transaction-optimized.
- Limit Network connectivity to the public IPs you work from, and the vNet/subnet where AVD hosts reside. If using hybrid-joined session hosts, you will join the share to ADDS in later step – include vNet where domain controllers reside.
- Under “File Shares” in the Storage Account, add a new share called “appattach”.
- For permissions, this guide focus on hybrid-joined session hosts. For permissions required in Entra ID joined session hosts setup, please consult Microsoft documentation: https://learn.microsoft.com/en-us/azure/virtual-desktop/app-attach-overview?pivots=app-attach
- Use AzFilesHybrid to join the share to ADDS. Must be done from a domain-joined server in the domain, and with a synced account that have permissions in ADDS to join accounts, and have owner permissions on the storage account in Azure. Synced accounts for administrative purposes are normally not recommended, but in this case required, but only while joining. Remove the admin account afterwards.
- Download AzFilesHybrid from GitHub: https://github.com/Azure-Samples/azure-files-samples/releases
- Use this script to join storage account to ADDS
# Define parameters, $StorageAccountName currently has a maximum limit of 15 characters
$DownloadPath = "C:\Users\testuser\Downloads\AzFilesHybrid.zip"
$SubscriptionId = "<your-subscription-id-here>"
$ResourceGroupName = "<resource-group-name-here>"
$StorageAccountName = "<storage-account-name-here>"
$OuDistinguishedName = "<ou-distinguishedname-here>"
# do not change below this line
$DomainAccountType = "ComputerAccount" # Default is set as ComputerAccount
$EncryptionType = "AES256,RC4"
if(!(test-Path "c:\temp"))
{
New-Item -Path "c:\temp" -ItemType Directory -Force
}
Expand-Archive -LiteralPath $DownloadPath -DestinationPath "c:\temp"
cd "C:\Temp"
# Change the execution policy to unblock importing AzFilesHybrid.psm1 module
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser -Force
# Navigate to where AzFilesHybrid is unzipped and stored and run to copy the files into your path
.\CopyToPSPath.ps1
Install-PackageProvider -Name NuGet -Force
# Import AzFilesHybrid module
Import-Module -Name AzFilesHybrid -Force
# Login with an Azure AD credential that has either storage account owner or contributer Azure role assignment
# If you are logging into an Azure environment other than Public (ex. AzureUSGovernment) you will need to specify that.
# See https://docs.microsoft.com/azure/azure-government/documentation-government-get-started-connect-with-ps
# for more information.
Connect-AzAccount
# Select the target subscription for the current session
Select-AzSubscription -SubscriptionId $SubscriptionId
# Register the target storage account with your active directory environment under the target OU (for example: specify the OU with Name as "UserAccounts" or DistinguishedName as "OU=UserAccounts,DC=CONTOSO,DC=COM").
# You can use to this PowerShell cmdlet: Get-ADOrganizationalUnit to find the Name and DistinguishedName of your target OU. If you are using the OU Name, specify it with -OrganizationalUnitName as shown below. If you are using the OU DistinguishedName, you can set it with -OrganizationalUnitDistinguishedName. You can choose to provide one of the two names to specify the target OU.
# You can choose to create the identity that represents the storage account as either a Service Logon Account or Computer Account (default parameter value), depends on the AD permission you have and preference.
# Run Get-Help Join-AzStorageAccountForAuth for more details on this cmdlet.
Join-AzStorageAccountForAuth `
-ResourceGroupName $ResourceGroupName `
-StorageAccountName $StorageAccountName `
-DomainAccountType $DomainAccountType `
-OrganizationalUnitDistinguishedName $OuDistinguishedName
#Run the command below if you want to enable AES 256 authentication. If you plan to use RC4, you can skip this step.
Update-AzStorageAccountAuthForAES256 -ResourceGroupName $ResourceGroupName -StorageAccountName $StorageAccountName
- Because hybrid-joined servers uses LocalSystem account to access shares, it will be necessary to configure default share-level permissions after it has been joined to ADDS.
Prepare certificate
All packages must be signed with a valid public trusted certificate to work properly.
Either obtain a public trusted certificate that works for digital signing or generate a self-signed certificate.
This section explains how to generate and trust a self-signed certificate.
- Open PowerShell 5 or 7 as Administrator.
- Format below script line 1 and 2 and then execute all lines of code in the PowerShell session.
$Subject = "CN=Contoso, O=Contoso, C=DK"
$Name = "Contoso AppAttach Certificate"
New-SelfSignedCertificate -Type Custom -Subject $Subject -KeyUsage DigitalSignature -FriendlyName $Name -CertStoreLocation "Cert:\CurrentUser\My" -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}") -NotAfter (Get-Date).AddMonths(120)
- Open MMC as administrator. Load Certificate Manager (user).
- Locate the certificate under Personal, Certificates.
- Export the certificate, including the private key in .PFX format. Generate a password for the .PFX file. Password must be kept in a secure location afterwards.
- Export the certificate without the private key in .CER format.
- Certificate in .CER format must be added to the Trust Root Certificate Store on all session hosts. Use Group Policy or Intune to accomplish this – otherwise you cannot add App in Azure in later step. DO NOT INSTALL THE .PFX CERTIFICATE TO AVD SESSION HOSTS.
- Take note of the expiration date of the certificate. It is advised to re-package apps with new certificate before the expiration of the current certificate.
Prepare App in MSIX format
If the app you want to present in AVD does not come in MSIX format, you have to prepare the App using MSIX Packaging Tool.
It is best to run the app in a clean virtual machine. Install the software and run it.
Software that should be packaged must not exist on machine before starting, otherwise the capture will be incomplete.
- Select Create your app package.
- Select to package on this computer
- Make sure there is no errors on the “Prepare Computer” step before proceeding.
- All packages are different, but for this example we use a simple .exe package that require no install commands. We use our certificate in .PFX format with password to sign the app. We use Microsoft TimeStamp server: http://timestamp.acs.microsoft.com
- Fill out all fields. DO NOT CHANGE PUBLISHER NAME, THAT MUST MATCH NAME FROM CERTIFICATE.
- Go through installation of the software. Select not to create any desktop shortcuts if asked. Select not to start App upon installation.
- Finish the package creation.
Prepare App in .CIM format with depending files
Before we can upload the app to Azure, we need to convert it to .CIM.
Use MSIXMGR to do that. PackagePath is the source .msix file and destination is the path for the .CIM and depending files. Change in below command before executing using CMD (run as administrator and make sure CMD dir is the folder of MXIXMGR exe file)msixmgr.exe -Unpack -packagePath "C:\Users\ChristofferJakobsen\Downloads\VLC_3.0.21.0_x64__cga4nf4zmpz28.msix" -destination "C:\msix\VLC\VLC.cim" -applyACLs -create -fileType cim -rootDirectory apps
Upload files to Storage Account
Use your prefered way of uploading files to the file share in the Storage Account. Here we just use the browse feature from Azure portal. (remember to include all files, not only the .cim file)
Add App to AVD
Add App to host pool (MSIX App Attach)
If we want to present the app to users within a full desktop, we must use MSIX AppAttach from within the host pool.
Important
MSIX AppAttach and AppAttach cannot be mixed within a host pool.
1. Navigate to your host pool and select MSIX Packages.
2. Add the packages by inserting the UNC path of the .CIM file, select package. Registration type can either be on-demand or log on blocking, depending on your needs.
3. The app will now be visible inside full desktop session for ALL users that have access to this full desktop host pool.
- Validate that users can see the app in the App menu in Windows:
Important
In the beginning of 2024 Microsoft changed behavior of host pools to only support Full Desktop or RemoteApps.
Remember to check that your host pool is set to Desktop under “Preferred app group type”. Find it in the Properties on the host pool.
Add App to host pool (App Attach)
If your users connect to apps using RemoteApps, you can leveage the newer AppAttach method instead of MSIX AppAttach.
- Go to App Attach from Azure Virtual Desktop.
- Create App Attach package.
- Select subscription, resource group, host pool and region. (Host pool is only used to validate the package against session hosts in later step in the wizard)
- Fill out all fields, start by selecting source storage account and package.
- If you have multiple host pools, you can add this package to multiple (I only have one). Add groups that should have the app visible to them as RemoteApps.
- Review and create the app.
- Add the app to an existing application group or create new. Remember to add the application group to a workspace, otherwise the apps in the application group will not be visible to users.
This picture shows how to validate that your application groups are added to the workspace or not. Add application groups to workspace if that part is missing in your deployment.
Troubleshooting
Use PSExec to monitor if session host have access to share:
https://www.alexandrumarin.com/azure-msix-app-attach-code-400-error/
If you would like to know if an app is mounted via App Attach, you can log on a user to a session host, then connect to this session host as admin, use CMD in Admin mode to navigate to C:\Program Files\WindowsApps and use DIR command to see if any app is showing with JUNKTION and a volume mount point:
Comments