Proactively monitor ARM-based Windows Virtual Desktop with Azure Log Analytics and Azure Monitor
Published Jul 08 2020 06:36 AM 61.9K Views

In this post, we’ll explain how to configure Azure Monitor with Azure Log Analytics in Microsoft Azure, so you can proactively monitor your Azure Resource Manager (ARM)-based Windows Virtual Desktop environment.

This blog post, which comes from a collaboration of different teams within Microsoft, aims to empower our customers on the ARM-based Windows Virtual Desktop. The information in this post is community driven. Nothing is officially launched by the Windows Virtual Desktop product team. I want to highlight @VanessaBruwer, @JasonByway and @ThomasVuylsteke at Microsoft for their work creating the custom workbook.

Let's begin. As shown in the diagram below, Azure Monitor can collect diagnostic data and operational insights from a variety of sources. You can monitor data for your workspace and virtual machine (VM) performance as well as tiered session information from your host pools, operating system and the services it relies on, and the platform itself.

Diagram of how data flows in and out of your Windows Virtual Desktop environmentDiagram of how data flows in and out of your Windows Virtual Desktop environment

By following the steps in this post, you can create a dashboard that provides access to insights about key elements of your Windows Virtual Desktop deployment, such as:

  • Session details
  • Session diagnostics
  • User specific reporting
  • Session performance
  • Host performance
  • Disk performance

2020-07-08 17_32_35-Window.png

Top three insights in the Windows Virtual Desktop workspace

The custom dashboard gives you visibility of key elements for your Windows Virtual Desktop workspace. Here, we’re highlighting the top three insights: session details, host pool performance, and disk performance.  

Session details

The dashboard view below shows the status of the most important session details—including top hosts, active users, and more—for your Windows Virtual Desktop workspace.

Screenshot of the Session Details dashboard for Windows Virtual DesktopScreenshot of the Session Details dashboard for Windows Virtual Desktop

Host pool performance

In this dashboard, you can collect and view information about the performance and registration statuses of your hosts.

Screenshot of the Host Performance dashboard for Windows Virtual DesktopScreenshot of the Host Performance dashboard for Windows Virtual Desktop

Disk performance

Through the Disk Performance dashboard you can view captured information about the storage level consumption of your profile container—virtual (logical) disks. This information can help you measure input/output operations per second (IOPS) and latency to your Azure Files or Azure NetApp Files environment regarding FSLogix Profile Container use in your Windows Virtual Desktop workspace.

Screenshot of the Disk Performance dashboard for Windows Virtual DesktopScreenshot of the Disk Performance dashboard for Windows Virtual Desktop

Prerequisites

To monitor your ARM-based Windows Virtual Desktop environment, be sure you have the following prerequisites in place:

Creating a Log Analytics workspace

  1. Search for Log Analytics and select Log Analytics workspaces.

    Searching for and selecting the Log Analytics workspaces serviceSearching for and selecting the Log Analytics workspaces service
  2. Select Add.

    Adding a Log Analytics workspaceAdding a Log Analytics workspace
  3. Name your Log Analytics workspace. Here, we’ve named our workspace wvdmonitorarm.
  4. Make sure that you are using the Pay-As-You-Go pricing tier.

    Note: You can calculate your Azure Monitoring costs upfront using the Azure Monitoring pricing calculator. The price will vary based on the time period required to capture data. For more information on optimizing costs, see Manage usage and costs with Azure Monitor Logs.

  5. Create the Log Analytics workspace.

    Reviewing and creating the Log Analytics workspaceReviewing and creating the Log Analytics workspace

Enable diagnostics on your Windows Virtual Desktop workspace

  1. Go to the Windows Virtual Desktop service on Azure and open the components of the service that you want to monitor.
  2. Select the host pool you want to monitor and open Diagnostic settings.

    Screenshot of pathway to host pool diagnostic settingsScreenshot of pathway to host pool diagnostic settings
  3. Check the desired log categories to activate them for the host pool.

    Specifying diagnostic settings and sending them to the Log Analytics workspaceSpecifying diagnostic settings and sending them to the Log Analytics workspace
  4. Check Send to Log Analytics and designate the workspace as the destination for diagnostic data.
  5. Repeat the same steps for Workspaces and Application groups.

Enable virtual machine insights to install the Workspace agent

To install the Workspace agent on the session hosts as part of your Windows Virtual Desktop host pool(s), perform the following steps.

  1. Search for and select Monitor in Azure services.

    Searching for and selecting Monitor in Azure servicesSearching for and selecting Monitor in Azure services
  2. Select Virtual Machines under Insights.
  3. Select Not monitored.
  4. Expand the resource group that contains your Windows Virtual Desktop hosts.

    Screenshot of Monitor page in Azure for Virtual MachinesScreenshot of Monitor page in Azure for Virtual Machines
  5. Select Enable.

    Screenshot of page during monitoring configurationScreenshot of page during monitoring configuration

The agent will automatically be installed and pushed to the session hosts via Azure extensions. For additional information, see Enable Azure Monitor for VMs overview.

Collect performance counters

  1. Open the Log Analytics workspace.
  2. Select Advanced settings.
  3. Follow the Data\Windows Performance Counters path.

    Note: Limits on API batches require collecting two batches of performance counters in the Log Analytics workspace.

  4. Select the + button to add the first 20 performance counters.

    Note: To avoid the “BatchRequestsLimitExceeded” error message, add a maximum of 20 counters for each batch.

    Batch collection 1

    Terminal Services Session(*)\% Processor Time

    Terminal Services(*)\Active Sessions

    Terminal Services(*)\Inactive Sessions

    Terminal Services(*)\Total Sessions

    LogicalDisk(*)\% Free Space

    LogicalDisk(*)\Avg. Disk sec/Read

    LogicalDisk(*)\Avg. Disk sec/Write

    LogicalDisk(*)\Current Disk Queue Length

    LogicalDisk(*)\Disk Reads/sec

    LogicalDisk(*)\Disk Transfers/sec

    LogicalDisk(*)\Disk Writes/sec

    LogicalDisk(*)\Free Megabytes

    Processor(_Total)\% Processor Time

    Memory(*)\% Committed Bytes In Use

    Network Adapter(*)\Bytes Received/sec

    Network Adapter(*)\Bytes Sent/sec

    Process(*)\% Processor Time

    Process(*)\% User Time

    Process(*)\IO Read Operations/sec

  5. Change the Sample Interval for all counters to 60 seconds.
  6. Select Save.

    Screenshot of Advanced settings, path to performance counters, and addition of performance counters in the Log Analytics workspaceScreenshot of Advanced settings, path to performance counters, and addition of performance counters in the Log Analytics workspace
  7. Add the second batch of performance counters.
    Batch collection 2

    Process(*)\IO Write Operations/sec

    Process(*)\Thread Count

    Process(*)\Working Set

    RemoteFX Graphics(*)\Average Encoding Time

    RemoteFX Graphics(*)\Frames Skipped/Second - Insufficient Client Resources

    RemoteFX Graphics(*)\Frames Skipped/Second - Insufficient Network Resources

    RemoteFX Graphics(*)\Frames Skipped/Second - Insufficient Server Resources

    RemoteFX Network(*)\Current TCP Bandwidth

    RemoteFX Network(*)\Current TCP RTT

    RemoteFX Network(*)\Current UDP Bandwidth

    RemoteFX Network(*)\Current UDP RTT

    PhysicalDisk(*)\Avg. Disk Bytes/Read
    PhysicalDisk(*)\Avg. Disk Bytes/Write
    PhysicalDisk(*)\Avg. Disk sec/Write
    PhysicalDisk(*)\Avg. Disk sec/Read
    PhysicalDisk(*)\Avg. Disk Bytes/Transfer
    PhysicalDisk(*)\Avg. Disk sec/Transfer
  8. As with the first batch, change the Sample Interval for all counters to 60 seconds.

    Note: If you do not change the Sample Interval, you may find that your workspace ingests more data, which can result in unexpected costs.

  9. Select Save.

Creating a workbook in Azure Monitor

  1. Go to Azure Monitor.
  2. Go to Workbooks and create a new workbook in Azure Monitor by selecting New.

    Creating a new workbook in Azure MonitorCreating a new workbook in Azure Monitor
  3. In the blank workbook that appears, select the </> button to access the Code - Advanced Editor.

    Screenshot of blank workbook page ready for code to be addedScreenshot of blank workbook page ready for code to be added
  4. Copy the code from this sample into the code area for the workbook, replacing the sample code in this workbook: https://github.com/wvdcommunity/AzureMonitor/blob/master/WVD-ARM-monitoring-workbook.json
  5. Select Apply.

    Applying code for the workbookApplying code for the workbook
  6. Select the Done editing button in the Monitor Workbooks dashboard.
  7. The log information will fill the custom workbook as shown below.

    Screenshot of the Windows Virtual Desktop dashboard with workbook insightsScreenshot of the Windows Virtual Desktop dashboard with workbook insights
  8. Name and save the workbook. (In the example below, we’ve named the workbook Windows Virtual Desktop).

    Naming and saving the Monitor workbookNaming and saving the Monitor workbook
  9. Select the SignInLogs diagnostic setting in Azure Active Directory to activate the Logon Location Heatmap diagnostic data.  

    Note: If you skip activating the Logon Location Heatmap diagnostic data, the error message shown below will appear. For more details, see Integrate Azure AD logs with Azure Monitor logs.

    View of error message “No logons detected in the last 7 days”View of error message “No logons detected in the last 7 days”

Sample queries

Now that you've enabled diagnostic data, here are some sample queries you can run.

Current active sessions

 

 

 

 

 

 

 

Perf
| where ObjectName == "Terminal Services"
| where CounterName == "Active Sessions"
| summarize arg_max(TimeGenerated, *) by Computer
| project Computer, CounterName, CounterValue

 

 

 

 

 

 

 

Current disconnected sessions

 

 

 

 

 

 

 

Perf
| where ObjectName == "Terminal Services"
| where CounterName == "Inactive Sessions"
| summarize arg_max(TimeGenerated, *) by Computer
| project Computer, CounterName, CounterValue

 

 

 

 

 

 

 

Current total sessions

 

 

 

 

 

 

 

Perf
| where ObjectName == "Terminal Services" 
| where CounterName == "Total Sessions" 
| summarize arg_max(TimeGenerated, *) by Computer
| project Computer, CounterName, CounterValue

 

 

 

 

 

 

 

Average and maximum sessions

 

 

 

 

 

 

 

Perf
| where ObjectName == "Terminal Services"
| where CounterName == "Total Sessions"
| summarize AggregatedValue = avg(CounterValue) by bin(TimeGenerated, 1h), Computer
Perf
| where ObjectName == "Terminal Services"
| where CounterName == "Total Sessions"
| summarize AggregatedValue = max(CounterValue) by bin(TimeGenerated, 1h), Computer

 

 

 

 

 

 

 

Session duration per user

 

 

 

 

 

 

 

let Events = WVDConnections | where UserName == 'username';
Events
| where State == "Connected"
| project CorrelationId , UserName, ResourceAlias , StartTime=TimeGenerated
| join (Events
| where State == "Completed"
| project EndTime=TimeGenerated, CorrelationId)
on CorrelationId
| project Duration = EndTime - StartTime, ResourceAlias
| sort by Duration desc

 

 

 

 

 

 

 

CPU, memory, disk, network usage per host

Logical disk:

 

 

 

 

 

 

 

 

Perf
| where ObjectName == "LogicalDisk" and CounterName == "% Free Space"
| where InstanceName <> "_Total"
| summarize AggregatedValue = avg(CounterValue) by bin(TimeGenerated, 10m), Computer, InstanceName

 

 

 

 

 

 

 

Processor:

 

 

 

 

 

 

 

Perf
| where ObjectName == "Processor" and CounterName == "% Processor Time"
| summarize AggregatedValue = avg(CounterValue) by bin(TimeGenerated, 10m), Computer, InstanceName

 

 

 

 

 

 

 

Memory:

 

 

 

 

 

 

 

Perf
| where ObjectName == "Memory" and CounterName == "% Committed Bytes In Use"
| summarize AggregatedValue = avg(CounterValue) by bin(TimeGenerated, 10m), Computer, InstanceName

 

 

 

 

 

 

 

Network:

 

 

 

 

 

 

 

Perf
| where ObjectName == "Network Interface"
| summarize AggregatedValue = avg(CounterValue) by bin(TimeGenerated, 10m), Computer, InstanceName, CounterName

 

 

 

 

 

 

 

Processor utilization per user:

 

 

 

 

 

 

 

Perf
| where ObjectName == "Process"
| join
(
VMProcess
| where UserName !contains "system" and UserName !contains "service"
| extend InstanceName = ExecutableName
| project TimeGenerated, InstanceName, Computer, UserName, UserDomain
)
on InstanceName
| summarize AggregatedValue = avg(CounterValue) by bin(TimeGenerated, 10m), InstanceName, CounterName, UserName, Computer

 

 

 

 

 

 

 

Inbound/outbound network bytes per user

 

 

 

 

 

 

 

VMConnection
| join
(
VMProcess
| where UserName !contains "system" and UserName !contains "service"
| extend ProcessName = ExecutableName
| project TimeGenerated, ProcessName, Computer, UserName, UserDomain
)
on ProcessName

 

 

 

 

 

 

 

RTT perf counter for RDP

 

 

 

 

 

 

 

Perf
| where ObjectName == "RemoteFX Network"
| where CounterName == "Current TCP RTT" or CounterName == "Current UDP RTT"
| summarize AggregatedValue = avg(CounterValue) by bin(TimeGenerated, 1h), Computer, InstanceName

 

 

 

 

 

 

 

Windows Virtual Desktop client type distribution

 

 

 

 

 

 

 

WVDConnections
| where State == "Connected"
| summarize ClientCount = dcount(UserName) by ClientOS, ClientVersion

 

 

 

 

 

 

 

Client types

 

 

 

 

 

 

 

WVDConnections
| where State == "Connected"
| extend ClientOSType = pack("ClientOSVersion", ClientOS)
| summarize AggregatedValue = count() by ClientOS

 

 

 

 

 

 

 

Windows Virtual Desktop agent health status

 

 

 

 

 

 

 

Heartbeat
| summarize heartbeat_count = count() by bin(TimeGenerated, 30m), Computer // bin is used to set the time grain to 30 minutes
| extend Available=iff(heartbeat_count > 0, true, false)
| summarize LastCall = max(TimeGenerated) by Computer, alive
| project Computer, LastCall, alive

 

 

 

 

 

 

 

Daily active users

 

 

 

 

 

 

 

Perf
| where ObjectName contains "Terminal Services" and CounterName == "Total Sessions"
| summarize TotalSessions = max(CounterValue) by bin(TimeGenerated, 1d), Computer

 

 

 

 

 

 

 

Top 10 hosts by CPU utilization

 

 

 

 

 

 

 

Perf
| where ObjectName == "Processor" and CounterName == "% Processor Time"
| summarize AggregatedValue = avg(CounterValue) by bin(TimeGenerated, 1h), Computer
| where AggregatedValue > 80
| order by AggregatedValue desc
| take 10

 

 

 

 

 

 

 

Disk performance

 

 

 

 

 

 

 

Perf
| where ObjectName == "PhysicalDisk" and CounterName == "Avg. Disk Bytes/Read" and InstanceName !contains "Total"
| parse InstanceName with * " " DriveLetter
| summarize AggregatedValue = avg(CounterValue) by bin(TimeGenerated, 10m), Computer, DriveLetter

 

 

 

 

 

 

 

Add the Windows Virtual Desktop workbook your Azure dashboard

Creating a custom dashboard as a landing page for your Azure portal is beneficial. This dashboard can also be used as a central page for your IT department.

  1. Open the custom Windows Virtual Desktop workbook you created in Azure Monitor.
  2. Select the pin buttons for the views you want to add to your Azure dashboard.

    Pinning views of monitoring data to the dashboardPinning views of monitoring data to the dashboard
  3. You can add all views at one time by selecting Pin Workbook in editing mode.
  4. When you are finished pinning the workbook, select Done Pinning.

    Selecting Done Pinning buttonSelecting Done Pinning button
  5. Select the Dashboard menu.

    Selecting the Dashboard to prepare for personalizing it with resource tilesSelecting the Dashboard to prepare for personalizing it with resource tiles
  6. Arrange the resource tiles to personalize the dashboard.
  7. Select Done customizing,

    Arranging resource tiles on the Windows Virtual Desktop Workspace DashboardArranging resource tiles on the Windows Virtual Desktop Workspace Dashboard

    This is an example of a workspace dashboard with tiles arranged:

    Screenshot of a Windows Virtual Desktop Workspace Dashboard with resource tiles arrangedScreenshot of a Windows Virtual Desktop Workspace Dashboard with resource tiles arranged
  8. Select the Auto refresh interval for the dashboard. Log Analytics metrics will refresh at the same rate as the dashboard.
  9. Select Apply.

    Selecting and applying refresh intervals for the dashboardSelecting and applying refresh intervals for the dashboard

Learn more

If you run into issues during setup, see Troubleshooting overview, feedback, and support for more information.

To stay informed about the latest Windows Virtual Desktop enhancements, join the Windows Virtual Desktop community on Tech Community, where you can also connect with the Windows Virtual Desktop Engineering team and your fellow public preview participants. For more information on tools that can help you empower end users to work securely in a remote work world, see Brad Anderson's post on New tools to help IT empower employees securely in a remote work world.

We welcome your feedback, comments, and questions below.

30 Comments
Version history
Last update:
‎Feb 02 2023 12:32 PM
Updated by: