Enroll AVD session host with Trusted Launch automated

  • last updated: Sun, 29 Jan 2023 12:50:32

In this blog post I show how to deploy an AVD session host with the Trusted Launch, secure boot and vTPM. This option is now Generally Available. I show how to deploy the AVD session host with the REST API and with the Az.Avd PowerShell module from a Compute Gallery image.

Azure offers trusted launch as a seamless way to improve the security of generation 2 VMs. Trusted launch protects against advanced and persistent attack techniques. A trusted launch comprises several coordinated infrastructure technologies that can be enabled independently. Each technology provides another layer of defense against sophisticated threats.

Attention: Trusted launch requires the creation of new virtual machines. You can’t enable trusted launch on existing virtual machines that were initially created without it. This also means for images in the Azure Compute Gallery.

Before you start

Make sure you have the following in place before you start.

A Compute Gallery Image definition with a Trusted Launch image. You receive an error like the one below if you haven’t. Updating an image afterward is not possible.

bad-request

I also planning a blog about how to create an Azure Compute Gallery with the Trusted Launch feature enabled. Because creating a new image with Trusted Launch is not possible through the portal. Expecting the blog in a few weeks.

In this chapter, I show two ways how to create a session host from the Azure Compute Gallery and Trusted Launch. First I show how to create a session host with the REST API. In the second part, I show how to deploy a session host (AAD) with the Az.Avd PowerShell module.

Starting variables

I created predefined variables because it makes the deployments easier.

$azureApiUrl = "https://management.azure.com"
$subscriptionId = "<subscriptionID>"
$location = "westeurope"
$hostpoolName = "Rozemuller-AAD"
$resourceGroupName = "rg-roz-avd-01"
$vmSize = "Standard_D2s_v4"
$imageVersionId = "<enter the image version resourceID>"
$prefix = "avd"
$subnetId = "<enter the subnet resourceID>"
$localAdmin = "<username>"
$localPass = "<password>"
$accesToken = Get-AzAccessToken -ResourceUrl $azureApiUrl
$token = @{
    'Content-Type' = 'application/json'
    Authorization = "{0} {1}" -f $accesToken.Type, $accesToken.Token
}

Deploy AVD session host with the REST API

Deploying a session host with the REST API consists of two main parts. First, we create the VM itself. This is the part where Trusted Launch is enabled. We add the VM as a session host in the second part.

Creating the VM has two sub-parts, deploying the network and the rest. This is because the REST API does not support creating a network and the rest in one request.

Create the rest of the VM with the code below with first the network part.

$vmName = "{0}-0" -f $Prefix
$nicName = "{0}-nic" -f $vmName
$nicBody = @{
    "properties" = @{
        "enableAcceleratedNetworking" = $true
        "ipConfigurations"            = @(
            @{
                "name"       = "ipconfig1"
                "properties" = @{
                    "subnet" = @{
                        id = $SubnetId
                    }
                }
            }
        )
    }
    "location"   = $Location
}
$nicJson = $nicBody | ConvertTo-Json -Depth 15
$nicUrl = "{0}/subscriptions/{1}/resourceGroups/{2}/providers/Microsoft.Network/networkInterfaces/{3}?api-version=2021-03-01" -f $azureApiUrl, $subscriptionId, $ResourceGroupName, $nicName
$NIC = Invoke-RestMethod -Method PUT -Uri $nicUrl -Headers $token -Body $nicJson
$vmBody = @{
    location     = $location
    identity     = @{
        type = "SystemAssigned"
    }
    properties = @{
        licenseType       = "Windows_Client"
        hardwareProfile = @{
            vmSize = $VmSize
        }
        securityProfile = @{
            securityType = "TrustedLaunch"
            uefiSettings = @{
                secureBootEnabled = $true
                vTpmEnabled = $true
              }
        }
        storageProfile  = @{
            imageReference = @{
                id = $ImageVersionId
            }

            osDisk         = @{
                caching      = "ReadWrite"
                name         = "{0}-os" -f $vmName
                createOption = "FromImage"
            }
        }
        osProfile       = @{
            adminUsername = $localAdmin
            computerName  = $vmName
            adminPassword = $localPass
        }
        networkProfile  = @{
            networkInterfaces = @(
                @{
                    id         = $NIC.Id
                    properties = @{
                        primary = $true
                    }
                }
            )
        }
    }
} | ConvertTo-Json -Depth 99
$vmUrl = "{0}/subscriptions/{1}/resourceGroups/{2}/providers/Microsoft.Compute/virtualMachines/{3}?api-version={4}" -f $azureApiUrl, $subscriptionId, $resourceGroupName, $vmName, '2021-11-01'
Invoke-RestMethod -Method PUT -Uri $vmUrl -Headers $token -Body $vmBody

trusted-launch.png

About deploying the Azure AD and AVD extensions I would like to refer to this blog article I wrote a while ago about join Azure AD in an automated way.

Deploy AVD session host with Az.Avd PowerShell module

Using the Az.Avd Powershell module gives you a lot advantages. You don’t have to think about all the separate steps and write a lot of code.

Adding a new session host is done with one single line of code. I turned the need starting variables into a parameter object because it keep my line of code clean.

$newShParameters = @{
    location          = "westeurope"
    hostpoolName      = "Rozemuller-AAD"
    resourceGroupName = "rg-roz-avd-01"
    vmSize            = "Standard_D2s_v4"
    imageVersionId    = "<imageversionID>"
    prefix            = "avd"
    subnetId          = "<subnetID>"
    localAdmin        = "<username>"
    localPass         = "<password>"
    initialNumber     = 9
    sessionHostCount  = 1
    disktype          = "Premium_LRS"
}

New-AvdAadSessionHost @newShParameters -TrustedLaunch

trusted-launch-result.png

Az.Avd is available in the official PowerShell Gallery. Install the Az.Avd module with the code below.

Install-Module Az.Avd
Import-Module Az.Avd

If you have installed the Az.Avd module already, thank you for that 🙏. In that case, just update the module with the command below.

Update-Module Az.Avd

Summary

Thank you for reading my blog post about how to deploy an AVD session host with Trusted Launch from a custom image from the Azure Compute Gallery. I show two ways, the REST API and the Az.Avd PowerShell module. The Compute Gallery image must be “trusted-launch-enabled”.

I hope you got a bit inspired.

Enjoy your day and happy automating 👋

comments powered by Disqus

Related Posts

Delete AAD and Intune devices based on CSV and Graph API

The power of community is to collaborate and help others achieve goals. In this case, I got a question from a good community friend to help write a script that removes over 6000 devices from Intune and Azure Active Directory.

Read more

Automate user sign-in experience with company branding

Recently Microsoft redesigned the company branding functionality. That means you have more flexibility in the main layout, full-screen background image for example. But also the ability to change the header, footer and even link relating to self-service password reset, privacy & cookies or Terms of Use.

Read more

Enable Azure Virtual Desktop Insights automated

Azure Virtual Desktop (AVD) Insights is a way to get sight into your AVD environment. In short (from Microsoft), Azure Virtual Desktop Insights is a dashboard built on Azure Monitor Workbooks that helps IT professionals understand their Azure Virtual Desktop environments.

Read more