Monitoring your Lync Peak Call Capacity

Both SIP and ISDN trunk providers will often bill you based on the number of simultaneous calls/channels they provide (as well as minute charges). As a result you may end up scaling your capacity above what your real needs might be, just to be on the safe side.

With Lync there is no available tool to monitor this, neither real-time nor historically. There used to be a cool script available by Tom Pacyk to do this, but the times this need has arisen over the last year I have only been faced by an error message stating that the resource is not available.

The call performance counters reside on the Mediation server and are by no means a secret, but I haven’t seen anyone else (beside Tom) provide something to output them.

That aside; I decided to make my own PowerShell script to this.
It is still maturing, but for now it will give you

  • Console output with the current total of inbound, outbound and concurrent calls (sampled every 15 seconds)
  • CSV file output with hourly peak and average (per 15 seconds) statistics on the same counters

I will continue to develop it into a more complete solution, as I see fit. If you have suggestions or comments on the topic they are more than welcome! Although, I have to admit that my PowerShell skills are not unlimited, I promise to give it my best effort!

DISCLAIMER: As I just began working for a new employer where I have not yet got the chance to upgrade our Lync platform to server 2013, I can only vouch for it working on Lync Server 2010 – but I cannot see any reason why it should not run on the 2013 version (the counters would be identical, I think). In any case it will have to be run on the server hosting the Mediation role.

Download the latest version of the script from here.


Release history:

April 15 2014 – v0.5 – first basic version, dumping hourly statistics to CSV file (max/avg in/out/concurrent calls)
April 16 2014 – v0.8 – added console output with current counters, added keyboard input to exit script


8 thoughts on “Monitoring your Lync Peak Call Capacity

  1. NeWay Technologies – Weekly Newsletter #91 – April 17, 2014 | NeWay

  2. NeWay Technologies – Weekly Newsletter #91 – April 18, 2014 | NeWay

  3. Rune, thank you for this script. I have tested it on a Lync 2013 with heavy load from Trio 5.0 in a native ucma integration, but your script doesn’t report the calls (conferences) housed in Trio. I can drop you a screenshot if you have interest. A script like this is absolutely a good tool to have available 🙂

    • Hi Simon, and thanks for the feedback.

      The script will report performance counters on the Mediation server where it is run, meaning that any call handled by a Trio Agent that is from/to an external participant should be reported.
      We run a Call Center based on Competella UCMA Application ourselves, and the script is ignorant to whether the call is from/to a Lync or UCMA endpoint – as long as it involves a PSTN participant it is captured.

      If you have a pool of Mediation servers the script will however only report the ones involving the one where the script is run. We are about to upgrade our Lync Servers including several Mediation serveres, at which point I will update it to summarize traffic from all servers.

      If you were looking for some output on the Trio Conferences themselves this script is not the right for you.


  4. Rune,

    Thanks for posting this. You note that it should probably work for 2013, but unfortunately it doesn’t. The counter names are slightly different.

    I was getting 0 results on calls with the original version, but I’ve since modified it for the 2013 counters on my mediation server.

    I’m going to post an entire revised version, because I don’t see an easy way to put an attachment. Hopefully the comments well collapse nicely.

    # Lets define the actual counter paths we will be fetching.
    # Changed to 2013 paths

    $outboundCallPath = “\LS:MediationServer – Outbound Calls(_Total)\- Current”
    $inboundCallPath = “\LS:MediationServer – Inbound Calls(_Total)\- Current”

    # Create CSV file for output. It will be named \Users\\Documents\Call counters DDMMYYY.csv

    $outputPath = $env:HOMEPATH + “\Documents\Call counters ” + (Get-Date -UFormat “%d%m%Y”) + “.csv”

    “Date;Hour;Avg inbound;Peak inbound;Avg outbound;Peak outbound;Avg concurrent;Peak concurrent” | Out-File -FilePath $outputPath -Encoding default
    “Unable to create file ” + $outputPath

    # Create empty arrays to store counters. These will be reset every hour.

    [int[]]$inboundCalls = $null
    [int[]]$outboundCalls = $null
    [int[]]$concurrentCalls = $null

    # Get the time
    $now = Get-Date

    # Now, for every 15 seconds we will repeat this same procedyre:
    # -> Fetch current call counter for inbound and outbound
    # -> Store data in array
    # -> if the hour changes, calculate average and peak counters and store to file

    do {

    # That was then, this is now
    $then = $now

    # Get the counters we want, and add them to the arrays
    [int]$currentInbound = (Get-Counter $inboundCallPath).CounterSamples[0].CookedValue.ToString()
    [int]$currentOutbound = (Get-Counter $outboundCallPath).CounterSamples[0].CookedValue.ToString()

    $inboundCalls += $currentInbound
    $outboundCalls += $currentOutbound
    $concurrentCalls += ($currentInbound + $currentOutbound)

    # Output to console
    “Current number of inbound calls: ” + $currentInbound
    “Current number of outbound calls: ” + $currentOutbound
    “Current number of concurrent calls: ” + ($currentInbound + $currentOutbound)

    # Now let’s get the time
    $now = Get-Date

    # Has the hour changed since then?
    if ($now.Hour -inotlike $then.Hour)

    # The peak and average value can be calculated and derived using Measure-Object
    $inbound = ($inboundCalls | Measure-Object -Maximum -Average)
    $outbound = ($outboundCalls | Measure-Object -Maximum -Average)
    $concurrent = ($concurrentCalls | Measure-Object -Maximum -Average)

    # Let’s append this to the CSV file we created
    (Get-Date -Date $then -UFormat “%d %b %Y;”) + $then.Hour + “;” + $inbound.Average + “;” + $inbound.Maximum + “;” + $outbound.Average + “;” + $outbound.Maximum + “;” + $concurrent.Average + “;” + $concurrent.Maximum | Out-File -FilePath $outputPath -Encoding default -Append

    # Let’s not forget to reset our arrays now that the hour has changed
    [int[]]$inboundCalls = $null
    [int[]]$outboundCalls = $null
    [int[]]$concurrentCalls = $null


    # Let’s hear if the user wants to end the script
    Write-Host “`n `nPress ESC to end the script!” -ForegroundColor Red

    # Loop around for 15 seconds while the user makes up his/her mind
    $i = 0

    $keypress = $Host.UI.RawUI.KeyAvailable
    if ($keypress)
    $end = $Host.UI.RawUI.ReadKey(“NoEcho,IncludeKeyDown”).VirtualKeyCode -eq 27

    # Let’t sleep for a second
    Start-Sleep -Seconds 1

    until ($end -or ($i -eq 15))
    while (-not $end)

    # Clean up and exit while pointing to the results file
    “`nCheck output file for any historical data:`n” + $outputPath + “`n”

  5. Monitoring Your Lync 2013 Peak Call Capacity | Eureka! I have found it!

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s