Settings an alert if available sessions is low

%3CLINGO-SUB%20id%3D%22lingo-sub-2481176%22%20slang%3D%22en-US%22%3ESettings%20an%20alert%20if%20available%20sessions%20is%20low%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2481176%22%20slang%3D%22en-US%22%3E%3CP%3EHi%2C%3CBR%20%2F%3E%3CBR%20%2F%3EI%20want%20to%20configure%20an%20alert%20when%20available%20sessions%20in%20a%20host%20pool%20is%20too%20low.%3CBR%20%2F%3EI'm%20looking%20at%20Log%20Analytics%20of%20course%20to%20do%20this%2C%20I%20do%20however%20have%20problems%20finding%20the%20right%20query.%3CBR%20%2F%3EI%20can%20query%20the%20current%20amount%20of%20sessions%2C%20no%20problem%20%2Cbut%20I%20need%20that%20to%20substract%20from%20the%20max%20I%20think.%20Any%20idea%20how%20I%20can%20query%20the%20available%20sessions%20%3F%20(either%20per%20host%20or%20per%20host%20pool)%3CBR%20%2F%3E%3CBR%20%2F%3E%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-LABS%20id%3D%22lingo-labs-2481176%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3EAlerting%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2487316%22%20slang%3D%22en-US%22%3ERe%3A%20Settings%20an%20alert%20if%20available%20sessions%20is%20low%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2487316%22%20slang%3D%22en-US%22%3EI%20would%20give%20Sepago%20a%20try%20for%20AVD%20monitoring%3A%20%3CA%20href%3D%22http%3A%2F%2Floganalytics.sepago.com%2Ffacts.html%22%20target%3D%22_blank%22%20rel%3D%22nofollow%20noopener%20noreferrer%22%3Ehttp%3A%2F%2Floganalytics.sepago.com%2Ffacts.html%3C%2FA%3E%20-%20it%20has%20a%20bunch%20of%20Monitors%20and%20dashboards.%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2491928%22%20slang%3D%22en-US%22%3ERe%3A%20Settings%20an%20alert%20if%20available%20sessions%20is%20low%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2491928%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F313219%22%20target%3D%22_blank%22%3E%40vinisz%3C%2FA%3EHey%2C%20Vinisz%3C%2FP%3E%3CP%3EI%20don't%20have%20the%20Kusto%20query%20for%20you%2C%20but%20this%20could%20be%20an%20alternative%20option.%20look%20at%20this%20(full%20Credit%20goes%20to%20Travis%2C%20I%20just%20pulled%20the%20relevant%20parts%20out%20-%20replace%20the%20hostpool%20variables%20with%20your%20own)%2C%20you%20should%20be%20able%20to%20turn%20the%20below%20into%20an%20Azure%20Automation%20runbook%20to%20trigger%20an%20email%20based%20on%20count%3A%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%23%3CA%20href%3D%22https%3A%2F%2Fraw.githubusercontent.com%2Ftsrob50%2FWVD-Public%2Fmaster%2FWVDARM_ScaleHostPoolVMs.ps1%22%20target%3D%22_blank%22%20rel%3D%22nofollow%20noopener%20noreferrer%22%3Ehttps%3A%2F%2Fraw.githubusercontent.com%2Ftsrob50%2FWVD-Public%2Fmaster%2FWVDARM_ScaleHostPoolVMs.ps1%3C%2FA%3E%3CBR%20%2F%3E%23%20Set%20default%20error%20action%3CBR%20%2F%3E%24defaultErrorAction%20%3D%20%24ErrorActionPreference%3C%2FP%3E%3CP%3E%23%20Enable%20Verbose%20logging%3CBR%20%2F%3E%24VerbosePreference%20%3D%20'SilentlyContinue'%3C%2FP%3E%3CP%3E%24hostPoolName%20%3D%20'avd-pooled'%3CBR%20%2F%3E%24hostPoolRg%20%3D%20'avd_prod'%3C%2FP%3E%3CP%3E%24hostPool%20%3D%20Get-AzWvdHostPool%20-ResourceGroupName%20%24hostPoolRg%20-HostPoolName%20%24hostPoolName%3CBR%20%2F%3E%24sessionHosts%20%3D%20Get-AzWvdSessionHost%20-ResourceGroupName%20%24hostPoolRg%20-HostPoolName%20%24hostPoolName%20%7C%20Where-Object%20%7B%20%24_.AllowNewSession%20-eq%20%24true%20%7D%3CBR%20%2F%3E%24runningSessionHosts%20%3D%20%24sessionHosts%20%7C%20Where-Object%20%7B%20%24_.Status%20-eq%20%22Available%22%20%7D%3CBR%20%2F%3E%23%20Get%20the%20Max%20Session%20Limit%20on%20the%20host%20pool%3CBR%20%2F%3E%23%20This%20is%20the%20total%20number%20of%20sessions%20per%20session%20host%3CBR%20%2F%3E%24maxSession%20%3D%20%24hostPool.MaxSessionLimit%3CBR%20%2F%3E%23%20Get%20current%20active%20user%20sessions%3CBR%20%2F%3E%24currentSessions%20%3D%200%3CBR%20%2F%3Eforeach%20(%24sessionHost%20in%20%24sessionHosts)%20%7B%3CBR%20%2F%3E%24count%20%3D%20%24sessionHost.session%3CBR%20%2F%3E%24currentSessions%20%2B%3D%20%24count%3CBR%20%2F%3E%7D%3CBR%20%2F%3E%24runningSessionHostsCount%20%3D%20%24runningSessionHosts.count%3CBR%20%2F%3E%24sessionHostTarget%20%3D%20%5Bmath%5D%3A%3ACeiling(((%24currentSessions)%20%2F%20%24maxSession))%3CBR%20%2F%3Eif%20(%24runningSessionHostsCount%20-lt%20%24sessionHostTarget)%20%7B%3CBR%20%2F%3EWrite-Verbose%20%22Running%20session%20host%20count%20%24runningSessionHostsCount%20is%20less%20than%20session%20host%20target%20count%20%24sessionHostTarget%22%3C%2FP%3E%3CP%3E%7D%3CBR%20%2F%3Eelseif%20(%24runningSessionHostsCount%20-gt%20%24sessionHostTarget)%20%7B%3CBR%20%2F%3EWrite-Verbose%20%22Running%20session%20hosts%20count%20%24runningSessionHostsCount%20is%20greater%20than%20session%20host%20target%20count%20%24sessionHostTarget%22%3C%2FP%3E%3CP%3E%7D%3CBR%20%2F%3Eelse%20%7B%3CBR%20%2F%3EWrite-Verbose%20%22Running%20session%20host%20count%20%24runningSessionHostsCount%20matches%20session%20host%20target%20count%20%24sessionHostTarget%2C%20doing%20nothing%22%3CBR%20%2F%3E%7D%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2523340%22%20slang%3D%22en-US%22%3ERe%3A%20Settings%20an%20alert%20if%20available%20sessions%20is%20low%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2523340%22%20slang%3D%22en-US%22%3EYou%20could%20use%20a%20KQL%20query%20like%20below.%20Update%20the%20computer%20name%20to%20match%20your%20session%20host%20prefix%20and%20update%20the%20counter%20value%20to%20a%20number%20slightly%20below%20the%20%22max%20session%20limit%22%20value%20on%20your%20host%20pool.%3CBR%20%2F%3E%3CBR%20%2F%3EPerf%3CBR%20%2F%3E%7C%20where%20ObjectName%20%3D%3D%20%22Terminal%20Services%22%3CBR%20%2F%3E%7C%20where%20CounterName%20%3D%3D%20%22Active%20Sessions%22%3CBR%20%2F%3E%7C%20where%20Computer%20contains%20%22avd%22%3CBR%20%2F%3E%7C%20where%20CounterValue%20%26gt%3B%200%3CBR%20%2F%3E%7C%20summarize%20arg_max(TimeGenerated%2C%20*)%20by%20Computer%3CBR%20%2F%3E%7C%20project%20Computer%2C%20CounterName%2C%20CounterValue%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2539637%22%20slang%3D%22en-US%22%3ERe%3A%20Settings%20an%20alert%20if%20available%20sessions%20is%20low%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2539637%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F888660%22%20target%3D%22_blank%22%3E%40JasonMasten%3C%2FA%3E%26nbsp%3B%2C%20Pretty%20nice%20query%2C%20but%20it%20outputs%20the%20amount%20of%20sessions%20per-host.%3CBR%20%2F%3EWhat%20I'm%20looking%20for%20is%20per%20hostpool%20and%20then%20%22max%20sessions%20per%20pool%20-%20current%20sessions%20per%20pool%22%3C%2FP%3E%3CP%3EAl%20dynamic%20of%20course.%20(just%20like%20it%20is%20displayed%20in%20the%20Azure%20WVD%20workbook%20under%20%22utilization%22%3C%2FP%3E%3CP%3EIs%20there%20no%20way%20to%20get%20underlying%20query%20of%20that%20one%20%3F%3C%2FP%3E%3C%2FLINGO-BODY%3E
Contributor

Hi,

I want to configure an alert when available sessions in a host pool is too low.
I'm looking at Log Analytics of course to do this, I do however have problems finding the right query.
I can query the current amount of sessions, no problem ,but I need that to substract from the max I think. Any idea how I can query the available sessions ? (either per host or per host pool)

11 Replies
I would give Sepago a try for AVD monitoring: http://loganalytics.sepago.com/facts.html - it has a bunch of Monitors and dashboards.
I know the sepago solution and I think it was nice before Azure monitor workbook was there, but I'm not talking about monitoring with all kinds of dashboards and graphs, that is all nice but I'm not going to watch a screen the entire day, I just want to receive alerts when available sessions is low.
It think it all has to do with the right LA query, if someone can provide that it would help a lot.

@viniszHey, Vinisz

I don't have the Kusto query for you, but this could be an alternative option. look at this (full Credit goes to Travis, I just pulled the relevant parts out - replace the hostpool variables with your own), you should be able to turn the below into an Azure Automation runbook to trigger an email based on count:

 

#https://raw.githubusercontent.com/tsrob50/WVD-Public/master/WVDARM_ScaleHostPoolVMs.ps1
# Set default error action
$defaultErrorAction = $ErrorActionPreference

# Enable Verbose logging
$VerbosePreference = 'SilentlyContinue'

$hostPoolName = 'avd-pooled'
$hostPoolRg = 'avd_prod'

$hostPool = Get-AzWvdHostPool -ResourceGroupName $hostPoolRg -HostPoolName $hostPoolName
$sessionHosts = Get-AzWvdSessionHost -ResourceGroupName $hostPoolRg -HostPoolName $hostPoolName | Where-Object { $_.AllowNewSession -eq $true }
$runningSessionHosts = $sessionHosts | Where-Object { $_.Status -eq "Available" }
# Get the Max Session Limit on the host pool
# This is the total number of sessions per session host
$maxSession = $hostPool.MaxSessionLimit
# Get current active user sessions
$currentSessions = 0
foreach ($sessionHost in $sessionHosts) {
$count = $sessionHost.session
$currentSessions += $count
}
$runningSessionHostsCount = $runningSessionHosts.count
$sessionHostTarget = [math]::Ceiling((($currentSessions) / $maxSession))
if ($runningSessionHostsCount -lt $sessionHostTarget) {
Write-Verbose "Running session host count $runningSessionHostsCount is less than session host target count $sessionHostTarget"

}
elseif ($runningSessionHostsCount -gt $sessionHostTarget) {
Write-Verbose "Running session hosts count $runningSessionHostsCount is greater than session host target count $sessionHostTarget"

}
else {
Write-Verbose "Running session host count $runningSessionHostsCount matches session host target count $sessionHostTarget, doing nothing"
}

You could use a KQL query like below. Update the computer name to match your session host prefix and update the counter value to a number slightly below the "max session limit" value on your host pool.

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

@Luke Murray 

I'm no powershell guru, but there is not output at all from this script.
Also, it gives an error like:

elseif : The term 'elseif' is not recognized as the name of a cmdlet, function, script file, or operable program. Check
 the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ elseif ($runningSessionHostsCount -gt $sessionHostTarget) {
+ ~~~~~~
    + CategoryInfo          : ObjectNotFound: (elseif:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

@JasonMasten , Pretty nice query, but it outputs the amount of sessions per-host.
What I'm looking for is per hostpool and then "max sessions per pool - current sessions per pool"

Al dynamic of course. (just like it is displayed in the Azure WVD workbook under "utilization"

Is there no way to get underlying query of that one ?

Well, I can see this query is in the workbook, now, how do I get this working for monitor ?

"let WVDHosts = dynamic([{WVDHosts}]);\r\nlet hostPool = \"{HostPool:label}\";\r\nPerf\r\n| extend Computername = strcat(hostPool, '/', Computer)| where Computername in (WVDHosts)\r\n| where TimeGenerated {TimeRange:query}\r\n| where ObjectName startswith \"Terminal Services\" and CounterName == \"Total Sessions\"\r\n| summarize Val= max(CounterValue-2) by bin(TimeGenerated, 1m), Computer\r\n| summarize Val= sum(Val) by TimeGenerated\r\n| project Val = ({VSessionLimit}*{SessionHostCount}) - Val, TimeGenerated\r\n| make-series [\"Available Sessions\"] = min(Val) on TimeGenerated step {TimeRange:grain}\r\n| where array_length(TimeGenerated) > 0\r\n"
I know how to set the alerts, I just need the right query, that is what this post is about..

@vinisz did you every find the solution to this? I am currently trawling the internet for the right Kusto query.

 

Kind regards,

Well, not in the way I wanted it to work in the first time, but we are now doing this via a logic-app, which asks the host pools via the API and then the session hosts of that pool.
After that, some calculations with retrieved data and then it can check the available sessions.
At the end, we send that data to log-analytics for trending (in powerBI) and to put an alert on it (via log analytics alert) , still working for several months like this without any problems