List Connections and Users connected to Lync Registrar Pool


The following script could be copied to %windir%/system32 as connections.ps1 in order to run it from Lync powershell directly.

 

It will list all the number of connectios to the registrar pool; i have added Listing all user aliases connected to Lync within the main Function.

#################################################################################################
# Connections.ps1
#
# Program to pull Lync connection information. 
# This program will pull complete information across all
# frontend servers in a pool.  It can also be used to find
# specific connection information on an individual user by
# supplying the user's sip address.  The parameter for
# the pool to access for connection information can be
# pre-populated so it doesn't have to be passed on the command line.
# Also it List all the connected Users.
#
# ACKNOWLEDGEMENT: This program's database connection information
#                  was originally taken from the "List Connections
#                  to Registrar Pools" submitted by Scott Stubberfield
#                  and Nick Smith from Microsoft to the Lync 2010
#                  PowerShell blog
#                  (http://blogs.technet.com/b/csps/) on June 10, 2010.
#
# NOTE: In order to gain remote access to each frontend server's
#       RTCLOCAL database where connection information is found,
#       you need to open the local firewall for port 1434.
#       Also, need to go into the SQL Server Configuration Manager
#       and for RTCLOCAL, enable named pipes and restart the SQL
#       service for the named pipes to take effect.
#
#       Port 1434 is required in order to make the connection to
#       the named instance RTCLOCAL on the remote machines.
#
#
# Written by: Tracy A. Cerise (tracy@uky.edu)
#       Date: March 2011
# --------------------
#
# Modification History
# Written by: Mahmoud Badran (v-mabadr@microsoft.com)
# Date: July 2011
# --------------------
#
# Could add # users with enterprise voice enabled and other
# individual stats to this page as well
#
#################################################################################################
 
##########################################################
# Commandline Parameters to use for running this program #
##########################################################
param($Pool = "cs-se.fabrikam.com", $SIPAddr, $FilePath, [switch] $Help)
 
 
 
#################################################################################################
#################################       Functions       #########################################
#################################################################################################
 
 
function GetData {
 
   param ($sipAddr = $null, $server)
 
   ##############################################################################################
   # Went to using a named parameter for this function due to the
   # way Powershell does its thing with parameter passing, which
   # is NOT GOOD!  At any rate, need to call this function
   # as you would from a command line: GetData -sipAddr "value"
   # -server "value"
   #
   # Also, assuming a value of NULL for the SIP address of an
   # individual user, mostly to use this for finding overall
   # values, only occasionally to seek specific users.
   ##############################################################################################
 
 
   if ($sipAddr) {
      $whereClause = "where R.UserAtHost = '$sipAddr' "
   }
   else {
      $whereClause = $null
   }
 
   #Define SQL Connection String
   $connstring = "server=$server\rtclocal;database=rtcdyn;trusted_connection=true;"
 
   #Define SQL Command
   $command = New-Object System.Data.SqlClient.SqlCommand
 
   $command.CommandText = "Select (cast (RE.ClientApp as varchar (100))) as ClientVersion, R.UserAtHost as UserName, Reg.Fqdn `
                           From rtcdyn.dbo.RegistrarEndpoint RE `
                           Inner Join `
                           rtc.dbo.Resource R on R.ResourceId = RE.OwnerId `
                           Inner Join `
                           rtcdyn.dbo.Registrar Reg on Reg.RegistrarId = RE.PrimaryRegistrarClusterId `
                           $whereClause `
                           Order By ClientVersion, UserName "
 
   $connection = New-Object System.Data.SqlClient.SqlConnection
   $connection.ConnectionString = $connstring
   $connection.Open()
 
   $command.Connection = $connection
 
   $sqladapter = New-Object System.Data.SqlClient.SqlDataAdapter
   $sqladapter.SelectCommand = $command
 
   $results = New-Object System.Data.Dataset
 
   $recordcount=$sqladapter.Fill($results)
 
   $connection.Close()
 
   return $Results.Tables[0]
}
#################################################################################################
 
 
function Help {
 
"
NAME
    Connections.ps1
 
 
SYNOPSIS
    Returns current connection count for all frontend servers in a given pool
    including a breakdown of connection by client, frontend server and users.
 
    It can also be used to return connection information on an individual user.
   
 
SYNTAX
    Connections.ps1 [-Pool <PoolFQDN>] [-SIPAddr] [-FilePath] [-help]
 
 
DESCRIPTION
    This program will return a connection count for a given pool.  The program
    can be edited to set a default pool.  You will also be able to get
    information on an individual user by providing the users SamAccountName.
    As well as listing all the connected users to the default pool.

 
 
EXAMPLES
 
    -------------------------- EXAMPLE 1 --------------------------
 
    C:\PS>connections.ps1
 
    Description
    -----------
    Returns information on all connections on all frontend servers in the
    default pool that has been hard-coded into the program.
 
 
    -------------------------- EXAMPLE 2 --------------------------
 
    C:\PS>connections.ps1 -Pool alternate.pool.fqdn
 
    Description
    -----------
    Returns information on all connections on all frontend servers in the
    pool given with the pool parameter.
 
 
    -------------------------- EXAMPLE 3 --------------------------
 
    C:\PS>connections.ps1 -SIPAddr userid@sip.domain
 
    Description
    -----------
    Returns all connection information for the given user including which
    frontend server connected to, how many connections and which clients
    connected with.
 
    -------------------------- EXAMPLE 4 --------------------------
 
    C:\PS>connections.ps1 -filepath c:\path\to\file\filename.csv
 
    Description
    -----------
    Returns information on all connections on all frontend servers in the
    default pool that has been hard-coded into the program and in addition
    writes out all the raw connection information into the filename specified.
 
 
"
   exit
 
}
#################################################################################################
 
 
#################################################################################################
#################################     Main Program      #########################################
#################################################################################################
 
#############################################
### Main program
#############################################
 
# If the help switch is toggled
if ($help) {
   Help
}
 
#
# Here is where we pull all the frontend server(s) from our topology for the designated
# pool and iterate through them to get current connections from all the servers.
#
# There are three possibilities here:
#    1. Have collection of frontend servers
#    2. Have a single frontend server or
#    3. Have no servers
#
# Only need to check for the first two cases, the third is implied otherwise...
 
$feServers = Get-CsComputer -Pool $Pool
 
 
if ($feServers.count) {
   # Frontend pool collection, iterate through them
   for ($i=0; $i -lt $feServers.count; $i++) {
 
      if ($SIPAddr) {
         $data = GetData  -sipAddr $SIPAddr -server $feServers[$i].identity
      }
      else {
         $data = GetData -server $feServers[$i].identity
      }
 
      # Since an individual user's connections are all homed on one server, won't have
      # data coming back from all frontend servers in the case of searching for a
      # single user
      if ($data) {
         $overallrecords = $overallrecords + $data
      }
   }
}
elseif ($feServers) {
   # Have a standalone server or a FE pool of only one server
   if ($SIPAddr) {
      $data = GetData  -sipAddr $SIPAddr -server $feServers.identity
   }
   else {
      $data = GetData -server $feServers.identity
   }
 
   # Make sure we have data to work with...
   if ($data) {
      $overallrecords = $data
   }
}
 
# Check to see if we have any data to act on
if (! $overallrecords) {
   write-host -ForegroundColor Yellow "`r`nNothing returned from query!`r`n"
 
   # Nothing else to do
   exit
}
else {
   $count=0
 
   $userHash = @{}
   $clientHash = @{}
   $serverHash = @{}
   $userlist = @{}
 
   $overallrecords | foreach-object {
      # Each record has three components: Connected Client Version, User's SIP
      # address and the frontend server's FQDN.  Here, we'll build a hash
      # for each of these components for each record.
 
      # Build hash of users

 $userlist = ($_.UserName)

      if (! $userHash.ContainsKey($_.UserName)) {
         $userHash.add($_.UserName, 1)
      }
      else {
         $userHash.set_item($_.UserName, ($userHash.get_item($_.UserName) + 1))
      }
 
      # Build hash of servers
      if (! $serverHash.ContainsKey($_.fqdn)) {
         $serverHash.add($_.fqdn, 1)
      }
      else {
         $serverHash.set_item($_.fqdn, ($serverHash.get_item($_.fqdn) + 1))
      }
 
      # Build hash of clients
      # Lets get rid of the extraneous verbage from the client version names, if applicable
      if ($_.ClientVersion.contains('(')) {
         # Get rid of extraneous verbage
         $clientName = $_.ClientVersion.substring(0, $_.ClientVersion.IndexOf('('))
      }
      else {
         # Have a client name with no extraneous verbage
         $clientName = $_.ClientVersion
      }
 
      if (! $clientHash.ContainsKey($clientName)) {
         $clientHash.add($clientName, 1)
      }
      else {
         $clientHash.set_item($ClientName, ($clientHash.get_item($ClientName) + 1))
      }
 
      $count++
   }
}
 
################################
####  Output Query Results  ####
################################
 
# If output to file is chosen, then write out the results and a note to that effect
# then exit
 
if ($FilePath) {
   $overallrecords | Export-Csv $FilePath
 
   write-host -foregroundcolor green "`r`nQuery Results written to $FilePath`r`n"
 
   exit
}
 
 
write-host -foregroundcolor cyan "`r`nClient Version/Agent                   Connections"
write-host -foregroundcolor cyan "--------------------------------------------------"
 
foreach ($key in $clientHash.keys) {
   # Break down client version into its two component parts and print
   # them out along with their respective counts in a nice format
   $index = $key.indexof(" ")
 
   if ($index -eq "-1") {
      # No second part
      $first = $key
      $second = " "
   }
   else {
      # Client version/agent has to main parts
      $first = $key.substring(0, $index)
      $second = $key.substring($index + 1)
   }
 
   $value = $clientHash.$key
 
   "{0, -20} {1, -20} {2, 5}" -f $first, $second, $value
}
 
write-host -foregroundcolor cyan "--------------------------------------------------"
 
write-host -foregroundcolor cyan "`r`n`r`nFrontend Server     Connections"
write-host -foregroundcolor cyan "-------------------------------"
 
foreach ($key in $serverHash.keys) {

   $value = $serverHash.$key
 
   "{0, -22} {1, 5}" -f $key, $value
}

 
write-host -foregroundcolor cyan "-------------------------------"
 
 
"{0, -22} {1, 5}" -f "Total connections...", $count
"`r`n"
 
write-host -foregroundcolor cyan "Total Unique Users/Clients"
write-host -foregroundcolor cyan "-------------------------------"
"{0, -22} {1, 5}" -f "Users...............", $userHash.count
"{0, -22} {1, 5}" -f "Client Versions.....", $clientHash.count
write-host -foregroundcolor cyan "-------------------------------"
"`r`n"

write-host -foregroundcolor cyan "Connected Users List"

foreach ($key in $userHash.keys) {
   $value = $userHash.$key
 
   "{0, -22} {1, 5}" -f $key, $value
}

write-host -foregroundcolor cyan "-------------------------------"
"`r`n"
 
Write-Host -ForegroundColor Green "Query complete`r`n"

Comments (9)

  1. Thanks, verry helpful Script

  2. Qbic808 says:

    Hi Mahmoud, I’m a little confused with the line $overallrecords = $overallrecords + $data. When I run the script it completes but errors along the way with ‘Method invocation failed because [System.Data.DataRow] doesn’t contain a method named ‘op_Addition’.
    It does this I believe because you haven’t previously defined what $overallrecords is prior to using the line $overallrecords = $overallrecords + $data. Am I missing something here? Regards, Nick

  3. Anonymous says:

    Thaks Mahmoud Badran! This script works great.
    My rate is * * * * * * * * * * (10 stars)

  4. Mark says:

    Hi there, Thanks for this script. Does this script include users that are connected to both the frontend servers and the edge servers? If not, is there a way of running this script on the edge server? If so, are there certain requirements to do so? Thanks,
    Mark

  5. Anonymous says:

    Pingback from If your looking to ramp on Lync On Premises here are some useful Lync resources well worth investigating

  6. Joe says:

    anyway to add the department that these users reside in or does this only pull CSUser data and not ADUser information?

  7. Thank your for useful script!

  8. james says:

    What I need is for a script to tell me the computer name or IP of the client. Does not look like this script will do that

  9. Jason says:

    The script runs fine on one pool, but the second pool returns "no data returned by query" Pools are identical. Any idea why the second pool returns no data?

Skip to main content