Publishing an MSIX as CIM to AVD in a Pipeline

I wanted to put this out there as it felt like a nifty way to pipeline AVD MSIX files into AVD without any user interaction (other than a pipeline kicking off the script).

https://github.com/jflieben/assortedFunctionsV2/blob/main/publish-MSIXPackageToHostpool.ps1

Basically, above will grab the MSIX file from a known Azure Fileshare (after mounting). It’ll read the MSIX’s primary CIM file for meta data, use the Azure Rest API to add it to the hostpool and then updates a param file of an ARM template which can be used to e.g. update the appgroup in Azure.

You’ll need some background knowledge to re-use above in your specific situation 🙂

Code example:

#create the MSIX package object in the hostpool. Ensure the lastUpdated value is always unique otherwise it will fail to overwrite an existing package with the same value
$apiPostData = @{
    "properties" = @{
        "displayName" = if($packageMeta -match "(?<=<DisplayName>)(.*?)(?=<\/DisplayName>)"){$matches[1]}else{Throw "No display name found in AppManifest"}
        "imagePath" = $imagePath
        "isActive" = $True
        "isRegularRegistration" = $False
        "lastUpdated" = (get-itemproperty $packageFolder.FullName).LastWriteTimeUtc.AddSeconds((Get-Random -Minimum "-150" -Maximum 150)).ToString("yyyy-MM-ddThh:mm:ss")
        "packageApplications" = $packageApplications
        "packageDependencies" = @()
        "packageFamilyName" = "$($packageShortName)_$($packageFamily)"
        "packageName" = $packageShortName
        "packageRelativePath" = "\MSIXPackages\$($packageFolder.Name)"
        "version" = $packageVersion
    }
}

#send the actual API request to register the package in the hostpool using the pipeline serviceprincipal
try{
    $context = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile.DefaultContext
    $token = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account, $context.Environment, $context.Tenant.Id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, $null, "https://management.azure.com")          
    Invoke-RestMethod -Uri "https://management.azure.com/subscriptions/$((get-azcontext).Subscription.id)/resourcegroups/rg-common-$($environment)-weeu-01/providers/Microsoft.DesktopVirtualization/hostPools/vdhp-common-$($environment)-weeu-01/msixPackages/$($packageFolder.Name)?api-version=2021-07-12" -Method PUT -UseBasicParsing -ContentType "application/json" -Body ($apiPostData | convertto-json -Depth 15) -Headers @{"Authorization"="Bearer $($token.AccessToken)"} -ErrorAction Stop
}catch{
    Write-Output $_
    closeCIMSession
    Throw
}

OnedriveMapper V5 required update!

Microsoft is planning to modify the Office 365 sign in process slightly by September 15th or October 1st and has kindly supplied advance notice and support for OnedriveMapper, but only for V3.29+ and V5.15+

So if you’re on a lower version -> update asap!

The new login interruption looks like this:

OnedriveMapper V5 @ GitHub

OnedriveMapper V3 @ GitHub