Skip to content

AVD Insights DCR template uses legacy \Terminal Services(*)\ wildcard format; counters not collected on Win11 24H2/25H2 multi-session #867

@ThojoUno

Description

@ThojoUno

What happened? Provide a clear and concise description of the bug, including deployment details.

Summary

The AVD Insights Data Collection Rule template at workload/bicep/modules/avdInsightsMonitoring/.bicep/dataCollectionRules.bicep requests three Terminal Services performance counters using the parenthesized wildcard instance format \Terminal Services(*)\Active Sessions. On Windows 11 multi-session 24H2 (build 26100) and 25H2 (build 26200), these counters are published as singletons  \Terminal Services\Active Sessions — without the wildcard.

The mismatch causes PdhAddEnglishCounter to fail with PDH_CSTATUS_BAD_COUNTERNAME (0xC0000BC0) and the counters are silently absent from the workspace Perf table even though the DCR is correctly associated and AMA is healthy.

Net effect

The three HostPool Capacity 50%/85%/95% alerts in any AMBA-aligned alert pack that depends on \Terminal Services(*)\Active Sessions (or Inactive/Total Sessions) cannot evaluate correctly. CPU, memory, disk, FSLogix, RemoteFX, User Input Delay, and other counters specified by the same DCR are unaffected.

Affected lines

workload/bicep/modules/avdInsightsMonitoring/.bicep/dataCollectionRules.bicep:80-82:

'\\Terminal Services(*)\\Active Sessions'
'\\Terminal Services(*)\\Inactive Sessions'
'\\Terminal Services(*)\\Total Sessions'

Reproduction

  1. Deploy the AVD accelerator with avdDeployMonitoring=true against a host pool whose session hosts run Win11 24H2 or 25H2 multi-session.
  2. Confirm the session hosts have AzureMonitorWindowsAgent extension installed and a DCR association to microsoft-avdi-{region}.
  3. From a session host, run:
    typeperf -q | Select-String "Terminal Services"
    
    Observed output (counters listed without parens):
    \Terminal Services\Total Sessions
    \Terminal Services\Inactive Sessions
    \Terminal Services\Active Sessions
    \Terminal Services Session(*)\% Processor Time
    \Terminal Services Session(*)\% User Time
    
  4. From AMA's runtime log (C:\WindowsAzure\Resources\AMADataStore.<host>\Tables\MAEventTable\...):
    Counter - MAEventTable: Level:2 ErrorCode:-1073738816:
    Message:PdhAddEnglishCounter(\Terminal Services(*)\Active Sessions) failed
    with PDH_CSTATUS_BAD_COUNTERNAME (0xC0000BC0)
    
    Same error for Inactive Sessions and Total Sessions.
  5. In the destination Log Analytics workspace, confirm that no rows with ObjectName == "Terminal Services" are produced for the affected hosts:
    Perf
    | where Computer startswith "<your-prefix>"
    | where TimeGenerated > ago(30m)
    | where ObjectName == "Terminal Services"
    | distinct CounterName
    
    Returns zero rows.

Distinguishing the two object names

  • Terminal Services (singleton, no parens) — what we need: contains Active Sessions, Inactive Sessions, Total Sessions. The DCR's current (*) form does not match this object.
  • Terminal Services Session(*) (multi-instance, parens correct) — different counter object entirely; contains % Processor Time, % User Time, etc. The DCR doesn't request these, but they're listed in typeperf output and confirm the parenthesized form does work for the objects that genuinely are multi-instance.

The DCR's other parenthesized counters (\LogicalDisk(C:)\..., \PhysicalDisk(*)\..., \User Input Delay per Process(*)\..., etc.) all work correctly because their target objects are actually multi-instance.

Confirmed Windows versions affected

Build | Edition | Status -- | -- | -- 26100 | Windows 11 Enterprise multi-session 24H2 | Affected 26200 | Windows 11 Enterprise multi-session 25H2 | Affected

Proposed fix

Update workload/bicep/modules/avdInsightsMonitoring/.bicep/dataCollectionRules.bicep:80-82 to remove the (*) instance specifier from the three Terminal Services counter specifiers:

                 '\\LogicalDisk(C:)\\% Free Space'
                 '\\LogicalDisk(C:)\\Avg. Disk sec/Transfer'
-                '\\Terminal Services(*)\\Active Sessions'
-                '\\Terminal Services(*)\\Inactive Sessions'
-                '\\Terminal Services(*)\\Total Sessions'
+                '\\Terminal Services\\Active Sessions'
+                '\\Terminal Services\\Inactive Sessions'
+                '\\Terminal Services\\Total Sessions'

Verified working — after applying the change to a fork and redeploying the DCR in-place, AMA picks up the new config on its next refresh, registers the correctly-named counters via PdhAddEnglishCounter, and starts publishing rows to Perf with ObjectName == "Terminal Services" within ~5–10 minutes. Host pool capacity alerts evaluate correctly thereafter.

Backward compatibility note

If older Windows multi-session builds (Windows 10 multi-session 1909/2004/2009) still publish these counters under the parenthesized wildcard, mixed-version pools may need both forms or a per-host-OS conditional. We have not verified the older builds. For environments standardized on 24H2 or 25H2 (the supported AVD multi-session builds), the singleton form is correct and necessary.

The published Microsoft AVD Insights workbook templates that consume these counters likely have the same issue when querying Perf | where ObjectName == "Terminal Services" and CounterName == "Active Sessions" — the query is correct, but the data isn't there because the DCR isn't collecting it. Worth a parallel check on those templates.


Files / context to reference if asked

  • Local fix in this repo: 900-avd-accelerator/workload/bicep/modules/avdInsightsMonitoring/.bicep/dataCollectionRules.bicep (commit 75d6ad2)
  • Local audit trail: docs/handover/avd-tag-group-handover.md §8.4 F8

Summary The AVD Insights Data Collection Rule template at [workload/bicep/modules/avdInsightsMonitoring/.bicep/dataCollectionRules.bicep](https://github.com/Azure/avdaccelerator/blob/main/workload/bicep/modules/avdInsightsMonitoring/.bicep/dataCollectionRules.bicep) requests three Terminal Services performance counters using the parenthesized wildcard instance format \Terminal Services(*)\Active Sessions. On Windows 11 multi-session 24H2 (build 26100) and 25H2 (build 26200), these counters are published as singletons — \Terminal Services\Active Sessions — without the wildcard.

The mismatch causes PdhAddEnglishCounter to fail with PDH_CSTATUS_BAD_COUNTERNAME (0xC0000BC0) and the counters are silently absent from the workspace Perf table even though the DCR is correctly associated and AMA is healthy.

Net effect
The three HostPool Capacity 50%/85%/95% alerts in any AMBA-aligned alert pack that depends on \Terminal Services(*)\Active Sessions (or Inactive/Total Sessions) cannot evaluate correctly. CPU, memory, disk, FSLogix, RemoteFX, User Input Delay, and other counters specified by the same DCR are unaffected.

Affected lines
workload/bicep/modules/avdInsightsMonitoring/.bicep/dataCollectionRules.bicep:80-82:

'\Terminal Services()\Active Sessions'
'\Terminal Services(
)\Inactive Sessions'
'\Terminal Services()\Total Sessions'
Reproduction
Deploy the AVD accelerator with avdDeployMonitoring=true against a host pool whose session hosts run Win11 24H2 or 25H2 multi-session.
Confirm the session hosts have AzureMonitorWindowsAgent extension installed and a DCR association to microsoft-avdi-{region}.
From a session host, run:
typeperf -q | Select-String "Terminal Services"
Observed output (counters listed without parens):
\Terminal Services\Total Sessions
\Terminal Services\Inactive Sessions
\Terminal Services\Active Sessions
\Terminal Services Session(
)% Processor Time
\Terminal Services Session()% User Time
From AMA's runtime log (C:\WindowsAzure\Resources\AMADataStore.\Tables\MAEventTable...):
Counter - MAEventTable: Level:2 ErrorCode:-1073738816:
Message:PdhAddEnglishCounter(\Terminal Services(
)\Active Sessions) failed
with PDH_CSTATUS_BAD_COUNTERNAME (0xC0000BC0)
Same error for Inactive Sessions and Total Sessions.
In the destination Log Analytics workspace, confirm that no rows with ObjectName == "Terminal Services" are produced for the affected hosts:
Perf
| where Computer startswith ""
| where TimeGenerated > ago(30m)
| where ObjectName == "Terminal Services"
| distinct CounterName
Returns zero rows.
Distinguishing the two object names
Terminal Services (singleton, no parens) — what we need: contains Active Sessions, Inactive Sessions, Total Sessions. The DCR's current () form does not match this object.
Terminal Services Session(
) (multi-instance, parens correct) — different counter object entirely; contains % Processor Time, % User Time, etc. The DCR doesn't request these, but they're listed in typeperf output and confirm the parenthesized form does work for the objects that genuinely are multi-instance.
The DCR's other parenthesized counters (\LogicalDisk(C:)..., \PhysicalDisk()..., \User Input Delay per Process()..., etc.) all work correctly because their target objects are actually multi-instance.

Confirmed Windows versions affected
Build Edition Status
26100 Windows 11 Enterprise multi-session 24H2 Affected
26200 Windows 11 Enterprise multi-session 25H2 Affected
Proposed fix
Update workload/bicep/modules/avdInsightsMonitoring/.bicep/dataCollectionRules.bicep:80-82 to remove the (*) instance specifier from the three Terminal Services counter specifiers:

             '\\LogicalDisk(C:)\\% Free Space'
             '\\LogicalDisk(C:)\\Avg. Disk sec/Transfer'
  •            '\\Terminal Services(*)\\Active Sessions'
    
  •            '\\Terminal Services(*)\\Inactive Sessions'
    
  •            '\\Terminal Services(*)\\Total Sessions'
    
  •            '\\Terminal Services\\Active Sessions'
    
  •            '\\Terminal Services\\Inactive Sessions'
    
  •            '\\Terminal Services\\Total Sessions'
    

Verified working — after applying the change to a fork and redeploying the DCR in-place, AMA picks up the new config on its next refresh, registers the correctly-named counters via PdhAddEnglishCounter, and starts publishing rows to Perf with ObjectName == "Terminal Services" within ~5–10 minutes. Host pool capacity alerts evaluate correctly thereafter.

Backward compatibility note
If older Windows multi-session builds (Windows 10 multi-session 1909/2004/2009) still publish these counters under the parenthesized wildcard, mixed-version pools may need both forms or a per-host-OS conditional. We have not verified the older builds. For environments standardized on 24H2 or 25H2 (the supported AVD multi-session builds), the singleton form is correct and necessary.

Related
The published Microsoft AVD Insights workbook templates that consume these counters likely have the same issue when querying Perf | where ObjectName == "Terminal Services" and CounterName == "Active Sessions" — the query is correct, but the data isn't there because the DCR isn't collecting it. Worth a parallel check on those templates.

Files / context to reference if asked
Local fix in this repo: 900-avd-accelerator/workload/bicep/modules/avdInsightsMonitoring/.bicep/dataCollectionRules.bicep (commit 75d6ad2)
Local audit trail: docs/handover/avd-tag-group-handover.md §8.4 F8

Please provide the correlation id associated with your error or bug.

xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

What was the expected outcome?

No response

Relevant log output

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions