{ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "_artifactsLocation": { "type": "string", "metadata": { "description": "The base URI where artifacts required by this template are located." }, "defaultValue": "https://raw.githubusercontent.com/Azure/RDS-Templates/master/wvd-templates/Create%20and%20provision%20WVD%20host%20pool/" }, "_artifactsLocationSasToken": { "type": "securestring", "metadata": { "description": "The sasToken required to access _artifactsLocation when they're located in a storage account with private access." }, "defaultValue": "" }, "rdshImageSource": { "type": "string", "metadata": { "description": "Select the image source for the session host vms. VMs from a Gallery image will be created with Managed Disks." }, "defaultValue": "Gallery", "allowedValues": [ "SharedImageGallery", "CustomVHD", "CustomImage", "Gallery" ] }, "SharedImageGalleryResourceGroup": { "type": "string", "metadata": { "description": "(Required when rdshImageSrouce = SharedImageGallery) ResourceGroup name of the Shared Image Gallery" }, "defaultValue": "" }, "SharedImageGalleryName": { "type": "string", "metadata": { "description": "(Required when rdshImageSrouce = SharedImageGallery) Name of the Shared Image Gallery." }, "defaultValue": "" }, "SharedImageGalleryDefinitionName": { "type": "string", "metadata": { "description": "(Required when rdshImageSrouce = SharedImageGallery) Name of the Image Definition." }, "defaultValue": "" }, "SharedImageGalleryVersionName": { "type": "string", "metadata": { "description": "(Required when rdshImageSrouce = SharedImageGallery) Name of the Image Version - should follow ..." }, "defaultValue": "" }, "vmImageVhdUri": { "type": "string", "metadata": { "description": "(Required when rdshImageSource = CustomVHD) URI of the sysprepped image vhd file to be used to create the session host VMs. For example, https://rdsstorage.blob.core.windows.net/vhds/sessionhostimage.vhd" }, "defaultValue": "" }, "rdshGalleryImageSKU": { "type": "string", "metadata": { "description": "(Required when rdshImageSource = Gallery) Gallery image SKU." }, "allowedValues": [ "Windows-10-Enterprise-multi-session-with-Office-365-ProPlus", "Windows-10-Enterprise-multi-session", "Windows-10-Enterprise-1903", "2016-Datacenter", "2019-Datacenter" ], "defaultValue": "Windows-10-Enterprise-multi-session-with-Office-365-ProPlus" }, "rdshCustomImageSourceName": { "type": "string", "defaultValue": "", "metadata": { "description": "(Required when rdshImageSource = CustomImage) Name of the managed disk." } }, "rdshCustomImageSourceResourceGroup": { "type": "string", "defaultValue": "", "metadata": { "description": "(Required when rdshImageSource = CustomImage) Resource group name for the managed disk, if you choose to provide one." } }, "rdshNamePrefix": { "type": "string", "metadata": { "description": "This prefix will be used in combination with the VM number to create the VM name. If using 'rdsh' as the prefix, VMs would be named 'rdsh-0', 'rdsh-1', etc. You should use a unique prefix to reduce name collisions in Active Directory." }, "defaultValue": "[take(toLower(resourceGroup().name),10)]" }, "rdshNumberOfInstances": { "type": "int", "metadata": { "description": "Number of session hosts that will be created and added to the hostpool." } }, "rdshVMDiskType": { "type": "string", "allowedValues": [ "Premium_LRS", "StandardSSD_LRS", "Standard_LRS" ], "metadata": { "description": "The VM disk type for the VM: Premium_LRS (Default), Standard_LRS or StandardSSD_LRS." }, "defaultValue": "Premium_LRS" }, "rdshVmSize": { "type": "string", "metadata": { "description": "The size of the session host VMs." }, "defaultValue": "Standard_D2s_v3" }, "enableAcceleratedNetworking": { "type": "bool", "metadata": { "description": "Enables Accelerated Networking feature, notice that VM size must support it, this is supported in most of general purpose and compute-optimized instances with 2 or more vCPUs, on instances that supports hyperthreading it is required minimum of 4 vCPUs." }, "defaultValue": false }, "rdshUseManagedDisks": { "type": "bool", "defaultValue": true, "metadata": { "description": "True indicating you would like to use managed disks or false indicating you would like to use unmanaged disks." } }, "storageAccountResourceGroupName": { "type": "string", "metadata": { "description": "(Required when rdshUseManagedDisks = False) The resource group containing the storage account of the image vhd file." }, "defaultValue": "" }, "domainToJoin": { "type": "string", "metadata": { "description": "FQDN of the AD Domain to which session host VMs are going to be joined. For example, 'contoso.com'." } }, "existingDomainUPN": { "type": "string", "metadata": { "description": "A username in the domain that has privileges to join the session hosts to the domain. For example, 'user1@contoso.com'." } }, "existingDomainPassword": { "type": "securestring", "metadata": { "description": "The password that corresponds to the existing domain username." } }, "ouPath": { "type": "string", "defaultValue": "", "metadata": { "description": "(Optional) Specifiy an organizational unit (OU) to place the new virtual machines when joining the domain. If you do not have a specific OU to place the virtual machines, leave it blank. Example OU: 'OU=testOU;DC=domain;DC=Domain;DC=com'" } }, "existingVnetName": { "type": "string", "metadata": { "description": "The name of the virtual network the VMs will be connected to." } }, "newOrExistingVnet": { "type": "string", "defaultValue": "existing", "allowedValues": [ "existing" ], "metadata": { "description": "Only existing vnets are allowed. This parameter ensures validation for Azure Marketplace offering." } }, "existingSubnetName": { "type": "string", "metadata": { "description": "The subnet the VMs will be placed in." } }, "virtualNetworkResourceGroupName": { "type": "string", "metadata": { "description": "The resource group containing the existing virtual network." } }, "rdBrokerURL": { "type": "string", "metadata": { "description": "The Broker URL of the Windows Virtual Desktop deployment the session hosts will be connected to." }, "defaultValue": "https://rdbroker.wvd.microsoft.com" }, "existingTenantGroupName": { "type": "string", "metadata": { "description": "The name of the tenant group in the Windows Virtual Desktop deployment" }, "defaultValue": "Default Tenant Group" }, "existingTenantName": { "type": "string", "metadata": { "description": "The name of the tenant in the Windows Virtual Desktop deployment." } }, "hostPoolName": { "type": "string", "metadata": { "description": "The name of the hostpool to be created in the RDS Tenant." } }, "serviceMetadataLocation": { "type": "string", "metadata": { "description": "Windows Virtual Desktop stores information that is global in nature. Select the location you would like the service metadata to be stored. See https://aka.ms/wvdgeo for more information." }, "allowedValues": [ "United-States" ], "defaultValue": "United-States" }, "enablePersistentDesktop": { "type": "bool", "metadata": { "description": "Set this parameter to true if you would like to enable Persistent Desktop experience. Defaults to false." }, "defaultValue": false }, "defaultDesktopUsers": { "type": "string", "metadata": { "description": "Provide a comma separated list of users you would like to assign to access the desktop for this host pool. Example: user1@contoso.com,user2@contoso.com,user3@contoso.com " }, "defaultValue": "" }, "tenantAdminUpnOrApplicationId": { "type": "string", "metadata": { "description": "The template will fail if you enter a user account that requires MFA or an application that is secured by a certificate. The UPN or ApplicationId must be an RDS Owner in the Windows Virtual Desktop Tenant to create the hostpool or an RDS Owner of the host pool to provision the host pool with additional VMs." } }, "tenantAdminPassword": { "type": "securestring", "metadata": { "description": "The password that corresponds to the tenant admin UPN." } }, "isServicePrincipal": { "type": "bool", "defaultValue": false, "metadata": { "description": "The boolean value indicating if the credentials are for a service principal." } }, "aadTenantId": { "type": "string", "defaultValue": "", "metadata": { "description": "(Required when isServicePrincipal = True) This value identifies the Azure AD tenant of the service principal." } }, "location": { "type": "string", "defaultValue": "[resourceGroup().location]", "metadata": { "description": "(Required for Azure Marketplace.) Leave as is, unless you would like to not use a location that is different from the location of the resouce group." } } }, "variables": { "rdshManagedDisks": "[if(equals(parameters('rdshImageSource'), 'CustomVHD'), parameters('rdshUseManagedDisks'), bool('true'))]", "rdshPrefix": "[concat(parameters('rdshNamePrefix'),'-')]", "avSetSKU": "[if(variables('rdshManagedDisks'), 'Aligned', 'Classic')]", "existingDomainUsername": "[first(split(parameters('existingDomainUPN'), '@'))]", "vhds": "[concat('vhds','/', variables('rdshPrefix'))]", "subnet-id": "[resourceId(parameters('virtualNetworkResourceGroupName'),'Microsoft.Network/virtualNetworks/subnets',parameters('existingVnetName'), parameters('existingSubnetName'))]", "existingTenantName": "[replace(parameters('existingTenantName'),'\"','')]", "hostPoolName": "[replace(parameters('hostPoolName'),'\"','')]", "hostPoolFriendlyName": "[variables('hostPoolName')]", "hostPoolDescription": "Created through ARM template", "registrationExpirationHours": "48", "vmTemplateName": "[concat( if(variables('rdshManagedDisks'), 'managedDisks', 'unmanagedDisks'), '-', toLower(replace(parameters('rdshImageSource'),' ', '')), 'vm')]", "vmTemplateUri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/', variables('vmTemplateName'), '.json', parameters('_artifactsLocationSasToken')))]", "rdshVmNamesOutput": { "copy": [ { "name": "rdshVmNamesCopy", "count": "[parameters('rdshNumberOfInstances')]", "input": { "name": "[concat(variables('rdshPrefix'),copyIndex('rdshVmNamesCopy'))]" } } ] }, "vmCreation-linkedTemplate_name": "[concat(variables('rdshPrefix'), 'vmCreation-linkedTemplate')]" }, "resources": [ { "apiVersion": "2018-10-01", "condition": "[equals(parameters('enablePersistentDesktop'),bool('False'))]", "type": "Microsoft.Compute/availabilitySets", "name": "[concat(variables('rdshPrefix'), 'availabilitySet')]", "location": "[parameters('location')]", "properties": { "platformUpdateDomainCount": 5, "platformFaultDomainCount": 2 }, "sku": { "name": "[variables('avSetSKU')]" } }, { "apiVersion": "2018-05-01", "name": "[variables('vmCreation-linkedTemplate_name')]", "type": "Microsoft.Resources/deployments", "dependsOn": [ "[concat('Microsoft.Compute/availabilitySets/', variables('rdshPrefix'), 'availabilitySet')]" ], "properties": { "mode": "Incremental", "templateLink": { "uri": "[variables('vmTemplateUri')]", "contentVersion": "1.0.0.0" }, "parameters": { "vmImageVhdUri": { "value": "[parameters('vmImageVhdUri')]" }, "storageAccountResourceGroupName": { "value": "[parameters('storageAccountResourceGroupName')]" }, "SharedImageGalleryResourceGroup": { "value": "[parameters('SharedImageGalleryResourceGroup')]" }, "SharedImageGalleryName": { "value": "[parameters('SharedImageGalleryName')]" }, "SharedImageGalleryDefinitionName":{ "value": "[parameters('SharedImageGalleryDefinitionName')]" }, "SharedImageGalleryVersionName":{ "value": "[parameters('SharedImageGalleryVersionName')]" }, "rdshGalleryImageSKU": { "value": "[parameters('rdshGalleryImageSKU')]" }, "rdshPrefix": { "value": "[variables('rdshPrefix')]" }, "rdshNumberOfInstances": { "value": "[parameters('rdshNumberOfInstances')]" }, "rdshVMDiskType": { "value": "[parameters('rdshVMDiskType')]" }, "rdshVmSize": { "value": "[parameters('rdshVmSize')]" }, "enableAcceleratedNetworking": { "value": "[parameters('enableAcceleratedNetworking')]" }, "existingDomainusername": { "value": "[variables('existingDomainUsername')]" }, "existingDomainPassword": { "value": "[parameters('existingDomainPassword')]" }, "subnet-id": { "value": "[variables('subnet-id')]" }, "vhds": { "value": "[variables('vhds')]" }, "rdshImageSourceResourceGroup": { "value": "[parameters('rdshCustomImageSourceResourceGroup')]" }, "rdshImageSourceName": { "value": "[parameters('rdshCustomImageSourceName')]" }, "location": { "value": "[parameters('location')]" }, "enablePersistentDesktop": { "value": "[parameters('enablePersistentDesktop')]" } } } }, { "apiVersion": "2018-10-01", "type": "Microsoft.Compute/virtualMachines/extensions", "name": "[concat(variables('rdshPrefix'), copyindex(),'/', 'joindomain')]", "location": "[parameters('location')]", "dependsOn": [ "[variables('vmCreation-linkedTemplate_name')]" ], "copy": { "name": "rdsh-domain-join-loop", "count": "[parameters('rdshNumberOfInstances')]" }, "properties": { "publisher": "Microsoft.Compute", "type": "JsonADDomainExtension", "typeHandlerVersion": "1.3", "autoUpgradeMinorVersion": true, "settings": { "name": "[parameters('domainToJoin')]", "ouPath": "[parameters('ouPath')]", "user": "[parameters('existingDomainUPN')]", "restart": "true", "options": "3" }, "protectedSettings": { "password": "[parameters('existingDomainPassword')]" } } }, { "apiVersion": "2018-10-01", "type": "Microsoft.Compute/virtualMachines/extensions", "name": "[concat(variables('rdshPrefix'), '0/', 'dscextension')]", "location": "[parameters('location')]", "dependsOn": [ "rdsh-domain-join-loop" ], "properties": { "publisher": "Microsoft.Powershell", "type": "DSC", "typeHandlerVersion": "2.73", "autoUpgradeMinorVersion": true, "settings": { "modulesUrl": "[uri(parameters('_artifactsLocation'), concat('DSC/Configuration.zip', parameters('_artifactsLocationSasToken')))]", "configurationFunction": "Configuration.ps1\\FirstSessionHost", "properties": { "TenantAdminCredentials": { "userName": "[parameters('tenantAdminUpnOrApplicationId')]", "password": "PrivateSettingsRef:tenantAdminPassword" }, "RDBrokerURL": "[parameters('rdBrokerURL')]", "DefinedTenantGroupName": "[parameters('existingTenantGroupName')]", "TenantName": "[variables('existingTenantName')]", "HostPoolName": "[variables('hostPoolName')]", "Description": "[variables('hostPoolDescription')]", "FriendlyName": "[variables('hostPoolFriendlyName')]", "Hours": "[variables('registrationExpirationHours')]", "isServicePrincipal": "[parameters('isServicePrincipal')]", "AadTenantId": "[parameters('aadTenantId')]", "EnablePersistentDesktop": "[parameters('enablePersistentDesktop')]", "defaultDesktopUsers": "[concat('\"',parameters('defaultDesktopUsers'),'\"')]" } }, "ProtectedSettings": { "items": { "tenantAdminPassword": "[parameters('tenantAdminPassword')]" } } } }, { "condition": "[greater(parameters('rdshNumberOfInstances'),1)]", "apiVersion": "2018-10-01", "type": "Microsoft.Compute/virtualMachines/extensions", "name": "[concat(variables('rdshPrefix'), copyindex(1),'/', 'dscextension')]", "location": "[parameters('location')]", "dependsOn": [ "[concat('Microsoft.Compute/virtualMachines/', variables('rdshPrefix'),'0/extensions/dscextension')]" ], "copy": { "name": "additional-rdsh-dsc-loop", "count": "[if(greater(parameters('rdshNumberOfInstances'),1),sub(parameters('rdshNumberOfInstances'),1),1)]" }, "properties": { "publisher": "Microsoft.Powershell", "type": "DSC", "typeHandlerVersion": "2.73", "autoUpgradeMinorVersion": true, "settings": { "modulesUrl": "[uri(parameters('_artifactsLocation'), concat('DSC/Configuration.zip', parameters('_artifactsLocationSasToken')))]", "configurationFunction": "Configuration.ps1\\AdditionalSessionHosts", "properties": { "TenantAdminCredentials": { "userName": "[parameters('tenantAdminUpnOrApplicationId')]", "password": "PrivateSettingsRef:tenantAdminPassword" }, "RDBrokerURL": "[parameters('rdBrokerURL')]", "DefinedTenantGroupName": "[parameters('existingTenantGroupName')]", "TenantName": "[variables('existingTenantName')]", "HostPoolName": "[variables('hostPoolName')]", "Hours": "[variables('registrationExpirationHours')]", "isServicePrincipal": "[parameters('isServicePrincipal')]", "AadTenantId": "[parameters('aadTenantId')]" } }, "ProtectedSettings": { "items": { "tenantAdminPassword": "[parameters('tenantAdminPassword')]" } } } } ], "outputs": { "rdshVmNamesObject": { "value": "[variables('rdshVmNamesOutput')]", "type": "object" } } }