AzureVirtualDesktop

From Piszczynski

Automate creation of azure virtual desktop

This cmdlet will create the host pool, workspace, and desktop app group. Additionally, it will register the desktop app group to the workspace. You can either create a workspace with this cmdlet or use an existing workspace

  • New-AzWvdHostPool -ResourceGroupName <resourcegroupname> -Name <hostpoolname> -WorkspaceName <workspacename> -HostPoolType <Pooled|Personal> -LoadBalancerType <BreadthFirst|DepthFirst|Persistent> -Location <region> -DesktopAppGroupName <appgroupname>

Run the next cmdlet to create a registration token to authorize a session host to join the host pool and save it to a new file on your local computer. You can specify how long the registration token is valid by using the -ExpirationHours parameter.

  • New-AzWvdRegistrationInfo -ResourceGroupName <resourcegroupname> -HostPoolName <hostpoolname> -ExpirationTime $((get-date).ToUniversalTime().AddDays(1).ToString('yyyy-MM-ddTHH:mm:ss.fffffffZ'))

After that, run this cmdlet to add Azure Active Directory users to the default desktop app group for the host pool.

  • New-AzRoleAssignment -SignInName <userupn> -RoleDefinitionName "Desktop Virtualization User" -ResourceName <hostpoolname+"-DAG"> -ResourceGroupName <resourcegroupname> -ResourceType 'Microsoft.DesktopVirtualization/applicationGroups'

Run this next cmdlet to add Azure Active Directory user groups to the default desktop app group for the host pool:

  • New-AzRoleAssignment -ObjectId <usergroupobjectid> -RoleDefinitionName "Desktop Virtualization User" -ResourceName <hostpoolname+"-DAG"> -ResourceGroupName <resourcegroupname> -ResourceType 'Microsoft.DesktopVirtualization/applicationGroups'

Run the following cmdlet to export the registration token to a variable, which will be used later to register the virtual machines to the Azure Virtual Desktop host pool.

  • $token = Get-AzWvdRegistrationInfo -ResourceGroupName <resourcegroupname> -HostPoolName <hostpoolname>


Assign Users to Host Pool

Automatic assignment

To configure a host pool to automatically assign users to VMs, run the following PowerShell cmdlet:

  • Update-AzWvdHostPool -ResourceGroupName <resourcegroupname> -Name <hostpoolname> -PersonalDesktopAssignmentType Automatic```

To assign a user to the personal desktop host pool, run the following PowerShell cmdlet:

  • New-AzRoleAssignment -SignInName <userupn> -RoleDefinitionName "Desktop Virtualization User" -ResourceName <appgroupname> -ResourceGroupName <resourcegroupname> -ResourceType 'Microsoft.DesktopVirtualization/applicationGroups'

Direct Assignment

To configure a host pool to require direct assignment of users to session hosts, run the following PowerShell cmdlet:

  • Update-AzWvdHostPool -ResourceGroupName <resourcegroupname> -Name <hostpoolname> -PersonalDesktopAssignmentType Direct

To assign a user to the personal desktop host pool, run the following PowerShell cmdlet:

  • New-AzRoleAssignment -SignInName <userupn> -RoleDefinitionName "Desktop Virtualization User" -ResourceName <appgroupname> -ResourceGroupName <resourcegroupname> -ResourceType 'Microsoft.DesktopVirtualization/applicationGroups'

To assign a user to a specific session host, run the following PowerShell cmdlet:

  • Update-AzWvdSessionHost -HostPoolName <hostpoolname> -Name <sessionhostname> -ResourceGroupName <resourcegroupname> -AssignedUser <userupn>

Use the Azure portal also to assign users directly - Azure Virtual Desktop page > Host pools


Edit Remote Desktop Protocol properties for users (RDP settings)

To add or edit a single custom Remote Desktop Protocol property, run the following PowerShell cmdlet:

  • Set-RdsHostPool -TenantName <tenantname> -Name <hostpoolname> -CustomRdpProperty "<property>"

Edit multiple custom properties using semi colon seperated list:

  • $properties="<property1>;<property2>;<property3>"
    • Set-RdsHostPool -TenantName <tenantname> -Name <hostpoolname> -CustomRdpProperty $properties

To enable access from Windows devices not joined to Azure AD, add targetisaadjoined:i:1 as a custom RDP property to the host pool.

To access Azure AD-joined virtual machines using the web, Android, macOS and iOS clients, you must add targetisaadjoined:i:1 as a custom RDP property to the host pool. These connections are restricted to entering user name and password credentials when signing in to the session host.

Setup device redirections

Setup device redirections You can use the following RDP properties and Group Policy settings to configure device redirections.

Audio input (microphone) redirection
Set the following RDP property to configure audio input redirection:

audiocapturemode:i:1 enables audio input redirection.
audiocapturemode:i:0disables audio input redirection.
Audio output (speaker) redirection
Set the following RDP property to configure audio output redirection:

audiomode:i:0enables audio output redirection.
audiomode:i:1 or audiomode:i:2 disable audio output redirection.
Camera redirection
Set the following RDP property to configure camera redirection:

camerastoredirect:s:* redirects all cameras.
camerastoredirect:s: disables camera redirection.
 
Note
Even if the camerastoredirect:s: property is disabled, local cameras may be redirected through the devicestoredirect:s: property. To fully disable camera redirection set camerastoredirect:s: and either set devicestoredirect:s: or define some subset of plug and play devices that does not include a camera.

You can also redirect specific cameras using a semicolon-delimited list of KSCATEGORY_VIDEO_CAMERA interfaces, such as camerastoredirect:s:\?\usb#vid_0bda&pid_58b0&mi.

Clipboard redirection
Set the following RDP property to configure clipboard redirection:

redirectclipboard:i:1 enables clipboard redirection.
redirectclipboard:i:0 disables clipboard redirection.
COM port redirections
Set the following RDP property to configure COM port redirection:

redirectcomports:i:1 enables COM port redirection.
redirectcomports:i:0 disables COM port redirection.
USB redirection
First, set the following RDP property to enable USB device redirection:

usbdevicestoredirect:s:* enables USB device redirection.
usbdevicestoredirect:s: disables USB device redirection.
Second, set the following Group Policy on the user's local device:

Navigate to Computer Configuration > Policies> Administrative Templates > Windows Components > Remote Desktop Services > Remote Desktop Connection Client > RemoteFX USB Device Redirection.
Select Allows RDP redirection of other supported RemoteFX USB devices from this computer.
Select the Enabled option, and then select the Administrators and Users in RemoteFX USB Redirection Access Rights box.
Select OK.
Plug and play device redirection
Set the following RDP property to configure plug and play device redirection:

devicestoredirect:s:* enables redirection of all plug and play devices.
devicestoredirect:s: disables redirection of plug and play devices.
You can also select specific plug and play devices using a semicolon-delimited list, such as devicestoredirect:s:root\*PNP0F08.

Local drive redirection
Set the following RDP property to configure local drive redirection:

drivestoredirect:s:* enables redirection of all disk drives.
Drivestoredirect:s: disables local drive redirection.
You can also select specific drives using a semicolon-delimited list, such as drivestoredirect:s:C:;E:;.

Printer redirection
Set the following RDP property to configure printer redirection:

redirectprinters:i:1 enables printer redirection.
redirectprinters:i:0 disables printer redirection.

Apply Licence to Azure virtual desktop session host

  • $vm = Get-AzVM -ResourceGroup <resourceGroupName> -Name <vmName>
    • $vm.LicenseType = "Windows_Client"
      • Update-AzVM -ResourceGroupName <resourceGroupName> -VM $vm

Verify license:

  • Get-AzVM -ResourceGroupName <resourceGroupName> -Name <vmName>

Run the following cmdlet to see a list of all session host virtual machines that have the Windows license applied in your Azure subscription:

  • $vms = Get-AzVM
    • $vms | Where-Object {$_.LicenseType -like "Windows_Client"} | Select-Object ResourceGroupName, Name, LicenseType


Create and configure session host images

Create Local Image

Can use Hyper-V manager to create a VM with a copied VHD

Ensure checkpoints are disabled:

  • Set-VM -Name <VMNAME> -CheckpointType Disabled

Ensure that the Disk is a Fixed disk as disks by default are created as dynamic. Using Hyper-V powershell module convert the disk to fixed:

  • Convert-VHD –Path c:\test\MY-VM.vhdx –DestinationPath c:\test\MY-NEW-VM.vhd -VHDType Fixed

Then you can upload the image (VHD) to an azure Blob container either with storage explorer or using azcopy

Modify/Configure Session Host image

Disable Automatic Updates via regkey:

  • reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" /v NoAutoUpdate /t REG_DWORD /d 1 /f

Specify Start layout for Windows 10 computers:

  • reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer" /v SpecialRoamingOverrideAllowed /t REG_DWORD /d 1 /f

Set up time zone redirection

  • reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v fEnableTimeZoneRedirection /t REG_DWORD /d 1 /f

Disable Storage Sense (Microsoft recommends for azure virtual desktop hosts)

  • reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\StorageSense\Parameters\StoragePolicy" /v 01 /t REG_DWORD /d 0 /f

Install Office 365 - see OfficeDeploymentTool

Configure onedrive - see OneDrive


After Completing the install of apps and configuration changes run the sysprep tool to generalize the image:

  • C:\Windows\System32\Sysprep\sysprep.exe /oobe /generalize /shutdown


Setup Network for Virtual Desktop Session Hosts

Outbound Access

Outbound for Azure Virtual Desktop

Azure virtual machines you create for Azure Virtual Desktop must have access to several Fully Qualified Domain Names (FQDNs) to function properly.

Azure Firewall provides an Azure Virtual Desktop FQDN Tag to simplify this configuration. Use the following steps to allow outbound Azure Virtual Desktop platform traffic:

Deploy Azure Firewall and configure your Azure Virtual Desktop host pool subnet User Defined Route (UDR) to route all traffic via the Azure Firewall. Your default route now points to the firewall.

Create an application rule collection and add a rule to enable the WindowsVirtualDesktop FQDN tag. The source IP address range is the host pool virtual network, the protocol is https, and the destination is WindowsVirtualDesktop.

The set of required storage and service bus accounts for your Azure Virtual Desktop host pool is deployment-specific. It isn't captured in the WindowsVirtualDesktop FQDN tag. You can address this in one of the following ways:

  • Allow https access from your host pool subnet to *xt.blob.core.windows.net, *eh.servicebus.windows.net and *xt.table.core.windows.net. These wildcard FQDNs enable the required access, but are less restrictive.
  • Use the following log analytics query to list the exact required FQDNs, and then allow them explicitly in your firewall application rules:
AzureDiagnostics
| where Category == "AzureFirewallApplicationRule"
| search "Deny"
| search "gsm*eh.servicebus.windows.net" or "gsm*xt.blob.core.windows.net" or "gsm*xt.table.core.windows.net"
| parse msg_s with Protocol " request from " SourceIP ":" SourcePort:int " to " FQDN ":" *
| project TimeGenerated,Protocol,FQDN

Create a network rule to add the following rules:

  • Allow DNS. Traffic from your AD DS private IP address to * for TCP and UDP ports 53.
  • Allow KMS. Traffic from your Azure Virtual Desktop virtual machines to Windows Activation Service TCP port 1688.

RDP Shortpath

Enable RDP shortpath to improve connections to session hosts for clients that have direct connection to the network that the session hosts are on.

You will need to enable the RDP shortpath listener on the session hosts:

To enable the RDP Shortpath listener:

Install administrative templates that add rules and settings for Azure Virtual Desktop. Download the Azure Virtual Desktop policy templates file (https://aka.ms/avdgpo)(AVDGPTemplate.cab) and extract the contents of the .cab file and .zip archive.

Copy the terminalserver-avd.admx file, then paste it into the %windir%\PolicyDefinitions folder.

Copy the en-us\terminalserver-avd.admlfile, then paste it into the%windir%\PolicyDefinitions\en-us folder.

To confirm the files copied correctly, open the Group Policy Editor and go to Computer Configuration, select Administrative Templates, select Windows Components, select Remote Desktop Services, select Remote Desktop Session Host, and select Azure Virtual Desktop.

You should see one or more Azure Virtual Desktop policies.

Open the Enable RDP Shortpath for managed networks policy and set it to Enabled. If you enable this policy setting, you can also configure the port number that the Azure Virtual Desktop session host will use to listen for incoming connections. The default port is 3390.

Restart your session host to apply the changes.

Configure Windows defender firewall for RDP shortpath

  • New-NetFirewallRule -DisplayName 'Remote Desktop - Shortpath (UDP-In)' -Action Allow -Description 'Inbound rule for the Remote Desktop service to allow RDP traffic. [UDP 3390]' -Group '@FirewallAPI.dll,-28752' -Name 'RemoteDesktop-UserMode-In-Shortpath-UDP' -PolicyStore PersistentStore -Profile Domain, Private -Service TermService -Protocol udp -LocalPort 3390 -Program '%SystemRoot%\system32\svchost.exe' -Enabled:True


Configure Access to Azure Virtual Desktops

Azure Virtual Desktop uses Azure Role-Based access (RBAC) controls to assign roles to users and admins.

The Desktop Virtualization User role is assigned to the user or user group and the scope is the app group. This role gives the user special data access on the app group.

Run the following cmdlet to add Azure Active Directory users to an app group:

  • New-AzRoleAssignment -SignInName -RoleDefinitionName

Run the following cmdlet to add Azure Active Directory user group to an app group:

  • New-AzRoleAssignment -ObjectId -RoleDefinitionName

Conditional Access Policy

Use a Conditional access policy to control how often and what conditions MFA will be requested:

Here's how to create a Conditional Access policy that requires multifactor authentication when connecting to Azure Virtual Desktop:

Sign in to the Azure portal as a global administrator, security administrator, or Conditional Access administrator.

Browse to Azure Active Directory > Security > Conditional Access.

Select New policy.

Give your policy a name. We recommend that organizations create a meaningful standard for the names of their policies.

Under Assignments, select Users and groups.

Under Include, select Select users and groups > Users and groups > Choose the group you created.

Select Done.

Under Cloud apps or actions > Include, select Select apps.

Select one of the following apps based on which version of Azure Virtual Desktop you're using. Choose Azure Virtual Desktop (App ID 9cdead84-a844-4324-93f2-b2e6bb768d07)

Go to Conditions > Client apps, then select where you want to apply the policy to:

  • Select Browser if you want the policy to apply to the web client.
  • Select Mobile apps and desktop clients if you want to apply the policy to other clients.
  • Select both check boxes if you want to apply the policy to all clients.

Once you've selected your app, choose Select, and then select Done.

Under Access controls > Grant, select Grant access, Require multifactor authentication, and then Select.

Under Access controls > Session, select Sign-in frequency, set the value to the time you want between prompts, and then select Select. For example, setting the value to 1 and the unit to Hours, will require multifactor authentication if a connection is launched an hour after the last one.

Confirm your settings and set Enable policy to On.

Select Create to enable your policy.

Setup RDS email discovery

To setup automatic feed discovery using email you will need to create a TXT record in your domain DNS:

Optimize Virtual desktop gold image

Use the following tool to optimize the gold build as required

https://github.com/The-Virtual-Desktop-Team/Virtual-Desktop-Optimization-Tool/releases/tag/2.1.2009.1


Publish Built-in Apps

To publish a built-in app:

1.Connect to one of the virtual machines in your host pool.

2.Get the PackageFamilyName of the app you want to publish.

3.Run the following cmdlet with the PackageFamilyName replaced by the PackageFamilyName found in the previous step:

  • New-AzWvdApplication -Name <applicationname> -ResourceGroupName <resourcegroupname> -ApplicationGroupName <appgroupname> -FilePath "shell:appsFolder\<PackageFamilyName>!App" -CommandLineSetting <Allow|Require|DoNotAllow> -IconIndex 0 -IconPath <iconpath> -ShowInPortal:$true

Azure Virtual Desktop only supports publishing apps with install locations that begin with C:\Program Files\WindowsApps.

Update app icons

After you publish an app, it will have the default Windows app icon instead of its regular icon picture. To change the icon to its regular icon, put the image of the icon you want on a network share. Supported image formats are PNG, BMP, GIF, JPG, JPEG, and ICO.

Publish Microsoft Edge

The process you use to publish Microsoft Edge is a little different from the publishing process for other apps. To publish Microsoft Edge with the default homepage, run this cmdlet:

  • New-AzWvdApplication -Name -ResourceGroupName -ApplicationGroupName -FilePath "shell:Appsfolder\Microsoft.MicrosoftEdge_8wekyb3d8bbwe!MicrosoftEdge" -CommandLineSetting <Allow|Require|DoNotAllow> -iconPath "C:\Windows\SystemApps\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\microsoftedge.exe" -iconIndex 0 -ShowInPortal:$true

Troubleshooting Azure virtual desktop clients

See the following for some fixes

https://learn.microsoft.com/en-gb/training/modules/configure-user-experience-settings/11-troubleshoot-azure-virtual-desktop-clients


Configure FSLogix in Azure Virtual Desktop

Best Practices

Use azure files integration with active directory domain service to enable correct permissions setup on the file shares

Azure Virtual Desktop offers full control over size, type, and count of VMs that are being used by customers.

To ensure your Azure Virtual Desktop environment follows best practices:

  • Azure Files storage account must be in the same region as the session host VMs.
  • Azure Files permissions should match permissions described in Requirements - Profile Containers.
  • Each host pool VM must be built of the same type and size VM based on the same master image.
  • Each host pool VM must be in the same resource group to aid management, scaling and updating.
  • For optimal performance, the storage solution and the FSLogix profile container should be in the same data center location.
  • The storage account containing the master image must be in the same region and subscription where the VMs are being provisioned.

Install

FSLogix is available for download here.

The download for FSLogix includes three installers that are used to install the specific component(s) necessary for your use.

To install FSLogix Applications:

1.From the FSLogix download file, select 32 bit or 64 bit depending on your environment.

2.Run FSLogixAppSetup.exe.

3.Click Options to specify an installation folder.

4.Accept the license agreement and click Install.

5.Microsoft FSLogix Apps will install.

6.To view the FSLogix Configuration Tool, check \Program Files\FSLogix\Apps\ConfigurationTool.exe.

Application Masking Rule Editor Installation

The Application Masking Rule Editor is used to define rules used by Application Masking.

1.From the FSLogix Download file, select 32 bit or 64 bit depending on your environment.

2.Run FSLogixAppsRuleEditorSetup.exe.

3.Use Options to specify installation folder (see screenshot for Microsoft FSLogix Apps above)

4.Accept the license agreement and click Install.

Profile Container

The configuration of Profile Container is accomplished through registry settings and user groups. Registry settings may be managed manually, with GPOs, or using alternate preferred methods. Configuration settings for Profile Container are set in HKLM\SOFTWARE\FSLogix\Profiles

Required Reg Keys:

  • Enabled
  • VHDLocations

Office Container

The configuration of Office Container is accomplished through registry settings and user groups. Registry settings may be managed manually, with GPOs, or using alternate preferred methods. Configuration settings for Profile Container are set in HKLM\SOFTWARE\Policies\FSLogix\ODFC

The minimum required settings are:

  • Enabled
  • VHD Locations

During install of fxlogix foure user groups are created to use to include or exclude users from using fxlogix, by default everyone is added to the "FSlogix ODFC Include List" group. In the case a user is part of multiple groups the exclude group takes priority

Exclusions

OneDrive

Exclude profile solution (except FSLogix Profile Container) syncing for the directories (and subdirectories) seen below:

  • Users<Username><OneDrive folder name>
    • The folder name depends on your Office 365 subscription, so it isn't a fixed name. If you have a question what this folder name is, set HKLM\Software\FSLogix\Logging\LoggingEnabled = 2 and sign out and back on.
    • Look inc:\programdata\fslogix\logs\odfc<find file with todays date>. In the log file, search for "OneDrive folder is" and you'll see which folder needs to be excluded.
  • Users<Username>\AppData\Local\Microsoft\OneDrive

These exclusions fix the following warning found in the FSLogix Profile log when users logon: "<name> isn't your original OneDrive folder"

Outlook

Exclude the directory (and subdirectories) listed below:

  • \Users\<username>\AppData\Local\Microsoft\Outlook

Installing Microsoft Office

You can install office to a .VHD to cut down on the space required on the C:\ of the virtual session hosts

Install Office Install Office on your VHD or VHDX, enable the Remote Desktop Protocol in your VM, then follow the instructions in Install Office on a VHD master image

Azure Virtual Desktop requires Share Computer Activation (SCA).

Create and prepare a VHD to store Office Next, you'll need to create and prepare a VHD image to use the Rule Editor on:

Open a command prompt as an administrator. and run the following command:

  • taskkill /F /IM MSEdge.exe /T

Run the command shown below:

  • sc queryex type=service state=all | find /i

If you find the service, restart the VM before continuing with step 3.

  • net stop ClickToRunSvc

Go to Program Files, select FSLogix, select Apps and run the command seen below to create the target VHD:

  • frx moveto-vhd -filename path\office.vhdx -src

The VHD you create with this command should contain the C:\Program Files\Microsoft Office folder.

Configure the Rule Editor

Now that you've prepared your image, you'll need to configure the Rule Editor and create a file to store your rules in. This will make FSLogix point the directory in teh file system to the correct .vhd that contains the office install

1.Go to Program Files, select FSLogix , select Apps and run RuleEditor.exe.

2.Select File, select New, select Create to make a new rule set, then save that rule set to a local folder.

3.Select Blank Rule Set, then select OK.

4.Select the + button to open the Add Rule window. to update the options in the Add Rule dialog.

5.From the drop-down menu, select App Container (VHD) Rule.

6.Enter C:\Program Files\Microsoft Office into the Folder field.

7.For the Disk file field, select <path>\office.vhdfrom the Create target VHD section.

8.Select OK.

9.Go to the working folder atC:\Users\<username>\Documents\FSLogix Rule Setsand find .frx and .fxa files. You need to move these files to the Rules folder located at C:\Program Files\FSLogix\Apps\Rules in order for the rules to start working.

10.Select Apply Rules to System for the rules to take effect.

You'll need to apply the app rule files will need to all session hosts.

Manage Rule Sets

Application Masking manages access to Applications, Fonts, and other items based on criteria. The Application Rules Editor is used to Describe the item, such as application, to be managed. The Editor is also used to define criteria rules are managed by.

Things you can do with the Apps Rules Editor:

  • Create new Rule Sets.
  • Edit existing Rule Sets.
  • Manage the user and group assignments for Rule Sets.
  • Temporarily test rule-sets.

Rule Types

FSLogix Has 4 rule types

  • Hiding Rule - hides the specified items using specified criteria.
  • Redirect Rule - causes the specified item to be redirected as defined.
  • App Container Rule - redirects the specified content into a VHD.
  • Specify Value Rule - assigns a value for the specified item.

Create Rule Set

1.Open the Apps Rule Editor. The first time you enter the Apps Rules Editor there won't be any rule sets in the left panel. In this example, one rule set has already been created named Contoso_1 with GitHub Desktop added.

2.Click File then New to create a new Rule Set.

3.Provide a name for the Rule Set and click Enter Filename.

4.After a filename is entered, a selection is made for the type and content of the rule.

5.After specifying the parameters wanted, click Scan to create a rule (In this example, GitHub Desktop is selected)

Redirecting to a network

Files and directories can be redirected to resources located on a network. The user must have appropriate rights to the network resource. To redirect to a network location, enter the path (in UNC format) into the Destination field.

Deploying Rule Sets

Application Masking and Java Version Control rely on Rules and Rule Sets.

By default, Rules and Rule Sets are accessed from C:\Program Files\FSLogix\Apps\Rules.

The location where Rules and Rule Sets are accessed differ if the FSLogix installation location is changed.

To deploy a rule set, use any method to copy rule files (.fxr) and assignment files (.fxa) to the rules directory.

Cloud Cache

Details on configuring cloud cache

Disaster recovery and Replication

The FSLogix agent can support multiple profile locations if you configure the registry entries for FSLogix.

To configure the registry entries:

1.Open the Registry Editor.

2.Go to Computer > HKEY_LOCAL_MACHINE > SOFTWARE > FSLogix > Profiles.

3.Right-click on VHDLocations and select Edit Multi-String.

4.In the Value Data field, enter the locations you want to use.

5.When you're done, select OK.

If the first location is unavailable, the FSLogix agent will automatically fail over to the second, and so on.

It's recommended you configure the FSLogix agent with a path to the secondary location in the main region. Once the primary location shuts down, the FLogix agent will replicate as part of the VM Azure Site Recovery replication. Once the replicated VMs are ready, the agent will automatically attempt to path to the secondary region.

Troubleshooting App Performance

To assist in troubleshooting App performance you can enable performance counters with the following reg key:

  • reg add "HKLM\System\CurrentControlSet\Control\Terminal Server" /v "EnableLagCounter" /t REG_DWORD /d 0x1 /f

Use Performance monitor on the Session host to identify what could be causing issues.

Add the "User Input Delay per Process" or "User Input Delay per Session"

Automation of Session Hosts

To scale the session hosts and automatically power on and off you will need to setup azure automation using the scaling tool.

The scaling tool uses a combination of an Azure Automation account, a PowerShell runbook, a webhook, and the Azure Logic App to function. When the tool runs, Azure Logic App calls a webhook to start the Azure Automation runbook. The runbook then creates a job.

Create Azure automation account

You'll need an Azure Automation account to run the PowerShell runbook.

Use the following commands:

  • Login-AzAccount

Then get the script for creating the automation account:

Use the following script to run the automation account creation script with the configured parameters:

$Params = @{
    "AADTenantId"          = "<Azure_Active_Directory_tenant_ID>"  # Optional. If not specified, it will use the current Azure context.
    "SubscriptionId"        = "<Azure_subscription_ID>"              # Optional. If not specified, it will use the current Azure context.
    "UseARMAPI"            = $true
    "ResourceGroupName"    = "<Resource_group_name>"                # Optional. Default: "AVDAutoScaleResourceGroup"
    "AutomationAccountName" = "<Automation_account_name>"            # Optional. Default: "AVDAutoScaleAutomationAccount"
    "Location"              = "<Azure_region_for_deployment>"
    "WorkspaceName"        = "<Log_analytics_workspace_name>"      # Optional. If specified, Log Analytics will be used to configure the custom log table that the runbook PowerShell script can send logs to.
}
.\CreateOrUpdateAzAutoAccount.ps1 @Params

The cmdlet's output will include a webhook URI. Make sure to keep a record of the URI because you'll use it as a parameter when you set up the execution schedule for the Azure Logic App.

If you specified the parameter WorkspaceName for Log Analytics, the cmdlet's output will also include the Log Analytics Workspace ID and its Primary Key. Make sure to remember URI because you'll need to use it again later as a parameter when you set up the execution schedule for the Azure Logic App.

Create Azure Automation Run As Account

The Azure Automation Run As account allows access to your Azure resources.

Any user who's a member of the Subscription Admins role and coadministrator of the subscription can create a Run As account.

To create a Run As account in your Azure Automation account:

In the Azure portal, select All services. In the list of resources, enter and select Automation accounts.

On the Automation accounts page, select the name of your Azure Automation account.

In the pane on the left side of the window, select Run As accounts under the Account Settings section.

Select Azure Run As account. When the Add Azure Run As account pane appears, review the overview information, and then select Create to start the account creation process.

Wait a few minutes for Azure to create the Run As account. You can track the creation progress in the menu under Notifications.

When the process finishes, it will create an account in the specified Azure Automation account. Select Azure Run As account.

Create Azure Logic App and schedule

Next, you'll need to create the Azure Logic App and set up an execution schedule for your new scaling tool.

Run the following commands:

  • Login-AzAccount

Run the following cmdlet to download the script for creating the Azure Logic App.

Run the following PowerShell script to create the Azure Logic App and execution schedule for your host pool:

$AADTenantId = (Get-AzContext).Tenant.Id

$AzSubscription = Get-AzSubscription | Out-GridView -OutputMode:Single -Title "Select your Azure Subscription"
Select-AzSubscription -Subscription $AzSubscription.Id

$ResourceGroup = Get-AzResourceGroup | Out-GridView -OutputMode:Single -Title "Select the resource group for the new Azure Logic App"

$AVDHostPool = Get-AzResource -ResourceType "Microsoft.DesktopVirtualization/hostpools" | Out-GridView -OutputMode:Single -Title "Select the host pool you'd like to scale"

$LogAnalyticsWorkspaceId = Read-Host -Prompt "If you want to use Log Analytics, enter the Log Analytics Workspace ID returned by when you created the Azure Automation account, otherwise leave it blank"
$LogAnalyticsPrimaryKey = Read-Host -Prompt "If you want to use Log Analytics, enter the Log Analytics Primary Key returned by when you created the Azure Automation account, otherwise leave it blank"
$RecurrenceInterval = Read-Host -Prompt "Enter how often you'd like the job to run in minutes, for example, '15'"
$BeginPeakTime = Read-Host -Prompt "Enter the start time for peak hours in local time, for example, 9:00"
$EndPeakTime = Read-Host -Prompt "Enter the end time for peak hours in local time, for example, 18:00"
$TimeDifference = Read-Host -Prompt "Enter the time difference between local time and UTC in hours, for example, +5:30"
$SessionThresholdPerCPU = Read-Host -Prompt "Enter the maximum number of sessions per CPU that will be used as a threshold to determine when new session host VMs need to be started during peak hours"
$MinimumNumberOfRDSH = Read-Host -Prompt "Enter the minimum number of session host VMs to keep running during off-peak hours"
$MaintenanceTagName = Read-Host -Prompt "Enter the name of the Tag associated with VMs you don't want to be managed by this scaling tool"
$LimitSecondsToForceLogOffUser = Read-Host -Prompt "Enter the number of seconds to wait before automatically signing out users. If set to 0, any session host VM that has user sessions, will be left untouched"
$LogOffMessageTitle = Read-Host -Prompt "Enter the title of the message sent to the user before they are forced to sign out"
$LogOffMessageBody = Read-Host -Prompt "Enter the body of the message sent to the user before they are forced to sign out"

$AutoAccount = Get-AzAutomationAccount | Out-GridView -OutputMode:Single -Title "Select the Azure Automation account"
$AutoAccountConnection = Get-AzAutomationConnection -ResourceGroupName $AutoAccount.ResourceGroupName -AutomationAccountName $AutoAccount.AutomationAccountName | Out-GridView -OutputMode:Single -Title "Select the Azure RunAs connection asset"

$WebhookURIAutoVar = Get-AzAutomationVariable -Name 'WebhookURIARMBased' -ResourceGroupName $AutoAccount.ResourceGroupName -AutomationAccountName $AutoAccount.AutomationAccountName

$Params = @{
    "AADTenantId"                  = $AADTenantId                            # Optional. If not specified, it will use the current Azure context
    "SubscriptionID"                = $AzSubscription.Id                      # Optional. If not specified, it will use the current Azure context
    "ResourceGroupName"            = $ResourceGroup.ResourceGroupName        # Optional. Default: "AVDAutoScaleResourceGroup"
    "Location"                      = $ResourceGroup.Location                  # Optional. Default: "West US2"
    "UseARMAPI"                    = $true
    "HostPoolName"                  = $AVDHostPool.Name
    "HostPoolResourceGroupName"    = $AVDHostPool.ResourceGroupName          # Optional. Default: same as ResourceGroupName param value
    "LogAnalyticsWorkspaceId"      = $LogAnalyticsWorkspaceId                # Optional. If not specified, script will not log to the Log Analytics
    "LogAnalyticsPrimaryKey"        = $LogAnalyticsPrimaryKey                  # Optional. If not specified, script will not log to the Log Analytics
    "ConnectionAssetName"          = $AutoAccountConnection.Name              # Optional. Default: "AzureRunAsConnection"
    "RecurrenceInterval"            = $RecurrenceInterval                      # Optional. Default: 15
    "BeginPeakTime"                = $BeginPeakTime                          # Optional. Default: "09:00"
    "EndPeakTime"                  = $EndPeakTime                            # Optional. Default: "17:00"
    "TimeDifference"                = $TimeDifference                          # Optional. Default: "-7:00"
    "SessionThresholdPerCPU"        = $SessionThresholdPerCPU                  # Optional. Default: 1
    "MinimumNumberOfRDSH"          = $MinimumNumberOfRDSH                    # Optional. Default: 1
    "MaintenanceTagName"            = $MaintenanceTagName                      # Optional.
    "LimitSecondsToForceLogOffUser" = $LimitSecondsToForceLogOffUser          # Optional. Default: 1
    "LogOffMessageTitle"            = $LogOffMessageTitle                      # Optional. Default: "Machine is about to shutdown."
    "LogOffMessageBody"            = $LogOffMessageBody                      # Optional. Default: "Your session will be logged off. Please save and close everything."
    "WebhookURI"                    = $WebhookURIAutoVar.Value
}

.\CreateOrUpdateAzLogicApp.ps1 @Params

After you run the script, the Azure Logic App should appear in a resource group

To make changes to the execution schedule, such as changing the recurrence interval or time zone, go to the Azure Logic Apps autoscale scheduler and select Edit to go to the Azure Logic Apps Designer