When automating Azure Virtual Desktop (AVD) deployments with Bicep, you might run into a frustrating issue: an empty registration token. This token is key for registering session hosts in the AVD environment. Here’s how to fix that problem and avoid some headaches.

Define the Host Pool and Generate the Token

First things first—define the AVD host pool in your Bicep file and make sure you explicitly generate the token by setting registrationTokenOperation to 'Update'.

resource avdhostpool 'Microsoft.DesktopVirtualization/hostPools@2024-04-08-preview' = {
  name: avdHostPoolName
  location: location
  properties: {
    hostPoolType: 'Pooled'
    loadBalancerType: 'DepthFirst'
    preferredAppGroupType: 'Desktop'
    startVMOnConnect: true
    validationEnvironment: false
    maxSessionLimit: 10
    registrationInfo: {
      expirationTime: expirationTime
      registrationTokenOperation: 'Update' // Generate that token!
      token: null
    }
  }
}

The key here is setting registrationTokenOperation to ‘Update’. This forces the host pool to cough up a valid token instead of an empty one.

Retrieve the Registration Token

Next, grab that shiny new token using the listRegistrationTokens function:

output registrationToken string = first(avdhostpool.listRegistrationTokens().value).token

This pulls the first token and stores it for use later. No more empty token surprises.

Create Session Hosts and Use the Token

Finally, use this token to register your session hosts. You can pass it using the AVD custom script extension to join the hostpool:

resource avdVM 'Microsoft.Compute/virtualMachines@2024-07-01' = [for i in range(0, 2): {
  name: 'avdvm-${i}'
  location: location
  properties: {
    hardwareProfile: {
      vmSize: 'Standard_D2s_v3'
    }
    storageProfile: {
      imageReference: {
        publisher: 'MicrosoftWindowsDesktop'
        offer: 'Windows-10'
        sku: '21h2-ent-multisession'
        version: 'latest'
      }
    }
    osProfile: {
      computerName: 'avdvm-${i}'
      adminUsername: 'azureadmin'
      adminPassword: 'Password123!'
    }
    networkProfile: {
      networkInterfaces: [
        {
          id: resourceId('Microsoft.Network/networkInterfaces', 'nic-avdvm-${i}')
        }
      ]
    }
  }
}]

resource vmExtension 'Microsoft.Compute/virtualMachines/extensions@2024-07-01' = [for i in range(0, 2): {
  name: 'avdvm-${i}/runScript'
  location: avdVM.location
  properties: {
    publisher: 'Microsoft.Compute'
    type: 'CustomScriptExtension'
    typeHandlerVersion: '1.10'
    settings: {
      fileUris: ['https://path/to/your/script.ps1']
      commandToExecute: 'powershell -ExecutionPolicy Unrestricted -File script.ps1 -Token ${registrationToken}'
    }
  }
}]

No more pulling your hair out over empty tokens! By setting registrationTokenOperation to ‘Update’ and using listRegistrationTokens(), you’ll get the registration token you need.