Archive | Azure Virtual Desktop RSS feed for this section

App Volumes for Azure Virtual Desktop and Windows 365 Cloud PC

4 Dec

Recently the Apps on demand was released, essentially this an Azure market place offering from VMware aka Broadcom. You can deploy App Volumes manager virtual machine that runs Windows Server 2022 with App Volumes Manager pre-installed. Additionally, deploy Azure file share and database configuration.

What is an AppStack

An AppStack in VMware App Volumes is a virtual container that contains a set of applications packaged together. It’s used in virtual desktop environments such as (AVD and Windows 365) to dynamically deliver these applications to users. AppStacks are read-only, can be attached to user sessions transparently, and appear as if the applications are natively installed. They offer efficient application management, allowing for easy updates and maintenance without impacting the underlying system. This approach simplifies application lifecycle management and enhances user experience in virtualized desktop scenarios.

Prerequisites

You’ll need the following things ready before you can rollout App Volumes:

  • Azure Subscription: Have an active Microsoft Azure subscription. Azure Documentation
  • Azure Permissions: Ensure permissions to create virtual machines for App Volumes Manager, storage accounts, and file shares on Azure.
  • Access to On-Prem Active Directory: Required for identity and access control.
  • Azure Virtual Desktop Access: For remote connectivity.
  • Azure AD Connect: Install Azure AD Connect on the Active Directory Domain Controller.
  • Active Directory Configurations:
  • App Volumes License File: Download and install the App Volumes license file. App Volumes in Azure follows a Bring Your Own License model. VMware App Volumes Product Download Page
  • Download App Volumes Agent:
  • System Requirements Awareness: Familiarize yourself with the system requirements for using App Volumes. VMware App Volumes 4 Installation Guide
  • SQL Server Database for Production: For a production environment, ensure the availability of an existing SQL server database, as the default SQL Server Express Database is not recommended for production use.

My party came crashing on the requirement of Active Directory (AD) Domain Controller. In my entire Azure, Azure Virtual Desktop, Windows 365 Cloud PC and Microsoft Intune I have made deliberate choice to keep it with mordern management\authentication and follow the Microsoft best practice guidance. Though I am not able to complete the entire configurations due to AD I decided to share whatever configurations I manage to perform to deploy the AV Manager appliance within my Azure subscription for this blog post.

Starting in the Azure Portal

  • Access the Marketplace: Begin by navigating to the Microsoft Azure portal and clicking on ‘Marketplace’.
  • Find VMware App Volumes: Search for the ‘VMware App Volumes’ offer and click on it.
  • Select App Volumes Version: In the VMware App Volumes Azure Application page, choose the desired version from the Plan drop-down box.
  • Click ‘Create’

Deploy the Virtual Machine Appliance

  • Details: Select your Subscription and Resource group. You can also create a new resource group if needed.
  • Instance Details: Choose the Region and enter the name for your virtual machine. Set up the credentials for the local administrator. (#TIP – Ensure you deploy the Appliance where the session host pools are located)
  • Public IP Address: A new public IP address is created by default, but you can opt for an existing one or none at all. (#TIP – This allows accessing the App Volumes Manager over the internet )
  • DNS Prefix: If using a public IP address, consider creating a DNS prefix for easier access. (#TIP – Pick a friendly name I decided to leave it as defaults)
  • By default, a new virtual network and subnet are created. However, in my situation, I want to leverage the existing VNET and Subnet.
  • Database Selection: Choose between a Local SQL Server Express Database (not recommended for production) or a Remote SQL Server database. Enter the necessary database connection details. (#TIP – Explore for production use evaluate using the Azure SQL DB as its a managed SQL instance and you will not have the overhead of managing and maintaining a SQL Server)
  • File Share Configuration: Decide if you want Azure Marketplace to automatically provision storage with file shares or use existing storage. Configure accordingly. (#TIP – Same if you have Azure Dell or NetApp Files storage you can leverage that or using Azure storage account)
  • Tags: Add any desired tags. (#TIP – Ensure you add the tags as it will help you later during Billing and Automation)
  • Review and Launch Deployment: Review your setting Click ‘Create’ to start the deployment process.
  • Navigate to App Volumes Manager Admin UI: This is where you’ll configure Active Directory and other settings.
  • Configure Storage: If you opted out of automatic storage provisioning, manually configure the storage in the App Volumes Manager admin UI.
  • When you navigate to the Storage the newly created SMB shares are listed for templates and AppStacks stroage.

I will come back to this blog post once I learn more about the “No AD” mode as this will enable me to further integrate App Volumes into my Azure Virtual Desktop and Windows 365 Cloud PCs.

Resources deployed within the Azure Resource Group

Following resources are deployed within your Azure Resource Group for App Volumes

Whislist

I would like to see the following enhacements at a later day:

  • VMware aka Broadcom should evlaute a complete SaaS offering taking it to the next level instead of deploying an appliance and required to do alot of configuration. Just give me “as a Service” and the only responsiblity is to create/update and mange the applications with Entra ID Groups.
  • Microsoft Entra ID integration is a must

I hope you will find this helpful information for getting started with App Volumes for Windows 365 Cloud PC and Azure Virtual Desktop. Please let me know if I have missed any steps or details, and I will be happy to update the post.

Thanks,
Aresh Sarkari

Azure Virtual Desktop – Terraform – Create a Scaling Plan for Pooled Host Pools (Part 4)

27 Oct

In today’s digital age, managing cloud resources efficiently is paramount, not just for operational efficacy but also for cost management. Enter Azure Virtual Desktop (AVD) Scaling Plans – Microsoft’s answer to dynamic and intelligent scaling of your virtual desktop infrastructure. No longer do organizations need to overprovision resources or let them sit idle; with AVD Scaling Plans, you get a responsive environment tailored to your usage patterns. In this blog post, we’ll create the scaling plans using Terraform.

In the previous blog post, we delved into the distinctions between the Personal Desktop (1:1 mapping), Pooled Desktop (1:Many mapping) and Remote App configurations, providing a comprehensive guide on their creation via Terraform. The series continues as we further explore how to create the AVD Scaling Plan for Pooled Host Pool.

Table of Content

Pre-requisites

Following are the pre-requisites before you begin

  • An Azure subscription
  • The Terraform CLI
  • The Azure CLI
  • Permissions within the Azure Subscription for using Terraform

Terraform – Authenticating via Service Principal & Client Secret

Before running any Terraform code, we will execute the following PowerShell (Run as administrator)and store the credentials as environment variables. If we do this via the environment variable, we don’t have to keep the below information within the providers.tf file. In a future blog post, there are better ways to store the below details, and I hope to showcase them:

# PowerShell
$env:ARM_CLIENT_ID = "9e453b62-0000-0000-0000-00000006e1ac"
$env:ARM_CLIENT_SECRET = "Z318Q~00000000000000000000000000000000_"
$env:ARM_TENANT_ID = "a02e602c-0000-000-0000-0e0000008bba61"
$env:ARM_SUBSCRIPTION_ID = "7b051460-00000-00000-00000-000000ecb1"
  • Azure Subcription ID – Azure Portal Subcription copy the ID
  • Client ID – From the above step you will have the details
  • Client Secret – From the above step you will have the details
  • Tenant ID – While creating the Enterprise Apps in ADD you will have the details

Terraform Folder Structure

The following is the folder structure for the terrraform code:

Azure Virtual Desktop Scaling Plan – Create a directory in which the below Terraform code will be published (providers.tf, main.tf, variables.tf and output.tf)

+---Config-AVD-ScalingPlans
|   |   main.tf
|   |   output.tf
|   |   providers.tf
|   |   variables.tf

Configure AVD – ScalingPlans – Providers.tf

Create a file named providers.tf and insert the following code:

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "3.76.0"
    }
    azuread = {
      source = "hashicorp/azuread"
    }
  }
}

provider "azurerm" {
  features {}
}

Configure AVD – ScalingPlans – main.tf

Create a file named main.tf and insert the following code. Let me explain what all we are attempting to accomplish here:

  • Leverage a existing Resource Group
  • Leverage a existing Host Pool
  • Create a custom role AVD AutoScale and assign to the Resource Group
    • This is a prerequisite for ensuring the scaling plan can increase and decrease the resources in your resource group.
  • Assign the role – AVD AutoScale to the service principal (AVD)
  • Create a a scaling plan with a production grade schedule
  • Associate the scaling plan with the host pool
# Generate a random UUID for role assignment
resource "random_uuid" "example" {}

# Fetch details of the existing Azure Resource Group
data "azurerm_resource_group" "example" {
  name = var.resource_group_name
}

# Fetch details of the existing Azure Virtual Desktop Host Pool
data "azurerm_virtual_desktop_host_pool" "existing" {
  name                = var.existing_host_pool_name
  resource_group_name = var.resource_group_name
}

# Define the Azure Role Definition for AVD AutoScale
resource "azurerm_role_definition" "example" {
  name        = "AVD-AutoScale"
  scope       = data.azurerm_resource_group.example.id
  description = "AVD AutoScale Role"
  # Define the permissions for this role
  permissions {
    actions = [
      # List of required permissions.
      "Microsoft.Insights/eventtypes/values/read",
      "Microsoft.Compute/virtualMachines/deallocate/action",
      "Microsoft.Compute/virtualMachines/restart/action",
      "Microsoft.Compute/virtualMachines/powerOff/action",
      "Microsoft.Compute/virtualMachines/start/action",
      "Microsoft.Compute/virtualMachines/read",
      "Microsoft.DesktopVirtualization/hostpools/read",
      "Microsoft.DesktopVirtualization/hostpools/write",
      "Microsoft.DesktopVirtualization/hostpools/sessionhosts/read",
      "Microsoft.DesktopVirtualization/hostpools/sessionhosts/write",
      "Microsoft.DesktopVirtualization/hostpools/sessionhosts/usersessions/delete",
      "Microsoft.DesktopVirtualization/hostpools/sessionhosts/usersessions/read",
      "Microsoft.DesktopVirtualization/hostpools/sessionhosts/usersessions/sendMessage/action",
      "Microsoft.DesktopVirtualization/hostpools/sessionhosts/usersessions/read"
    ]
    not_actions = []
  }
  assignable_scopes = [
    data.azurerm_resource_group.example.id,
  ]
}

# Fetch the Azure AD Service Principal for Windows Virtual Desktop
data "azuread_service_principal" "example" {
  display_name = "Azure Virtual Desktop"
}

# Assign the role to the service principal
resource "azurerm_role_assignment" "example" {
  name                   = random_uuid.example.result
  scope                  = data.azurerm_resource_group.example.id
  role_definition_id     = azurerm_role_definition.example.role_definition_resource_id
  principal_id           = data.azuread_service_principal.example.id
  skip_service_principal_aad_check = true
}

# Define the Azure Virtual Desktop Scaling Plan
resource "azurerm_virtual_desktop_scaling_plan" "example" {
  name                = var.scaling_plan_name
  location            = var.location
  resource_group_name = var.resource_group_name
  friendly_name       = var.friendly_name
  description         = var.scaling_plan_description
  time_zone           = var.timezone
  tags = var.tags

  dynamic "schedule" {
    for_each = var.schedules
    content {
      name                              = schedule.value.name
      days_of_week                      = schedule.value.days_of_week
      ramp_up_start_time                = schedule.value.ramp_up_start_time
      ramp_up_load_balancing_algorithm  = schedule.value.ramp_up_load_balancing_algorithm
      ramp_up_minimum_hosts_percent     = schedule.value.ramp_up_minimum_hosts_percent
      ramp_up_capacity_threshold_percent= schedule.value.ramp_up_capacity_threshold_pct
      peak_start_time                   = schedule.value.peak_start_time
      peak_load_balancing_algorithm     = schedule.value.peak_load_balancing_algorithm
      ramp_down_start_time              = schedule.value.ramp_down_start_time
      ramp_down_load_balancing_algorithm= schedule.value.ramp_down_load_balancing_algorithm
      ramp_down_minimum_hosts_percent   = schedule.value.ramp_down_minimum_hosts_percent
      ramp_down_force_logoff_users      = schedule.value.ramp_down_force_logoff_users
      ramp_down_wait_time_minutes       = schedule.value.ramp_down_wait_time_minutes
      ramp_down_notification_message    = schedule.value.ramp_down_notification_message
      ramp_down_capacity_threshold_percent = schedule.value.ramp_down_capacity_threshold_pct
      ramp_down_stop_hosts_when         = schedule.value.ramp_down_stop_hosts_when
      off_peak_start_time               = schedule.value.off_peak_start_time
      off_peak_load_balancing_algorithm = schedule.value.off_peak_load_balancing_algorithm
    }
  }
  
  # Associate the scaling plan with the host pool
  host_pool {
    hostpool_id          = data.azurerm_virtual_desktop_host_pool.existing.id
    scaling_plan_enabled = true
  }
}

Configure AVD – ScalingPlans – variables.tf

Create a file named variables.tf and insert the following code. The place where we define existing or new variables:

# Define the resource group of the Azure Virtual Desktop Scaling Plan
variable "resource_group_name" {
  description = "The name of the resource group."
  type        = string
  default     = "AE-DEV-AVD-01-PO-D-RG"
}

# Define the attributes of the Azure Virtual Desktop Scaling Plan
variable "scaling_plan_name" {
  description = "The name of the Scaling plan to be created."
  type        = string
  default     = "AVD-RA-HP-01-SP-01"
}

# Define the description of the scaling plan
variable "scaling_plan_description" {
  description = "The description of the Scaling plan to be created."
  type        = string
  default     = "AVD Host Pool Scaling plan"
}

# Define the timezone of the Azure Virtual Desktop Scaling Plan
variable "timezone" {
  description = "Scaling plan autoscaling triggers and Start/Stop actions will execute in the time zone selected."
  type        = string
  default     = "AUS Eastern Standard Time"
}

# Define the freindlyname of the Azure Virtual Desktop Scaling Plan
variable "friendly_name" {
  description = "The friendly name of the Scaling plan to be created."
  type        = string
  default     = "AVD-RA-HP-SP-01"
}

# Define the host pool type(Pooled or Dedicated) of the Azure Virtual Desktop Scaling Plan
variable "host_pool_type" {
  description = "The host pool type of the Scaling plan to be created."
  type        = string
  default     = "Pooled"
}

# Define the details of the scaling plan schedule
variable "schedules" {
  description = "The schedules of the Scaling plan to be created."
  type        = list(object({
    name                          = string
    days_of_week                  = list(string)
    ramp_up_start_time            = string
    ramp_up_load_balancing_algorithm = string
    ramp_up_minimum_hosts_percent = number
    ramp_up_capacity_threshold_pct = number
    peak_start_time               = string
    peak_load_balancing_algorithm = string
    ramp_down_start_time          = string
    ramp_down_load_balancing_algorithm = string
    ramp_down_minimum_hosts_percent = number
    ramp_down_capacity_threshold_pct = number
    ramp_down_wait_time_minutes   = number
    ramp_down_stop_hosts_when     = string
    ramp_down_notification_message = string
    off_peak_start_time           = string
    off_peak_load_balancing_algorithm = string
    ramp_down_force_logoff_users  = bool
  }))
  default = [
    {
      name = "weekdays_schedule"
      days_of_week = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]
      ramp_up_start_time = "08:00"
      ramp_up_load_balancing_algorithm = "BreadthFirst"
      ramp_up_minimum_hosts_percent = 20
      ramp_up_capacity_threshold_pct = 60
      peak_start_time = "09:00"
      peak_load_balancing_algorithm = "DepthFirst"
      ramp_down_start_time = "18:00"
      ramp_down_load_balancing_algorithm = "DepthFirst"
      ramp_down_minimum_hosts_percent = 10
      ramp_down_capacity_threshold_pct = 90
      ramp_down_wait_time_minutes = 30
      ramp_down_stop_hosts_when = "ZeroActiveSessions"
      ramp_down_notification_message = "You will be logged off in 30 min. Make sure to save your work."
      off_peak_start_time = "20:00"
      off_peak_load_balancing_algorithm = "DepthFirst"
      ramp_down_force_logoff_users = false
    }
  ]
}

# Define the location of the Azure Virtual Desktop Scaling Plan
variable "location" {
  description = "The location where the resources will be deployed."
  type        = string
  default     = "australiaeast"
}

# Define the tags of the Azure Virtual Desktop Scaling Plan
variable "tags" {
  description = "The tags to be assigned to the Scaling plan."
  type        = map(string)
  default     = {
    "Billing" = "IT"
    "Department" = "IT"
    "Location" = "AUS-East"
  }
}

# Define the name of the Azure Virtual Desktop Host Pool
variable "existing_host_pool_name" {
  description = "The name of the existing Azure Virtual Desktop Host Pool."
  type        = string
  default     = "AE-DEV-AVD-01-PO-D-HP"
}

Configure AVD – ScalingPlans – output.tf

Create a file named output.tf and insert the following code. This will showcase in the console what is getting deployed in form of a output.

# Output the ID of the Azure Virtual Desktop Scaling Plan
output "scaling_plan_id" {
  description = "The ID of the Virtual Desktop Scaling Plan."
  value       = azurerm_virtual_desktop_scaling_plan.example.id
}

Intialize Terraform – AVD – ScalingPlans

Run terraform init to initialize the Terraform deployment. This command downloads the Azure provider required to manage your Azure resources. (Its pulling the AzureRM and AzureAD)

terraform init -upgrade

Create Terraform Execution Plan – AVD – ScalingPlans

Run terraform plan to create an execution plan.

terraform plan -out scaleplan.tfplan

Apply Terraform Execution Plan – AVD – ScalingPlans

Run terraform apply to apply the execution plan to your cloud infrastructure.

terraform apply "scaleplan.tfplan"

Validate the Output in Azure Portal

Go to the Azure portal, Select Azure Virtual Desktop and Select Scaling Plans and validate all the details such as Host Pool Assignment and Schedule:

Clean-up the above resources (Optional)

If you want to delete all the above resources then you can use the following commands to destroy. Run terraform plan and specify the destroy flag.

terraform plan -destroy -out scaleplan.destory.tfplan
terraform apply "scaleplan.destory.tfplan"

The intention here is to get you quickly started with Terraform on Azure Virtual Desktop Solution:

DescriptionLinks
Create an autoscale scaling plan for Azure Virtual DesktopCreate an autoscale scaling plan for Azure Virtual Desktop | Microsoft Learn
Setting up your computer to get started with Terrafor using PowershellInstall Terraform on Windows with Azure PowerShell
AVD Configure Azure Virtual Desktophttps://learn.microsoft.com/en-us/azure/developer/terraform/configure-azure-virtual-desktop
Terraform Learninghttps://youtube.com/playlist?list=PLLc2nQDXYMHowSZ4Lkq2jnZ0gsJL3ArAw

I hope you will find this helpful information for getting started with Terraform to deploy the Azure Virtual Desktop – Scaling Plans. Please let me know if I have missed any steps or details, and I will be happy to update the post.

Thanks,
Aresh Sarkari

Watermarking & Session Capture Protection in Azure Virtual Desktop using Microsoft Intune and Azure AD Joined devices

31 Aug

In the July 2023 release for Azure Virtual Desktop, the Watermarking and Session capture protection features became generally available. Numerous blog posts already showcase how to enable the feature using Group Policy. In today’s post, I will showcase how to enable Watermarking and Session Capture protection using Microsoft Intune for Session Host Virtual machines that are Azure AD joined.

Prerequisites

You’ll need the following things ready before you can rollout watermarking/session capture protection:

  • Azure Virtual Desktop: You must have Azure Virtual Desktop deployed (Pooled or Personal Desktops) and set up in your Azure environment.
  • Microsoft Intune: You should have an active subscription to Microsoft Intune, which is a cloud-based service that enables device management and security. The role within Intune Portal for creating and assigning the configuration profiles is – Policy and Profile manager built-in role-based access control (RBAC) role.
  • Azure Active Directory: Your Azure Virtual Desktop environment should be integrated with Azure Active Directory (AD) (The Host pools RDP properties – targetisaadjoined:i:1). The AAD Security groups must be in place, which has the members as the session’s host in AVD.
  • Azure AD Joined Devices: The session host virtual machines (VMs) you want to enable Watermarking and Session Capture protection for should be Azure AD joined. This means they must be connected to Azure AD and registered as members of your organization’s directory.
  • Admin Access: You need administrative access to the Azure portal (https://portal.azure.com) and Microsoft Intune (https://intune.microsoft.com).
  • Windows 11 operating system for the client along with the Azure Virtual Desktop Client or Remote Desktop Client versions 1.2.x and higher

Configuration Profiles – Intune

To enable the Watermarking and Session Capture protection features in Azure Virtual Desktop using Microsoft Intune Configuration profiles and Azure AD joined devices, you can follow these steps:

  • In the settings picker, browse to Administrative templates > Windows Components > Remote Desktop Services > Remote Desktop Session Host > Azure Virtual Desktop. You should see settings in the Azure Virtual Desktop subcategory available for you to configure, such as “Enable watermarking” and “Enable screen capture protection”
  • Select the “Enable screen capture protection” settings, too and leave the values as defaults. (Feel free to tweak it based on your requirements)
  • Assigning the configuration to the AAD group, which has all the session host devices
  • Reboot the session host after applying or wait until the next maintenance cycle

Client Validation

Connect to a remote session with a supported client (Azure Virtual Desktop Client or Remote Desktop Client versions 1.2.x), where you should see QR codes appear.

The QR code only works for Windows 11 Multi-session\Windows 11 Enterprise (pooled or personal desktops). The RemoteApps will not show the QR code as its not supported.

Screenshot protection – In the session, it will be completely blank if you try to take a screenshot. Below is an example. I was trying to take a screenshot of the text file, and the screenshot was completely blank.

Mobile Phone Photo

When you try to take a screenshot from the mobile phone, this is how it will look, and it will pop the Connection ID. You have this connection ID you can match in Azure Insights.

Azure Virtual Desktop Insights

To find out the session information from the QR code by using Azure Virtual Desktop Insights:

  1. Open a web browser and go to https://aka.ms/avdi to open Azure Virtual Desktop Insights. Sign-in using your Azure credentials when prompted.
  2. Select the relevant subscription, resource group, host pool and time range, then select the Connection Diagnostics tab.
  3. In the section Success rate of (re)establishing a connection (% of connections), there’s a list of all connections showing First attemptConnection IdUser, and Attempts. You can look for the connection ID from the QR code in this list, or export to Excel.

I hope you will find this helpful information for getting started with Watermarking and Screenshot protection for the Azure Virtual Desktop – Session Host. Please let me know if I have missed any steps or details, and I will be happy to update the post.

Thanks,
Aresh Sarkari

Azure Virtual Desktop – Terraform – Create a Host Pool, Desktop Application Group and Workspace for Pooled Remote App aka Published Applications (Part 3)

15 May

In the previous blog post we look at creating the Personal Desktop (1×1 mapping) and Pooled Desktop (1 x Many) using Terraform Azure Virtual Desktop – Terraform – Create a Host Pool, Desktop Application Group and Workspace for Personal Desktop (Part 1) | AskAresh and Azure Virtual Desktop – Terraform – Create a Host Pool, Desktop Application Group and Workspace for Pooled Desktop (Part 2). In this blog post series I am going to demonstrate how to create the AVD Host Pool, Application Group and Workspace using Terraform for Pooled Remote App aka Published Applications (1xMany)

We are going to create the following three types of configurations using Terraform:

  • Azure Virtual Desktop – Personal Desktop (1×1) – Part 1
  • Azure Virtual Desktop – Pooled Desktop (Multi-Session Full Desktop Experience) – Part 2
  • Azure Virtual Desktop – Remote App (Multi-Session Application aka Published Apps) – Part 3

Note – We are creating the Pooled RemoteApp in this post and in the subsequent post the other types were. In this post In this post I will not show case the creation of service principal and secret please refer for the Part 1 for that activity.

Pre-requisites

Following are the pre-requisites before you begin

  • An Azure subscription
  • The Terraform CLI
  • The Azure CLI
  • Permissions within the Azure Subscription for using Terraform

Terraform – Authenticating via Service Principal & Client Secret

Before running any Terraform code the following powershell (Make sure run as administrator) we will execute and store the credentials as enviornment variables. If we do this via the environment variable we dont have to store the below information within the providers.tf file. In the future blog post there are better way to store the below details and I hope to showcase them:

# PowerShell
$env:ARM_CLIENT_ID = "9e453b62-0000-0000-0000-00000006e1ac"
$env:ARM_CLIENT_SECRET = "Z318Q~00000000000000000000000000000000_"
$env:ARM_TENANT_ID = "a02e602c-0000-000-0000-0e0000008bba61"
$env:ARM_SUBSCRIPTION_ID = "7b051460-00000-00000-00000-000000ecb1"
  • Azure Subcription ID – Azure Portal Subcription copy the ID
  • Client ID – From the above step you will have the details
  • Client Secret – From the above step you will have the details
  • Tenant ID – While creating the Enterprise Apps in ADD you will have the details

Terraform Folder Structure

The following is the folder structure for the terrraform code:

Azure Virtual Desktop Pooled RemoteApp – Create a directory in which the below Terraform code will be published (providers.tf, main.tf, variables.tf and output.tf)

+---Config-AVD-Pooled-RemoteApp
|   |   main.tf
|   |   output.tf
|   |   providers.tf
|   |   variables.tf

Configure AVD – Pooled RemoteApp – Providers.tf

Create a file named providers.tf and insert the following code:

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "3.49.0"
    }
    azuread = {
      source = "hashicorp/azuread"
    }
  }
}

provider "azurerm" {
  features {}
}

Configure AVD – Pooled RemoteApp – main.tf

Create a file named main.tf and insert the following code. Let me explain what all we are attempting to accomplish here:

  • Create a Resource Group
  • Create a Workspace
  • Create a Host Pool
  • Create a Remote Application Group (RAG)
  • Associate Workspace and RAG
  • Assign Azure AD Group to the Desktop Application Group (RAG)
  • Assign Azure AD Group to the Resource Group for RBAC for the Session Host (Virtual Machine User Login)
# Resource group name is output when execution plan is applied.
resource "azurerm_resource_group" "rg" {
  name     = var.rg_name
  location = var.resource_group_location
  tags = var.tags
}

# Create AVD workspace
resource "azurerm_virtual_desktop_workspace" "workspace" {
  name                = var.workspace
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  friendly_name       = "${var.prefix} Workspace"
  description         = "${var.prefix} Workspace"
  tags = var.tags
}

# Create AVD host pool
resource "azurerm_virtual_desktop_host_pool" "hostpool" {
  resource_group_name      = azurerm_resource_group.rg.name
  location                 = azurerm_resource_group.rg.location
  name                     = var.hostpool
  friendly_name            = var.hostpool
  validate_environment     = true #[true false]
  start_vm_on_connect      = true
  custom_rdp_properties    = "targetisaadjoined:i:1;drivestoredirect:s:*;audiomode:i:0;videoplaybackmode:i:1;redirectclipboard:i:1;redirectprinters:i:1;devicestoredirect:s:*;redirectcomports:i:1;redirectsmartcards:i:1;usbdevicestoredirect:s:*;enablecredsspsupport:i:1;redirectwebauthn:i:1;use multimon:i:1;enablerdsaadauth:i:1;"
  description              = "${var.prefix} HostPool"
  type                     = "Pooled" #[Pooled or Personal]
  preferred_app_group_type = "RailApplications" #[Desktop or RailApplications]
  maximum_sessions_allowed = 5  #[Tweak based on your vm tshirt size]
  load_balancer_type       = "DepthFirst" #[BreadthFirst or DepthFirst]
  tags = var.tags
scheduled_agent_updates {
  enabled = true
  timezone = "AUS Eastern Standard Time"  # Update this value with your desired timezone
  schedule {
    day_of_week = "Saturday"
    hour_of_day = 1   #[1 here means 1:00 am]
  }
}
}

resource "azurerm_virtual_desktop_host_pool_registration_info" "registrationinfo" {
  hostpool_id     = azurerm_virtual_desktop_host_pool.hostpool.id
  expiration_date = var.rfc3339
}

# Create AVD RAG
resource "azurerm_virtual_desktop_application_group" "rag" {
  resource_group_name = azurerm_resource_group.rg.name
  host_pool_id        = azurerm_virtual_desktop_host_pool.hostpool.id
  location            = azurerm_resource_group.rg.location
  type                = "RemoteApp"
  name                = var.app_group_name
  friendly_name       = "RemoteApp AppGroup"
  description         = "${var.prefix} AVD RemoteApp application group"
  depends_on          = [azurerm_virtual_desktop_host_pool.hostpool, azurerm_virtual_desktop_workspace.workspace]
  tags = var.tags
}

# Associate Workspace and DAG
resource "azurerm_virtual_desktop_workspace_application_group_association" "ws-dag" {
  application_group_id = azurerm_virtual_desktop_application_group.rag.id
  workspace_id         = azurerm_virtual_desktop_workspace.workspace.id
}

# Assign AAD Group to the Remote Application Group (RAG)
resource "azurerm_role_assignment" "AVDGroupRemoteAppAssignment" {
  scope                = azurerm_virtual_desktop_application_group.rag.id
  role_definition_name = "Desktop Virtualization User"
  principal_id         = data.azuread_group.AVDGroup.object_id
}

# Assign AAD Group to the Resource Group for RBAC for the Session Host
resource "azurerm_role_assignment" "RBACAssignment" {
  scope                = azurerm_resource_group.rg.id
  role_definition_name = "Virtual Machine User Login"
  principal_id         = data.azuread_group.AVDGroup.object_id
}

Note – The individual applications are not published yet. They can be published once you have the session host created. After which, using Terraform, the individual applications can be published too. The exe path of apps needs to be mapped within the operating system. I plan to create a separate blog post on session host creation via Terraform.

Configure AVD – Pooled RemoteApp – variables.tf

Create a file named variables.tf and insert the following code:

variable "resource_group_location" {
  default     = "australiaeast"
  description = "Location of the resource group - Australia East"
}

variable "rg_name" {
  type        = string
  default     = "AE-DEV-AVD-01-PO-A-RG"
  description = "Name of the Resource group in which to deploy service objects"
}

variable "workspace" {
  type        = string
  description = "Name of the Azure Virtual Desktop workspace"
  default     = "AE-DEV-AVD-01-WS"
}

variable "hostpool" {
  type        = string
  description = "Name of the Azure Virtual Desktop host pool"
  default     = "AE-DEV-AVD-01-PO-A-HP"
}

variable "app_group_name" {
  description = "Name of the Azure Virtual Desktop application group"
  type        = string
  default     = "AE-DEV-AVD-01-RAG"
}

variable "rfc3339" {
  type        = string
  default     = "2023-05-20T12:43:13Z"  #Update this value with a future date
  description = "Registration token expiration"
}

variable "prefix" {
  type        = string
  default     = "AE-DEV-AVD-01-HP-"
  description = "Prefix of the name of the AVD HostPools"
}

variable "tags" {
  type    = map(string)
  default = {
    Environment = "Dev"
    Department  = "IT"
    Location = "AustraliaEast"
    ServiceClass = "DEV"
    Workload = "Host Pool 01"
  }
}

data "azuread_client_config" "AzureAD" {}

data "azuread_group" "AVDGroup" {
  display_name     = "Win365-Users"  
}

Configure AVD – Pooled RemoteApp – output.tf

Create a file named output.tf and insert the following code. This will showcase in the console what is getting deployed in form of a output.

output "azure_virtual_desktop_compute_resource_group" {
  description = "Name of the Resource group in which to deploy session host"
  value       = azurerm_resource_group.rg.name
}

output "azure_virtual_desktop_host_pool" {
  description = "Name of the Azure Virtual Desktop host pool"
  value       = azurerm_virtual_desktop_host_pool.hostpool.name
}

output "azurerm_virtual_desktop_application_group" {
  description = "Name of the Azure Virtual Desktop DAG"
  value       = azurerm_virtual_desktop_application_group.rag.name
}

output "azurerm_virtual_desktop_workspace" {
  description = "Name of the Azure Virtual Desktop workspace"
  value       = azurerm_virtual_desktop_workspace.workspace.name
}

output "location" {
  description = "The Azure region"
  value       = azurerm_resource_group.rg.location
}

data "azuread_group" "aad_group" {
  display_name = "Win365-Users"
}

output "AVD_user_groupname" {
  description = "Azure Active Directory Group for AVD users"
  value       = data.azuread_group.aad_group.display_name
}

Intialize Terraform – AVD – Pooled RemoteApp

Run terraform init to initialize the Terraform deployment. This command downloads the Azure provider required to manage your Azure resources. (Its pulling the AzureRM and AzureAD)

terraform init -upgrade

Create Terraform Execution Plan – AVD – Pooled RemoteApp

Run terraform plan to create an execution plan.

terraform plan -out mainavdremoteapp.tfplan

Apply Terraform Execution Plan – AVD – Pooled RemoteApp

Run terraform apply to apply the execution plan to your cloud infrastructure.

terraform apply mainavdremoteapp.tfplan

Validate the Output in Azure Portal

Go to the Azure portal, Select Azure Virtual Desktop and Select Host pools, Application Group and Workspace created using Terraform.

Clean-up the above resources (Optional)

If you want to delete all the above resources then you can use the following commands to destroy. Run terraform plan and specify the destroy flag.

terraform plan -destroy -out mainavdremoteapp.destroy.tfplan

Run terraform apply to apply the execution plan.

terraform apply mainavdremoteapp.destroy.tfplan

The intention here is to get you quickly started with Terraform on Azure Virtual Desktop Solution:

DescriptionLinks
Setting up your computer to get started with Terrafor using PowershellInstall Terraform on Windows with Azure PowerShell
AVD Configure Azure Virtual Desktophttps://learn.microsoft.com/en-us/azure/developer/terraform/configure-azure-virtual-desktop
Terraform Learninghttps://youtube.com/playlist?list=PLLc2nQDXYMHowSZ4Lkq2jnZ0gsJL3ArAw

I hope you will find this helpful information for getting started with Terraform to deploy the Azure Virtual Desktop – Pooled Remote App. Please let me know if I have missed any steps or details, and I will be happy to update the post.

Thanks,
Aresh Sarkari

Azure Virtual Desktop – Terraform – Create a Host Pool, Desktop Application Group and Workspace for Pooled Desktop (Part 2)

15 May

In the previous blog post we look at creating the Personal Desktop (1×1 mapping) using Terraform. Azure Virtual Desktop – Terraform – Create a Host Pool, Desktop Application Group and Workspace for Personal Desktop (Part 1) | AskAresh. In this blog post series I am going to demonstrate how to create the AVD Host Pool, Application Group and Workspace using Terraform for Pooled Desktop (1xMany)

We are going to create the following three types of configurations using Terraform:

  • Azure Virtual Desktop – Personal Desktop (1×1) – Part 1
  • Azure Virtual Desktop – Pooled Desktop (Multi-Session Full Desktop Experience) – Part 2
  • Azure Virtual Desktop – Remote App (Multi-Session Application aka Published Apps) – Part 3

Note – We are creating the Pooled Desktop in this post and in the subsequent post the other types will be created. In this post In this post I will not show case the creation of service principal and secret please refer for the Part 1 for that activity.

Pre-requisites

Following are the pre-requisites before you begin

  • An Azure subscription
  • The Terraform CLI
  • The Azure CLI
  • Permissions within the Azure Subscription for using Terraform

Terraform – Authenticating via Service Principal & Client Secret

Before running any Terraform code the following powershell (Make sure run as administrator) we will execute and store the credentials as enviornment variables. If we do this via the environment variable we dont have to store the below information within the providers.tf file. In the future blog post there are better way to store the below details and I hope to showcase them:

# PowerShell
$env:ARM_CLIENT_ID = "9e453b62-0000-0000-0000-00000006e1ac"
$env:ARM_CLIENT_SECRET = "Z318Q~00000000000000000000000000000000_"
$env:ARM_TENANT_ID = "a02e602c-0000-000-0000-0e0000008bba61"
$env:ARM_SUBSCRIPTION_ID = "7b051460-00000-00000-00000-000000ecb1"
  • Azure Subcription ID – Azure Portal Subcription copy the ID
  • Client ID – From the above step you will have the details
  • Client Secret – From the above step you will have the details
  • Tenant ID – While creating the Enterprise Apps in ADD you will have the details

Terraform Folder Structure

The following is the folder structure for the terrraform code:

Azure Virtual Desktop Pooled Desktop – Create a directory in which the below Terraform code will be published (providers.tf, main.tf, variables.tf and output.tf)

+---Config-AVD-Pooled-Desktop
|   |   main.tf
|   |   output.tf
|   |   providers.tf
|   |   variables.tf

Configure AVD – Pooled Desktop Pool – Providers.tf

Create a file named providers.tf and insert the following code:

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "3.49.0"
    }
    azuread = {
      source = "hashicorp/azuread"
    }
  }
}

provider "azurerm" {
  features {}
}

Configure AVD – Pooled Desktop Pool – main.tf

Create a file named main.tf and insert the following code. Let me explain what all we are attempting to accomplish here:

  • Create a Resource Group
  • Create a Workspace
  • Create a Host Pool (Pooled Desktops and Depth first load balancing)
  • Create a Desktop Application Group (DAG)
  • Associate Workspace and DAG
  • Assign Azure AD Group to the Desktop Application Group (DAG)
  • Assign Azure AD Group to the Resource Group for RBAC for the Session Host (Virtual Machine User Login)
# Resource group name is output when execution plan is applied.
resource "azurerm_resource_group" "rg" {
  name     = var.rg_name
  location = var.resource_group_location
  tags = var.tags
}

# Create AVD workspace
resource "azurerm_virtual_desktop_workspace" "workspace" {
  name                = var.workspace
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  friendly_name       = "${var.prefix} Workspace"
  description         = "${var.prefix} Workspace"
  tags = var.tags
}

# Create AVD host pool
resource "azurerm_virtual_desktop_host_pool" "hostpool" {
  resource_group_name      = azurerm_resource_group.rg.name
  location                 = azurerm_resource_group.rg.location
  name                     = var.hostpool
  friendly_name            = var.hostpool
  validate_environment     = true #[true false]
  start_vm_on_connect      = true
  custom_rdp_properties    = "targetisaadjoined:i:1;drivestoredirect:s:*;audiomode:i:0;videoplaybackmode:i:1;redirectclipboard:i:1;redirectprinters:i:1;devicestoredirect:s:*;redirectcomports:i:1;redirectsmartcards:i:1;usbdevicestoredirect:s:*;enablecredsspsupport:i:1;redirectwebauthn:i:1;use multimon:i:1;enablerdsaadauth:i:1;"
  description              = "${var.prefix} HostPool"
  type                     = "Pooled" #[Pooled or Personal]
  maximum_sessions_allowed = 5
  load_balancer_type       = "DepthFirst" #[BreadthFirst DepthFirst]
  tags = var.tags
scheduled_agent_updates {
  enabled = true
  timezone = "AUS Eastern Standard Time"  # Update this value with your desired timezone
  schedule {
    day_of_week = "Saturday"
    hour_of_day = 1   #[1 here means 1:00 am]
  }
}
}

resource "azurerm_virtual_desktop_host_pool_registration_info" "registrationinfo" {
  hostpool_id     = azurerm_virtual_desktop_host_pool.hostpool.id
  expiration_date = var.rfc3339
}

# Create AVD DAG
resource "azurerm_virtual_desktop_application_group" "dag" {
  resource_group_name = azurerm_resource_group.rg.name
  host_pool_id        = azurerm_virtual_desktop_host_pool.hostpool.id
  location            = azurerm_resource_group.rg.location
  type                = "Desktop"
  name                = var.app_group_name
  friendly_name       = "Desktop AppGroup"
  description         = "${var.prefix} AVD application group"
  depends_on          = [azurerm_virtual_desktop_host_pool.hostpool, azurerm_virtual_desktop_workspace.workspace]
  tags = var.tags
}

# Associate Workspace and DAG
resource "azurerm_virtual_desktop_workspace_application_group_association" "ws-dag" {
  application_group_id = azurerm_virtual_desktop_application_group.dag.id
  workspace_id         = azurerm_virtual_desktop_workspace.workspace.id
}

# Assign AAD Group to the Desktop Application Group (DAG)
resource "azurerm_role_assignment" "AVDGroupDesktopAssignment" {
  scope                = azurerm_virtual_desktop_application_group.dag.id
  role_definition_name = "Desktop Virtualization User"
  principal_id         = data.azuread_group.AVDGroup.object_id
}

# Assign AAD Group to the Resource Group for RBAC for the Session Host
resource "azurerm_role_assignment" "RBACAssignment" {
  scope                = azurerm_resource_group.rg.id
  role_definition_name = "Virtual Machine User Login"
  principal_id         = data.azuread_group.AVDGroup.object_id
}

Configure AVD – Pooled Desktop Pool – variables.tf

Create a file named variables.tf and insert the following code:

variable "resource_group_location" {
  default     = "australiaeast"
  description = "Location of the resource group - Australia East"
}

variable "rg_name" {
  type        = string
  default     = "AE-DEV-AVD-01-PO-D-RG"
  description = "Name of the Resource group in which to deploy service objects"
}

variable "workspace" {
  type        = string
  description = "Name of the Azure Virtual Desktop workspace"
  default     = "AE-DEV-AVD-01-WS"
}

variable "hostpool" {
  type        = string
  description = "Name of the Azure Virtual Desktop host pool"
  default     = "AE-DEV-AVD-01-PO-D-HP"
}

variable "app_group_name" {
  description = "Name of the Azure Virtual Desktop application group"
  type        = string
  default     = "AE-DEV-AVD-01-DAG"
}

variable "rfc3339" {
  type        = string
  default     = "2023-05-20T12:43:13Z"  #Update this value with a future date
  description = "Registration token expiration"
}

variable "prefix" {
  type        = string
  default     = "AE-DEV-AVD-01-HP-"
  description = "Prefix of the name of the AVD machine(s)"
}

variable "tags" {
  type    = map(string)
  default = {
    Environment = "Dev"
    Department  = "IT"
    Location = "AustraliaEast"
    ServiceClass = "DEV"
    Workload = "Host Pool 01"
  }
}

data "azuread_client_config" "AzureAD" {}

data "azuread_group" "AVDGroup" {
  display_name     = "Win365-Users"  
}

Configure AVD – Pooled Desktop Pool – output.tf

Create a file named output.tf and insert the following code. This will showcase in the console what is getting deployed in form of a output.

output "azure_virtual_desktop_compute_resource_group" {
  description = "Name of the Resource group in which to deploy session host"
  value       = azurerm_resource_group.rg.name
}

output "azure_virtual_desktop_host_pool" {
  description = "Name of the Azure Virtual Desktop host pool"
  value       = azurerm_virtual_desktop_host_pool.hostpool.name
}

output "azurerm_virtual_desktop_application_group" {
  description = "Name of the Azure Virtual Desktop DAG"
  value       = azurerm_virtual_desktop_application_group.dag.name
}

output "azurerm_virtual_desktop_workspace" {
  description = "Name of the Azure Virtual Desktop workspace"
  value       = azurerm_virtual_desktop_workspace.workspace.name
}

output "location" {
  description = "The Azure region"
  value       = azurerm_resource_group.rg.location
}

data "azuread_group" "aad_group" {
  display_name = "Win365-Users"
}

output "AVD_user_groupname" {
  description = "Azure Active Directory Group for AVD users"
  value       = data.azuread_group.aad_group.display_name
}

Intialize Terraform – AVD – Pooled Desktop Pool

Run terraform init to initialize the Terraform deployment. This command downloads the Azure provider required to manage your Azure resources. (Its pulling the AzureRM and AzureAD)

terraform init -upgrade

Create Terraform Execution Plan – AVD – Pooled Desktop Pool

Run terraform plan to create an execution plan.

terraform plan -out mainavdpooled.tfplan

Apply Terraform Execution Plan – AVD – Pooled Desktop Pool

Run terraform apply to apply the execution plan to your cloud infrastructure.

terraform apply mainavdpooled.tfplan

Validate the Output in Azure Portal

Go to the Azure portal, Select Azure Virtual Desktop and Select Host pools, Application Group and Workspace created using Terraform.

Clean-up the above resources (Optional)

If you want to delete all the above resources then you can use the following commands to destroy. Run terraform plan and specify the destroy flag.

terraform plan -destroy -out mainavdpooled.destroy.tfplan

Run terraform apply to apply the execution plan.

terraform apply mainavdpooled.destroy.tfplan

The intention here is to get you quickly started with Terraform on Azure Virtual Desktop Solution:

DescriptionLinks
Setting up your computer to get started with Terrafor using PowershellInstall Terraform on Windows with Azure PowerShell
AVD Configure Azure Virtual Desktophttps://learn.microsoft.com/en-us/azure/developer/terraform/configure-azure-virtual-desktop
Terraform Learninghttps://youtube.com/playlist?list=PLLc2nQDXYMHowSZ4Lkq2jnZ0gsJL3ArAw

I hope you will find this helpful information for getting started with Terraform to deploy the Azure Virtual Desktop – Pooled Desktop. Please let me know if I have missed any steps or details, and I will be happy to update the post.

Thanks,
Aresh Sarkari

Azure Virtual Desktop – Terraform – Create a Host Pool, Desktop Application Group and Workspace for Personal Desktop (Part 1)

8 May

In the past, I have written blog posts on creating the Azure Virtual Desktop (AVD) solution using PowerShell. In this blog post series, I will demonstrate how to create the AVD Host Pool, Application Group and Workspace using Terraform. Terraform is an open-source infrastructure as code (IaC) software tool that enables you to safely and predictably create, change, and improve infrastructure. Terraform can be used to manage infrastructure on various cloud providers, including Azure.

We are going to create the following three types of configurations using Terraform:

  • Azure Virtual Desktop – Personal Desktop (1×1)
  • Azure Virtual Desktop – Pooled Desktop (Multi-Session Full Desktop Experience)
  • Azure Virtual Desktop – Remote App (Multi-Session Application aka Published Apps)

Note – We are creating the Personal Desktop in this post, and the other desktop/app types will be created in the subsequent post. In this post, I will showcase the creation of service principal and secret. In the next part, we shall move straight onto the Terraform code. Referring to part 1 in the series will be essential if you are doing the basics.

Pre-requisites

Following are the pre-requisites before you begin

  • An Azure subscription
  • The Terraform CLI
  • The Azure CLI
  • Permissions within the Azure Subscription for using Terraform

Terraform Service Principal and Secret (Azure AD – App Registrations)

Let’s pre-create the application ID and client secret we will use to connect and leverage the Terraform code in VScode.

  • Connect to Azure Portal and go to Azure Active Directory
  • Click on App Registrations and select – New Registration
  • Give the App a Name – Terraform
  • You will get two important information created for later use within Terraform
    • Application ID
    • Tenant ID
  • Now let’s grant this App Terraform Permission. Click on Add a permission and select MS Graph and search for AppRoleAssignment.ReadWrite.All and select read/write permissions and Add Permissions
  • Select Grant admin consent for domain
  • We are using client secret so now lets enable that. Click on Certificates & Secrets – Client Secrets and select New client secret\
  • Give it a name (Terra-secret) and expiry date (12 months)
  • Copy the Secret Value

Terraform – Authenticating via Service Principal & Client Secret

In the above step, we created the Service Principal and Client secret. We will use it before running any Terraform code in PowerShell (Ensure to run as administrator). We will execute and store the credentials as environment variables. If we do this via the environment variable, we don’t have to store the below information within the providers.tf file. In a future blog post, there are better ways to keep the below details, and I hope to showcase them:

# PowerShell
$env:ARM_CLIENT_ID = "9e453b62-0000-0000-0000-00000006e1ac"
$env:ARM_CLIENT_SECRET = "Z318Q~00000000000000000000000000000000_"
$env:ARM_TENANT_ID = "a02e602c-0000-000-0000-0e0000008bba61"
$env:ARM_SUBSCRIPTION_ID = "7b051460-00000-00000-00000-000000ecb1"
  • Azure Subscription ID – Azure Portal Subscription copy the ID.
  • Client ID – From the above step, you will have the details
  • Client Secret – From the above step, you will have the details
  • Tenant ID – While creating the Enterprise Apps in Azure AD, you will have the details

Terraform Folder Structure

The following is the folder structure for the Terraform code:

Azure Virtual Desktop Personal Pool – Create a directory in which the below Terraform code will be published (providers.tf, main.tf, variables.tf and output.tf)

+---Config-AVD-Personal-Desktop
|   |   main.tf
|   |   output.tf
|   |   providers.tf
|   |   variables.tf

Note – I am not demonstrating how to install Terraform as it’s dead simple, and the information is available everywhere.

Configure AVD – Personal Desktop Pool – Providers.tf

Create a file named providers.tf and insert the following code. (We are using the AzureRM and AzureAD providers)

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "3.49.0"
    }
    azuread = {
      source = "hashicorp/azuread"
    }
  }
}

provider "azurerm" {
  features {}
}

Configure AVD – Personal Desktop Pool – main.tf

Create a file named main.tf and insert the following code. Let me explain what we are attempting to accomplish here: (Note I have # commented the lines with additional info)

  • Create a Resource Group
  • Create a Workspace
  • Create a Host Pool
  • Create a Desktop Application Group (DAG)
  • Associate Workspace and DAG
  • Assign Azure AD Group to the Desktop Application Group (DAG)
  • Assign Azure AD Group to the Resource Group for RBAC for the Session Host (Virtual Machine User Login)
# Resource group name is output when execution plan is applied.
resource "azurerm_resource_group" "rg" {
  name     = var.rg_name
  location = var.resource_group_location
  tags = var.tags
}

# Create AVD workspace
resource "azurerm_virtual_desktop_workspace" "workspace" {
  name                = var.workspace
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  friendly_name       = "${var.prefix} Workspace"
  description         = "${var.prefix} Workspace"
  tags = var.tags
}

# Create AVD host pool
resource "azurerm_virtual_desktop_host_pool" "hostpool" {
  resource_group_name      = azurerm_resource_group.rg.name
  location                 = azurerm_resource_group.rg.location
  name                     = var.hostpool
  friendly_name            = var.hostpool
  validate_environment     = true #[true false]
  start_vm_on_connect      = true
  custom_rdp_properties    = "targetisaadjoined:i:1;drivestoredirect:s:*;audiomode:i:0;videoplaybackmode:i:1;redirectclipboard:i:1;redirectprinters:i:1;devicestoredirect:s:*;redirectcomports:i:1;redirectsmartcards:i:1;usbdevicestoredirect:s:*;enablecredsspsupport:i:1;redirectwebauthn:i:1;use multimon:i:1;enablerdsaadauth:i:1;"
  description              = "${var.prefix} HostPool"
  type                     = "Personal" #[Pooled or Personal]
  personal_desktop_assignment_type = "Automatic"
  load_balancer_type       =  "Persistent"
  tags = var.tags
scheduled_agent_updates {
  enabled = true
  timezone = "AUS Eastern Standard Time"  # Update this value with your desired timezone
  schedule {
    day_of_week = "Saturday"
    hour_of_day = 1   #[1 here means 1:00 am]
  }
}
}

resource "azurerm_virtual_desktop_host_pool_registration_info" "registrationinfo" {
  hostpool_id     = azurerm_virtual_desktop_host_pool.hostpool.id
  expiration_date = var.rfc3339
}

# Create AVD DAG
resource "azurerm_virtual_desktop_application_group" "dag" {
  resource_group_name = azurerm_resource_group.rg.name
  host_pool_id        = azurerm_virtual_desktop_host_pool.hostpool.id
  location            = azurerm_resource_group.rg.location
  type                = "Desktop"
  name                = var.app_group_name
  friendly_name       = "Desktop AppGroup"
  description         = "${var.prefix} AVD application group"
  depends_on          = [azurerm_virtual_desktop_host_pool.hostpool, azurerm_virtual_desktop_workspace.workspace]
  tags = var.tags
}

# Associate Workspace and DAG
resource "azurerm_virtual_desktop_workspace_application_group_association" "ws-dag" {
  application_group_id = azurerm_virtual_desktop_application_group.dag.id
  workspace_id         = azurerm_virtual_desktop_workspace.workspace.id
}

# Assign AAD Group to the Desktop Application Group (DAG)
resource "azurerm_role_assignment" "AVDGroupDesktopAssignment" {
  scope                = azurerm_virtual_desktop_application_group.dag.id
  role_definition_name = "Desktop Virtualization User"
  principal_id         = data.azuread_group.AVDGroup.object_id
}

# Assign AAD Group to the Resource Group for RBAC for the Session Host
resource "azurerm_role_assignment" "RBACAssignment" {
  scope                = azurerm_resource_group.rg.id
  role_definition_name = "Virtual Machine User Login"
  principal_id         = data.azuread_group.AVDGroup.object_id
}

Configure AVD – Personal Desktop Pool – variables.tf

Create a file named variables.tf and insert the following code. I have followed a naming convention that includes the following:

  • AE – Australia East
  • Environment – PROD or DEV
  • Instance – 01
  • RG – Resource Group
  • WS – Workspace
  • DAG – Desktop Application Group
variable "resource_group_location" {
  default     = "australiaeast"
  description = "Location of the resource group - Australia East"
}

variable "rg_name" {
  type        = string
  default     = "AE-DEV-AVD-01-RG"
  description = "Name of the Resource group in which to deploy service objects"
}

variable "workspace" {
  type        = string
  description = "Name of the Azure Virtual Desktop workspace"
  default     = "AE-DEV-AVD-01-WS"
}

variable "hostpool" {
  type        = string
  description = "Name of the Azure Virtual Desktop host pool"
  default     = "AE-DEV-AVD-01-PE-D-HP"
}

variable "app_group_name" {
  description = "Name of the Azure Virtual Desktop application group"
  type        = string
  default     = "AE-DEV-AVD-01-DAG"
}

variable "rfc3339" {
  type        = string
  default     = "2023-05-20T12:43:13Z" #Update this value with a future date
  description = "Registration token expiration"
}

variable "prefix" {
  type        = string
  default     = "AE-DEV-AVD-01-HP-"
  description = "Prefix of the name of the AVD machine(s)"
}

variable "tags" {
  type    = map(string)
  default = {
    Environment = "Dev"
    Department  = "IT"
    Location = "AustraliaEast"
    ServiceClass = "DEV"
    Workload = "Host Pool 01"
  }
}

data "azuread_client_config" "AzureAD" {}

data "azuread_group" "AVDGroup" {
  display_name     = "Win365-Users"  
}

Configure AVD – Personal Desktop Pool – output.tf

Create a file named output.tf and insert the following code. This will showcase in the console what is getting deployed as output.

output "azure_virtual_desktop_compute_resource_group" {
  description = "Name of the Resource group in which to deploy session host"
  value       = azurerm_resource_group.rg.name
}

output "azure_virtual_desktop_host_pool" {
  description = "Name of the Azure Virtual Desktop host pool"
  value       = azurerm_virtual_desktop_host_pool.hostpool.name
}

output "azurerm_virtual_desktop_application_group" {
  description = "Name of the Azure Virtual Desktop DAG"
  value       = azurerm_virtual_desktop_application_group.dag.name
}

output "azurerm_virtual_desktop_workspace" {
  description = "Name of the Azure Virtual Desktop workspace"
  value       = azurerm_virtual_desktop_workspace.workspace.name
}

output "location" {
  description = "The Azure region"
  value       = azurerm_resource_group.rg.location
}

data "azuread_group" "aad_group" {
  display_name = "Win365-Users"
}

output "AVD_user_groupname" {
  description = "Azure Active Directory Group for AVD users"
  value       = data.azuread_group.aad_group.display_name
}

Intialize Terraform – AVD – Personal Desktop Pool

Run the following command to initialize the Terraform deployment. This command downloads the Azure provider required to manage your Azure resources.

terraform init -upgrade

Create Terraform Execution Plan – AVD – Personal Desktop Pool

Run the following command to create an execution plan.

terraform plan -out mainavdpersonal.tfplan

Apply Terraform Execution Plan – AVD – Personal Desktop Pool

Run the following command to apply the execution plan to your cloud infrastructure.

terraform apply mainavdpersonal.tfplan

Validate the Output in Azure Portal

Go to the Azure portal, Select Azure Virtual Desktop and Select Host pools, Application Group and Workspace created using Terraform.

Clean-up the above resources (Optional)

If you want to delete all the above resources then you can use the following commands to destroy. Run terraform plan and specify the destroy flag.

terraform plan -destroy -out mainavdpersonal.destroy.tfplan

Run terraform apply to apply the execution plan.(Destroy)

terraform apply mainavdpersonal.destroy.tfplan

The intention here is to get you quickly started with Terraform on Azure Virtual Desktop Solution:

DescriptionLinks
Setting up your computer to get started with Terrafor using PowershellInstall Terraform on Windows with Azure PowerShell
AVD Configure Azure Virtual Desktophttps://learn.microsoft.com/en-us/azure/developer/terraform/configure-azure-virtual-desktop
Terraform Learninghttps://youtube.com/playlist?list=PLLc2nQDXYMHowSZ4Lkq2jnZ0gsJL3ArAw

I hope you will find this helpful information for getting started with Terraform to deploy the Azure Virtual Desktop – Personal Desktop Pool. Please let me know if I have missed any steps or details, and I will be happy to update the post.

Thanks,
Aresh Sarkari

Disable Search Highlights on Windows 365 Cloud PC and Azure Virtual Desktop using Microsoft Intune

24 Feb

Search Highlight is a feature in Windows 11 (Enterprise\Multi-session) that highlights search results in the Start menu and taskbar search box. While this feature can be helpful for some users, others may find it distracting or unnecessary. Fortunately, it is possible to disable the Search Highlight feature in Windows 11 using Microsoft Intune. Plenty of information is available on disabling the Windows 11 Search Highlight using Group policy, Registry and UI. However, we will leverage Custom OMA-URI settings from Microsoft Intune in this blog post.

Search – CSP Details

The Search – Policy configuration service provider enables the enterprise to configure policies on Windows 11. Following are the details on the one we are using for disabling the search highlights:

How to disable Search Highlights in Microsoft Endpoint Manager

To disable the Search Highlight feature in Windows 11 (Enterprise/Multi-session) using Microsoft Intune, follow these steps:

  • Login to the MEM Portal – https://endpoint.microsoft.com/
  • Select Devices > Configuration Profiles > Create Profile.
  • For Platform, select Windows 10 and later.
  • For Profile type, select Templates > Custom and select Create.
  • Enter a Name – DisableSearchHighlight and description and choose Next
  • Under the OMA-URI Settings, clicks on Add
  • Enter the Name, Description, and OMA-URI fetched in the references from the MS CSP link below. The value is an integer based on the documentation, and as we disable the setting, the value is 0.
  • Remember the MS documentation called out this setting only applies to Devices. In the case of Assignments, we will target Windows 365 Device Group and Azure Virtual Desktop Session Host Pools.
  • Click on Review and Save

Validate the Policy is applying

After 10-15 mins of waiting, go into the newly configured configuration profiles policy, and you will start seeing it getting applied to the targeted devices (MEM Portal > Devices > Configuration Profiles > DisableSearchHighlights)

Cloud PC – Within Windows 11

Login to the Windows 365 Cloud PC, and now when you click on Search, the advertisements and search highlights are gone.

Useful LinksCredits
Search – CSP Policy – https://learn.microsoft.com/en-us/windows/client-management/mdm/policy-csp-searchMicrosoft
5 Unique Ways to Disable Search Highlights on Windows 11Prajwal Desai
Disable Enable Search Highlights in Windows 11Jitesh Kumar

I hope you will find this helpful information towards disabling the annoying Search Highlights on Windows 365, AVD environment and physical endpoints using Microsoft Endpoint Manager. Please let me know if I have missed any steps or details, and I will be happy to update the post.

Thanks,
Aresh Sarkari

Microsoft Defender for Endpoint – Web Content Filtering for Windows 365 Cloud PC and Azure Virtual Desktop

22 Feb

In today’s world, online security has become more important than ever, especially for businesses. As more and more companies shift their workloads to the cloud, the need for effective security measures has increased. One of the most critical aspects of security is web content filtering. Microsoft Defender for Endpoint is an excellent solution for protecting your Windows 365 Cloud PC and Azure Virtual Desktop environments. If you haven’t see my previous blog post on – Microsoft Defender for Endpoint (MDE) – Getting started for Windows 365 Cloud PC and Azure Virtual Desktop check that first.

Usecase

Web content filtering is a critical aspect of online security that can be used in many different scenarios. Here are some common use cases for web content filtering:

  1. Business Security: Blocking access to malicious websites and other dangerous content, web content filtering helps prevent cyber attacks and data breaches.
  2. Compliance: Many organizations are required to comply with industry-specific regulations and standards, such as HIPAA or PCI-DSS. Web content filtering can help ensure that employees are not accessing websites or content that violates these regulations.
  3. Employee Productivity: Web content filtering can also be used to enhance employee productivity by blocking access to non-work-related websites, such as social media or gaming sites.
  4. Education: Educational institutions can use web content filtering to prevent students from accessing websites that are not educational or age-appropriate.
  5. Guest Wi-Fi: Businesses that offer guest Wi-Fi can use web content filtering to protect their network and guests from online threats.

Overall, web content filtering is a versatile tool that can be used in a variety of settings to enhance online security, productivity, and compliance.

Pre-requisites

To use Microsoft Defender for Endpoint web content filtering on Windows 365 Cloud PC and Azure Virtual Desktop, there are a few prerequisites that you need to meet:

  • Portal Access to Microsoft 365 Defender Portal
  • Windows Defender SmartScreen Enabled on all Browsers (Edge, Chrome etc.)
  • Network Protection must be enable on the endpoint devices
  • Microsoft Defender for Endpoint (MDE) Plan 1 or 2
  • MDE for Business
  • Windows 10/11 or Multi-session Operating System

Enable Web Content Filtering

To enable Web Content Filtering in Microsoft Defender for Endpoint (MDE), you need to follow these steps:

  • Log in to the Microsoft Defender Security Center: Go to https://security.microsoft.com/ and log in with your Microsoft 365 account.
  • Navigate to Settings and select Endpoints
  • Click on Advance Features and enable Web Content Filtering

Create Device Group for Windows 365 & AVD in Microsoft 365 Defender Portal

To assign the policy to particular devices such as Windows 365 Cloud and Azure Virtual Desktop Session, we will create the Device Groups:

  • Log in to the Microsoft Defender Security Center: Go to https://security.microsoft.com/ and log in with your Microsoft 365 account.
  • Navigate to Settings and select Endpoints
  • Under Permissions, click on Device Groups
  • Select Add device group and give it a name – Win365Devices
  • The Cloud PC start with CPC, I will be using that along with OS type – Windows 11
  • For the Azure Virtual Desktop – My Session host start with AVD-, I will use that as the device group along with OS Type – Windows 11

Enable Network Protection under Microsoft Endpoint Portal (Intune)

Under the Enpoint Secruity – Antivirus policy we will enable the configuration:

  • Login to the MEM Portal – https://endpoint.microsoft.com/
  • Select Endpoint security > Antivirus > Create Policy.
  • For Platform, select Windows 10, Windows 11, and Windows Servers.
  • For Profile type, select Microsoft Defender Antivirus, and then select Create.
  • Enter a Name – W365-AVD-AV-P01 and description and choose Next
  • Under the Configuration Settings
  • Enable Network Protection – Enable (Block Mode)

In my previous blog post on getting started, I enabled Network Protect and other configurations. Here I am trying to give you a quick config guidance.

Enable Smart Screen under Microsoft Edge Browser via Intune

I want to use the security baseline around Microsoft Edge for enabling global configuration across all the endpoints:

  • Login to the MEM Portal – https://endpoint.microsoft.com/
  • Select Endpoint security > Security Baseline > Microsoft Endge Baseline.
  • Click on Create a profile and give it a name – MSEdge-Sbaseline-01
  • Enable the SmartScreen config
  • I am applying this security baseline to All Devices

Note you can enable them via configuration profiles too. In this scenario, I prefer using the security baselines.

Enable Smart Screen for Google Chrome Browser via Intune

To enable Smart Screen on Google Chrome, follow these steps:

  • Login to the MEM Portal – https://endpoint.microsoft.com/
  • Select Devices > Configuration profiles > Create profile
  • Under Platform – Windows 10 & Later
  • Profile Type – Templates and Select Administrative Templates
  • Give the policy a name – GoogleChrome-SmartScreen-CP01
  • Under Computer – Select Configure the list of force-installed apps and extensions
  • Click on Enable and enter the below URL for extension
  • Further assign the policy to the target devices
  • Click on Review and Save
bkbeeeffjjeopflfhgeknacdieedcoml;https://clients2.google.com/service/update2/crx

Create policy for Web Content Filtering

To create a web content filtering policy in Microsoft Defender for Endpoint, follow these steps:

  • Log in to the Microsoft Defender Security Center: Go to https://security.microsoft.com/ and log in with your Microsoft 365 account.
  • Navigate to Settings and select Endpoints
  • Under Rules > Web Content Filtering > Add Item
    • Policy Name – Stop Social Media
    • Block Categories > Leisure > Social Networking & Instant Messaging & Professional Networking
    • Scope – Select the Windows 365 Device Group & AVD Device Group (Session Host VMs), as its a targeted policy
  • Wait for approx. 40 mins for the policy to implement for your endpoints

Validate the URLs within Windows 365 Cloud PC

Before going ahead and checking the URLs within the browser verify the following on the virtual desktop or endpoints:

SmartScreen

Open the browser and type edge://policy and make sure the Smart Screen is enabled

Network Protection

Open the Powershell and check if network protection is enable (Value 1) block mode

Microsoft Edge

Open Microsoft Edge and open https:\\www.facebook.com or https:\\www.snapchat.com

Google Chrome

Check reports in Defender Portal

Under the Microsoft Defender Portal go to Reports > Web Protection > Web content filtering categories details

Useful LinksCredits
Web content filtering – https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/web-content-filtering?view=o365-worldwideMicrosoft
How to configure Microsoft Defender SmartScreen via Microsoft Intune? – Endpoint CaveRene Laas
Enabling web filtering with Microsoft Defender for Endpoint – CIAOPSRobert Crane

I hope you will find this helpful information towards web content filtering journey to secure your Windows 365 and AVD environments using Microsoft Defender for Endpoint. Please let me know if I have missed any steps or details, and I will be happy to update the post.

Thanks,
Aresh Sarkari

Microsoft Defender for Endpoint (MDE) – Getting started for Windows 365 Cloud PC and Azure Virtual Desktop

16 Feb

If you are using Windows 365 Cloud PC and Azure Virtual Desktop, the Microsoft Defender for Endpoint (MDE) is a security solution designed for protecting endpoints, such as Windows 11/Windows 11 Mutli-Session computers, servers, Azure Virtual Desktops and more from various types of cyber threats. The main reason it’s evident to use MDE is that it seamlessly integrates with the solution with minimal to less effort compared to other solutions. This blog post will discuss how to get started with Microsoft Defender for Endpoint in the Windows 365 Cloud and Azure Virtual Desktop.

Prerequisites

  • Rights to use and deploy Windows 365 Cloud PC and Azure Virtual Desktop and the ncessary licenses
  • Microsoft Defender for Endpoint Plan 1 or Plan 2 depending upon the requirements and $$$.
  • Make sure the license is available and listed Microsoft admin center

Enable MDE in Microsoft 365 Security Portal/Intune

To enable Microsoft Defender for Endpoint (MDE) in the Microsoft Defender Security Center, you need to follow these steps:

  1. Log in to the Microsoft Defender Security Center: Go to https://security.microsoft.com/ and log in with your Microsoft 365 account.
  2. Navigate to Settings and select Endpoints
  3. Click on On for Microsoft Intune Connection & Device Discovery
  4. Scroll to the bottom and select Save Preferences

We will manage the endpoints via Intune, so all the rest of the actions and fun will be within the https://endpoint.microsoft.com/ and Endpoint Security. After a brief period of 10-15 mins, you can see the connection status being Available and synchronized.

Create the Endpoint detection and response policy (onboarding)

Our environment is managed via Modern Management, and we don’t have the overhead of legacy setup. We will use the Intune Endpoint detection response (EDR) policy to onboard the devices. This is the simplest method as it doesn’t involve installing the agent manually or via GPOs.

Sign in to the Microsoft Endpoint Manager admin center.

  • Login to the MEM Portal – https://endpoint.microsoft.com/
  • Select Endpoint security > Endpoint detection and response > Create Policy.
  • For Platform, select Windows 10, Windows 11, and Windows Servers.
  • For Profile type, select Endpoint detection and response, and then select Create.
  • Enter a Name – W365-AVD-EDR-P01 and description and choose Next
  • Under the Configuration Settings
    • MDE client configuration package type – Auto from connector (We are a 100% modern managed environment we can leverage this simple option)
    • Sample Sharing – Not configured
    • Telemetry Reporting Frequency – Expedite (We want reporting to be lightning-fast)
  • Next, the most critical part is the target assignments. I am explicitly creating this policy to target Windows 365 Cloud PC and Azure Virtual Desktop
  • Review and Create the policy and it will go ahead and enable MDE on the fleet.
  • After sometime all your devices will show whether they are onboarded or not.

Many ways to carry out the onboarding. This is just one way and the most straightforward. Read more options here – https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/onboarding-endpoint-manager?view=o365-worldwide

On the onboarded device, go and run the following command to verify the status

Get-MpComputerStatus

Device Compliance Policy (Update)

I already have my existing Windows 10/11 compliance policy after enabling MDE, and I will go ahead and update the compliance policy to accommodate the changes further. This will allow reporting within the tenant on what device compliance level the endpoints are on and whether corporate governance is maintained.

Create Antivirus Policy in Intune

The next step is creating the Antivirus (AV) Policy with the options that your organization demands. I am starting with a few, but remember most choices will require nailing out with internal security/endpoint/governance teams.

Below configurations are not an exhaustive list – Consult with the endpoint/security teams to meet the organization’s requirements.

Sign in to the Microsoft Endpoint Manager admin center.

  • For Platform, select Windows 10, Windows 11, and Windows Servers.
  • For Profile type, select Microsoft Defender Antivirus, and then select Create.
  • Enter a Name – W365-AVD-AV-P01 and description and choose Next
  • Under the Configuration Settings
Configuration SettingsStatus (Value)
Allow Archive Scanning (Scanning through zip and cab files)Allowed
Allow Behaviour Monitoring Allowed
Allow Cloud Protection (Joining Microsoft MAPS Community)Allowed
Allow Email Scanning (Very useful if you are using Microsoft 365)Allowed
Allow Full Scan Removable Drive Scanning (Scanning of Pen Drives)Allowed
Allow Intrusion Prevention SystemAllowed
Allow scanning of all downloaded files and attachmentsAllowed
Allow Realtime MonitoringAllowed
Cloud Block LevelHigh
Allow Users UI Access (Defender Client)Allowed
Enable Network ProtectionEnabled (Audit mode)
Avg CPU Load Factor Enabled (30%)
Schedule Quick Scan TimeEnable (120)
Signature Update IntervalEnable (8 hours)
  • Next, the most critical part is the target assignments. I am explicitly creating this policy to target Windows 365 Cloud PC and Azure Virtual Desktop
  • Review and Create the policy and it will go ahead and enable AV across the fleet.
  • After sometime all your devices will show whether they are onboarded or not.

Create Attack surface reduction (ASR) Policy in Intune

The attack surface reduction set of capabilities provide the first line of defense in the stack. By ensuring configuration settings are properly set and exploit mitigation techniques are applied, these set of capabilities resist attacks and exploitation. This set of capabilities also includes network protection and web protection, which regulate access to malicious IP addresses, domains, and URLs. In my case I am starting with few, but remember most of the options will require nailing out with internal security/endpoint/governeance teams.

Below configurations are not an exhaustive list – Consult with the endpoint/security teams to meet the organization’s requirements. Here I would like to take the approach of Audit mode first, followed by adding exclusions to refine the block rules (production).

Sign in to the Microsoft Endpoint Manager admin center.

  • For Platform, select Windows 10, Windows 11, and Windows Servers.
  • For Profile type, select Attack Surface Reduction Rules, and then select Create.
  • Enter a Name – W365-AVD-ASR-P01 and description and choose Next
  • Under the Configuration Settings
Configuration SettingsStatus (Value)
Block Adobe Reader from creating child processesAudit
Block execution of potentially obfuscated scriptsAudit
Block Win32 API calls from office macrosAudit
Block credential stealing from the Windows local security authority subsystemAudit
Block JavaScript or VBScript from launching downloaded executable contentAudit
Block process creatons originating from PSExec and WMI commandsAudit
Block untrusted and unsigned processes that run from USBAudit
Block abuse of exploited vulnerable signed drivers (Devices)Audit
  • Next, the most critical part is the target assignments. I am explicitly creating this policy to target Windows 365 Cloud PC and Azure Virtual Desktop
  • Review and Create the policy and it will go ahead and enable ASR across the fleet.
  • After sometime all your devices will show whether they are onboarded or not.
Useful LinksCredits
Microsoft Defender for Endpoint series – Tips and tricks/ common mistakes – Part10 (jeffreyappel.nl) – The most mind blowing and detailed blog post series on MDE. I think I only scratch the surface here however, Jeffrey takes an indept approach.Jeffrey Appel
Configure Microsoft Defender for Endpoint in IntuneMicrosoft
Defend Cloud PCs against threats with Microsoft Defender for Endpoint | Windows in the Cloud – YouTubeChristiaan Brinkhoff | LinkedIn and Paul Huijbregts | LinkedIn

Next step, I plan to write a few blog posts on specific topics like URLs, Networks etc, blocking (TikTok, Facebook etc,) concerning MDE. I hope you will find this helpful information towards your journey to secure your Windows 365 and AVD environments using Microsoft Defender for Endpoint. Please let me know if I have missed any steps or details, and I will be happy to update the post.

Thanks,
Aresh Sarkari

Compliance Policy for Azure Virtual Desktop Session Host Virtual machine managed via Microsoft Intune

3 Feb

Microsoft Intune Compliance Policy can be used to manage the security and compliance of Azure Virtual Desktop (AVD) Session Host virtual machines. The policy can enforce specific configuration settings such as password complexity, security updates, and device encryption to ensure that the virtual machines meet the organization’s security and compliance requirements.

To set up an Intune Compliance Policy for an AVD Session Host virtual machine, the virtual machine must be enrolled with Intune. Then, the policy can be created in the Intune portal and assigned to the virtual machine. The policy settings will be enforced on the virtual machine and monitored for compliance.

Note: The Intune Compliance Policy is just one of the ways to manage the security and compliance of AVD Session Host virtual machines. Other tools such as Azure Security Center and Azure Policy can also be used.

Why create the azure virtual desktop session host compliance policy?

There are several reasons why organizations create Azure Virtual Desktop (AVD) Session Host Compliance Policies:

  1. Security: Compliance policies help ensure that the AVD Session Host virtual machines are configured with the necessary security measures to protect sensitive data and prevent unauthorized access. This includes enforcing encryption, password policies, and software updates.
  2. Compliance: Compliance policies help organizations meet regulatory requirements, such as HIPAA, PCI, and SOC, by ensuring that the AVD Session Host virtual machines are configured in accordance with these regulations.
  3. Consistency: Compliance policies help ensure that all AVD Session Host virtual machines are configured consistently and meet the same standards. This makes it easier for administrators to manage the environment and ensures that all users have a consistent and secure experience.
  4. Monitoring: Compliance policies provide ongoing monitoring of the AVD Session Host virtual machines, so administrators can quickly identify and address any deviations from the desired configuration.

By creating an AVD Session Host Compliance Policy, organizations can ensure that their virtual machines are secure, compliant, consistent, and properly monitored, which can help reduce the risk of security breaches and regulatory violations.

What compliance policies are supported with Azure Virtual Desktop?

The following compliance policies are supported on Windows 10 or Windows 11 Enterprise multi-session VMs:

  • Minimum OS version
  • Maximum OS version
  • Valid operating system builds
  • Simple passwords
  • Password type
  • Minimum password length
  • Password Complexity
  • Password expiration (days)
  • Number of previous passwords to prevent reuse
  • Microsoft Defender Antimalware
  • Microsoft Defender Antimalware security intelligence up-to-date
  • Firewall
  • Antivirus
  • Antispyware
  • Real-time protection
  • Microsoft Defender Antimalware minimum version
  • Defender ATP Risk score

Note in my sceanrio I am not using all of the above only a few based on the configuration of my environment. You will need a Azure AD device group containing all the session host for AVD to apply this policy.

What am I configuring?

I am only configuring two things. However, I urge if you to leverage Microsoft Defender and make sure you use the Antivirus and Antimalware settings (Another blog post later day for Defender integrations):

  • Minimum OS version – 10.0.22621.963
  • Firewall – Require

The above is not an extensive list, but I am trying to give you an idea here.

Create the compliance policy for AVD

Open the Microsoft Endpoint Manager admin center and navigate to Devices and Compliance Policies.

  • Click on Create Policy and Select Platform Windows 10 and later
  • Give the policy a name and description
  • Configure the above two parameters
  • An assignment is the most critical aspect, here, you want an Azure AD Dynamic Device Group that will make sure all the AVD Session hosts are covered.
  • My current AAD Dynamic Group query is as follows, I am working towards getting a more refine query to make it understand Multi-session(I have raised a query internally within MS)

Device Compliance (AVD Session Host VMs)

After waiting for 15 mins you will start noticing all your AVD Session host VM’s will now begin to show as compliant.

I hope you will find this helpful information for creating a compliance policy for your AVD Session host VMs. Please let me know if I have missed any steps or details, and I will be happy to update the post.

Thanks,
Aresh Sarkari