Example diagnostic queries for session host update in Azure Virtual Desktop
Important
Session host update for Azure Virtual Desktop is currently in PREVIEW. See the Supplemental Terms of Use for Microsoft Azure Previews for legal terms that apply to Azure features that are in beta, preview, or otherwise not yet released into general availability.
Session host update uses Log Analytics in Azure Monitor to store information about updates. This article has some example Kusto queries you can use with Log Analytics to see information about session host updates.
Prerequisites
Before you can use these queries, you need:
An existing host pool with a session host configuration.
Configured diagnostic settings on each host pool you use with session host update to send logs and metrics to a Log Analytics workspace. The categories Checkpoint, Error, and Session Host Management Activity Logs must be enabled as a minimum.
A previously scheduled and run a session host update on the session hosts in the host pool.
Diagnostic data location
Once you configure diagnostic settings on a host pool, diagnostic data for session host update is stored in the tables WVDSessionHostManagement
and WVDCheckpoints
of your Log Analytics workspace. Log entries use the existing Management activity type, which comes from the Azure Resource Manager (ARM) provider.
The table WVDSessionHostManagement
is specific to session host update and is created once you enable the category Session Host Management Activity Logs on the diagnostic settings for each host pool you use with session host update, and session host update runs. If you previously configured diagnostic settings for a host pool, you need to enable the category Session Host Management Activity Logs. For more information Configure diagnostic settings to capture platform logs and metrics for Azure Virtual Desktop.
The rest of this article has some example queries you can run. You can use them as a basis to create your own queries. You need to run each of these queries in Log Analytics. For more information on how to run queries, see Start Log Analytics.
Session host updates that completed successfully
This query correlates the tables WVDSessionHostManagement
and WVDCheckpoints
to provide the time taken to complete an update and the median time to update a single session host in minutes in last 30 days:
let timeRange = ago(30d);
let succeededStatus = "Succeeded";
let hostPoolUpdateCompletedCheckpoint = "HostPoolUpdateCompleted";
let sessionHostUpdateCompletedCheckpoint = "SessionHostUpdateCompleted";
let provisioningTypeUpdate = "Update";
WVDSessionHostManagement
| where ProvisioningStatus == succeededStatus and TimeGenerated >= timeRange and ProvisioningType == provisioningTypeUpdate
| join kind = inner (
// Get number of session hosts updated
WVDCheckpoints
| where Name == hostPoolUpdateCompletedCheckpoint
| extend ParametersParsed = parse_json(Parameters)
| extend SessionHostUpdateCount = ParametersParsed["SessionHostsUpdateCompleted"], UpdateCompletionTime = todatetime(ParametersParsed["TimeCompleted"]), UpdateStartTime = todatetime(ParametersParsed["TimeStarted"])
| project CorrelationId, SessionHostUpdateCount, UpdateStartTime, UpdateCompletionTime
) on CorrelationId
| join kind = inner
(
// Get time to update individual session hosts
WVDCheckpoints
| where Name == sessionHostUpdateCompletedCheckpoint
| extend ParametersParsed = parse_json(Parameters)
| extend SessionHostUpdateTime = todecimal(ParametersParsed["TimeTakenToUpdateSessionHostInSeconds"])
// Calculate median time to update session host
| summarize SessionHostMedianUpdateTime = percentile(SessionHostUpdateTime, 50) by CorrelationId
) on CorrelationId
| project TimeGenerated, _SubscriptionId, _ResourceId, CorrelationId, UpdateStartDateTime = UpdateStartTime, UpdateEndDateTime = UpdateCompletionTime, ['UpdateDuration [InMinutes]'] = datetime_diff('minute', UpdateCompletionTime, UpdateStartTime), SessionHostUpdateCount, ['MedianSessionHostUpdateTime [InMinutes]'] = toint(SessionHostMedianUpdateTime/(60 * 1.0)), UpdateBatchSize = UpdateMaxVmsRemoved, FromSessionHostConfigVer, ToSessionHostConfigVer, UpdateDeleteOriginalVm
The dataset returned is as follows:
Column | Definition |
---|---|
TimeGenerated | System generated event timestamp |
_SubscriptionId | Subscription ID of a host pool |
_ResourceId | Resource ID of a host pool |
CorrelationId | Unique identifier assigned to every image update performed on a host pool |
UpdateStartDateTime | Session host update start timestamp in UTC |
UpdateEndDateTime | Session host update completion timestamp in UTC |
UpdateDuration | Time taken to complete to update the image of all session hosts in a host pool in minutes |
SessionHostUpdateCount | Number of session hosts updated |
MedianSessionHostUpdateTime | Median time to update the image of a single session host in minutes |
UpdateBatchSize | Number of session hosts that were in a single batch during an update of the image |
FromSessionHostConfigVer | Session host configuration before an update of the image |
ToSessionHostConfigVer | Session host configuration after an update of the image |
UpdateDeleteOriginalVm | Whether the original virtual machine was preserved after the completion of an update of the image |
Errors during a session host update
This query correlates the tables WVDSessionHostManagement
and WVDErrors
to provide information you can use to troubleshoot errors during session host updates in the last 30 days:
let timeRange = ago(30d);
let provisioningTypeUpdate = "Update";
WVDSessionHostManagement
| where ProvisioningStatus in ("Failed", "Error", "Canceled") and TimeGenerated >= timeRange and ProvisioningType == provisioningTypeUpdate
| summarize arg_max(TimeGenerated, _ResourceId, _SubscriptionId, FromSessionHostConfigVer, ToSessionHostConfigVer) by CorrelationId
| join kind = inner
(
// Get image update errors
WVDErrors
| where TimeGenerated >= timeRange
| extend IsSessionHostResourceIdAvailable = iif(Message startswith "SessionHostResourceId", 1, 0)
| extend startIndex = iif(IsSessionHostResourceIdAvailable == 1, indexof(Message, ":") + 1, 0)
| extend length = iif(IsSessionHostResourceIdAvailable == 1, indexof(Message, ";") - startIndex, 0)
// Get Session host ResourceId when available
| extend SessionHostResourceId = iif(IsSessionHostResourceIdAvailable == 1, substring(Message, startIndex, length), "")
| project TimeGenerated, CorrelationId, SessionHostResourceId, CodeSymbolic, Message
) on CorrelationId
| project TimeGenerated, _SubscriptionId, _ResourceId, CorrelationId, CodeSymbolic, SessionHostResourceId, Message, FromSessionHostConfigVer, ToSessionHostConfigVer
The dataset returned is as follows:
Column | Definition |
---|---|
TimeGenerated | System generated event timestamp |
_SubscriptionId | Subscription ID of a host pool |
_ResourceId | Resource ID of a host pool |
CorrelationId | Unique identifier assigned to every image update performed on a host pool |
CodeSymbolic | Error code |
SessionHostResourceId | Resource ID of a session host, if applicable |
Message | Error information |
FromSessionHostConfigVer | Session host configuration version before an image update |
ToSessionHostConfigVer | Session host configuration version to which session hosts were updated where the update process failed |
Session host updates canceled by an administrator before the scheduled time
This query correlates the tables WVDSessionHostManagement
and WVDCheckpoints
to provide session host updates that were scheduled, but then canceled by an administrator before they started, in the last 30 days:
let timeRange = ago(30d);
let canceledStatus = "Canceled";
let scheduledStatus = "Scheduled";
let hostPoolUpdateCanceledCheckpoint = "HostPoolUpdateCanceled";
let provisioningTypeUpdate = "Update";
WVDSessionHostManagement
| where ProvisioningStatus == canceledStatus and TimeGenerated >= timeRange and ProvisioningType == provisioningTypeUpdate
| join kind = inner
(
WVDCheckpoints
| where Name == "HostPoolUpdateCanceled"
| project TimeGenerated, CorrelationId, Name, Parameters
| extend ParametersParsed = parse_json(Parameters)
| extend StateFrom = tostring(ParametersParsed["StateFrom"]), StateTo = tostring(ParametersParsed["StateTo"]), CanceledTime = todatetime(ParametersParsed["TimeCanceled"])
| where StateFrom == scheduledStatus and StateTo == canceledStatus
) on CorrelationId
| project TimeGenerated, _SubscriptionId, _ResourceId, CorrelationId, ScheduledDateTime = todatetime(ScheduledDateTime), CanceledDateTime = CanceledTime, UpdateBatchSize = UpdateMaxVmsRemoved
The dataset returned is as follows:
Column | Definition |
---|---|
TimeGenerated | System generated event timestamp |
_SubscriptionId | Subscription ID of a host pool |
_ResourceId | Resource ID of a host pool |
CorrelationId | Unique identifier assigned to every update of the image of a host pool |
ScheduledDateTime | Session host update scheduled time in UTC |
CanceledDateTime | Time in UTC when an update of the image was canceled by an administrator |
UpdateBatchSize | Number of session hosts that were in a single batch during an update of the image |
Session host updates that were in progress or failed, then later canceled by an administrator
This query correlates the tables WVDSessionHostManagement
and WVDCheckpoints
to provide session host updates that were in progress or failed, then later canceled by an administrator in the last 30 days:
let timeRange = ago(30d);
let canceledStatus = "Canceled";
let scheduledStatus = "Scheduled";
let hostPoolUpdateCanceledCheckpoint = "HostPoolUpdateCanceled";
let provisioningTypeUpdate = "Update";
WVDSessionHostManagement
| where ProvisioningStatus == canceledStatus and TimeGenerated >= timeRange and ProvisioningType == provisioningTypeUpdate
| join kind = inner
(
WVDCheckpoints
| where Name == hostPoolUpdateCanceledCheckpoint
| project TimeGenerated, CorrelationId, Name, Parameters
| extend ParametersParsed = parse_json(Parameters)
| extend StateFrom = tostring(ParametersParsed["StateFrom"]), StateTo = tostring(ParametersParsed["StateTo"]), CanceledTime = todatetime(ParametersParsed["TimeCanceled"]), TotalSessionHostsInHostPool = toint(ParametersParsed["TotalSessionHostsInHostPool"]), SessionHostUpdateCount = ParametersParsed["SessionHostsUpdateCompleted"]
| where StateFrom != scheduledStatus and StateTo == canceledStatus
) on CorrelationId
| project TimeGenerated, _SubscriptionId, _ResourceId, CorrelationId, ScheduledDateTime = todatetime(ScheduledDateTime), CanceledDateTime = CanceledTime, TotalSessionHostsInHostPool, SessionHostUpdateCount, UpdateBatchSize = UpdateMaxVmsRemoved
The dataset returned is as follows:
Column | Definition |
---|---|
TimeGenerated | System generated event timestamp |
_SubscriptionId | Subscription ID of a host pool |
_ResourceId | Resource ID of a host pool |
CorrelationId | Unique identifier assigned to every update of the session host of a host pool |
ScheduledDateTime | Session host update scheduled time in UTC |
CanceledDateTime | Time in UTC when an administrator canceled an update of the session host |
TotalSessionHostsInHostPool | Total number of session hosts in a host pool |
SessionHostUpdateCount | Number of session hosts that were updated before canceling a session host update |
UpdateBatchSize | Number of session hosts in a single batch during an update of the session host |
Status of every session host update
This query correlates the tables WVDSessionHostManagement
and WVDCheckpoints
to provide the latest status of every session host update in the last 30 days:
let timeRange = ago(30d);
let sessionHostUpdateCompletedCheckpoint = "SessionHostUpdateCompleted";
let provisioningTypeUpdate = "Update";
WVDSessionHostManagement
| where TimeGenerated >= timeRange and ProvisioningType == provisioningTypeUpdate
| join kind = leftouter (
// Get number of session hosts updated if available
WVDCheckpoints
| where Name == sessionHostUpdateCompletedCheckpoint
| summarize SessionHostUpdateCount = count() by CorrelationId
) on CorrelationId
| summarize arg_max(TimeGenerated, _SubscriptionId, _ResourceId, ScheduledDateTime, UpdateMaxVmsRemoved, SessionHostUpdateCount, ProvisioningStatus) by CorrelationId
| project TimeGenerated, _SubscriptionId, _ResourceId, CorrelationId, ProvisioningStatus, ScheduledDateTime = todatetime(ScheduledDateTime), UpdateBatchSize = UpdateMaxVmsRemoved, SessionHostUpdateCount = iif(isempty(SessionHostUpdateCount), 0, SessionHostUpdateCount)
The dataset returned is as follows:
Column | Definition |
---|---|
TimeGenerated | System generated event timestamp |
_SubscriptionId | Subscription ID for a host pool |
_ResourceId | Resource ID of a host pool |
CorrelationId | Unique identifier assigned to every update of the image of a host pool |
ProvisioningStatus | Current status of an update of the image of a host pool |
ScheduledDateTime | Session host update scheduled time in UTC |
UpdateBatchSize | Number of session hosts in a single batch during an update of the image |
SessionHostUpdateCount | Number of session hosts that were updated |
Next steps
For troubleshooting guidance for session host update, see Troubleshoot session host update.