• WinNT (Local Users, SAM) Custom FIM Management Agent

    This ending week I encountered an interesting case where an organization has a large # of stand-alone servers (not joined to a domain controller). The number is 750++ servers and growing. The challenge was how to manage identity on the servers.

    Fast forward skipping the discussions why these servers are stand alone and not joined to an Active Directory forest.

    FIM as it stands provides brilliant support for Active Directory yet it doesn’t provide an out of the box support for WinNT account storage. A custom M/A was due. Code is attached to this post; hope it helps you in a similar situation. Some notes:

    • FIM extensible M/A APIs are pretty forward and don’t need schema handling and runtime resolution. Unlike similar architecture provided by WCF LOB SDK or BizTalk server.
    • WinNT LDAP is pretty simple few attributes for user and groups. Schema is not extendable so you can always use M/A safely.

    The M/A provides the following features:

    • Sync
      • User (CRUD Operations)
      • Group (CRUD Operations)
      • Password
        • Password Reset with FIM PCNS.

    How the code works:

    • The code provides 2 entry points one for Sync & one for password reset.
    • User & Group are represented by classes “factorized” by factory that takes care of creating a user based on CSEntry (FIM Class) or DirectoryEntery (WinNT class).
    • User  & Object classes implement an IidmObject interface which specifies the CRUD Operation in addition to state management needed for processing.

    In addition to the code, I have attached M/A metadata file and an export to ease the deployment operation on your end you can use FIM Management Agent Packaging utility to generate your own named M/A.

    For more information on how to create a custom M/A

    Creating Connected Data Source Extensions: http://msdn.microsoft.com/en-us/library/ms695383.aspx
    How to create Management Agents: http://msdn.microsoft.com/en-us/library/ms695385.aspx

    Questions & comments? The easiest way is find me on Twitter: @khnidk

    Khaled Hnidk

  • 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"

  • Denali CTP3 is here

    Did you download it ??... Not Yet...

    Go NOW and GET CTP3 from the below URL

    http://www.microsoft.com/sqlserver/en/us/default.aspx

     

  • Lync Internal Ports

    These Ports should be open from Client side to Server Side

    Required Server Ports (by Server Role)

    Server role

    Service name

    Port

    Protocol

    Notes

    Front End Servers

    Lync Server Front-End service

    5060

    TCP

    Optionally used by Standard Edition servers and Front End Servers for static routes to trusted services, such as remote call control servers.

    Front End Servers

    Front-End service

    5061

    TCP(TLS)

    Used by Standard Edition servers and Front End pools for all internal SIP communications between servers (MTLS), for SIP communications between Server and Client (TLS) and for SIP communications between Front End Servers and Mediation Servers (MTLS). Also used for communications with Monitoring Server.

    Front End Servers

    Front-End service

    444

    HTTPS

    Used for communication between the Focus (the Lync Server component that manages conference state) and the individual servers.

    Front End Servers

    Lync Server Front-End service

    135

    DCOM and remote procedure call (RPC)

    Used for DCOM based operations such as Moving Users, User Replicator Synchronization, and Address Book Synchronization.

    Front End Servers

    Lync Server IM Conferencing service

    5062

    TCP

    Used for incoming SIP requests for instant messaging (IM) conferencing.

    Front End Servers

    Lync Server Web Conferencing service

    8057

    TCP (TLS)

    Used to listen for Persistent Shared Object Model (PSOM) connections from client.

    Front End Servers

    Web Conferencing Compatibility Service

    8058

    TCP (TLS)

    Used to listen for Persistent Shared Object Model (PSOM) connections from the Live Meeting client and previous versions of Communicator.

    Front End Servers

    Lync Server Audio/Video Conferencing service

    5063

    TCP

    Used for incoming SIP requests for audio/video (A/V) conferencing.

    Front End Servers

    Lync Server Audio/Video Conferencing service

    57501-65335

    TCP/UDP

    Media port range used for video conferencing.

    Front End Servers

    Web Compatibility service

    80

    HTTP

    Used for communication from Front End Servers to the web farm FQDNs (the URLs used by IIS web components) when HTTPS is not used.

    Front End Servers

    Lync Server Web Compatibility service

    443

    HTTPS

    Used for communication from Front End Servers to the web farm FQDNs (the URLs used by IIS web components).

     

     

     

     

     

     

    Front End Servers

    Lync Server Conferencing Attendant service (dial-in conferencing)

    5064

    TCP

    Used for incoming SIP requests for dial-in conferencing.

    Front End Servers

    Lync Server Conferencing Attendant service (dial-in conferencing)

    5072

    TCP

    Used for incoming SIP requests for Microsoft Lync 2010 Attendant (dial in conferencing).

    Front End Servers that also run a Collocated Mediation Server

    Lync Server Mediation service

    5070

    TCP

    Used by the Mediation Server for incoming requests from the Front End Server to the Mediation Server.

    Front End Servers that also run a Collocated Mediation Server

    Lync Server Mediation service

    5067

    TCP (TLS)

    Used for incoming SIP requests from the PSTN gateway to the Mediation Server.

    Front End Servers that also run a Collocated Mediation Server

    Lync Server Mediation service

    5068

    TCP

    Used for incoming SIP requests from the PSTN gateway to the Mediation Server.

    Front End Servers that also run a Collocated Mediation Server

    Lync Server Mediation service

    5081

    TCP

    Used for outgoing SIP requests from the Mediation Server to the PSTN gateway.

    Front End Servers that also run a Collocated Mediation Server

    Lync Server Mediation service

    5082

    TCP (TLS)

    Used for outgoing SIP requests from the Mediation Server to the PSTN gateway.

    Front End Servers

    Lync Server Application Sharing service

    5065

    TCP

    Used for incoming SIP listening requests for application sharing.

    Front End Servers

    Lync Server Application Sharing service

    49152-65335

    TCP

    Media port range used for application sharing.

    Front End Servers

    Lync Server Conferencing Announcement service

    5073

    TCP

    Used for incoming SIP requests for the Lync Server Conferencing Announcement service (that is, for dial-in conferencing).

    Front End Servers

    Lync Server Call Park service

    5075

    TCP

    Used for incoming SIP requests for the Call Park application.

    Front End Servers

    Audio Test service

    5076

    TCP

    Used for incoming SIP requests for the Audio Test service.

    Front End Servers

    Not applicable

    5066

    TCP

    Used for outbound Enhanced 9-1-1 (E9-1-1) gateway.

    Front End Servers

    Lync Server Response Group service

    5071

    TCP

    Used for incoming SIP requests for the Response Group application.

     

     

     

     

     

    Front End Servers

    Lync Server Response Group service

    8404

    TCP (MTLS)

    Used for incoming SIP requests for the Response Group application.

    Front End Servers

    Lync Server Bandwidth Policy Service

    5080

    TCP

    Used for call admission control by the Bandwidth Policy service for A/V Edge TURN traffic.

    Front End Servers

    Lync Server Bandwidth Policy Service

    448

    TCP

    Used for call admission control by the Lync Server Bandwidth Policy Service.

    Front End Servers where the Central Management store resides

    CMS Replication service

    445

    TCP

    Used to push configuration data from the Central Management store to servers running Lync Server.

    All internal servers

    Various

    49152-57500

    TCP/UDP

    Media port range used for audio conferencing on all internal servers. Used by all servers that terminate audio: Front End Servers (for Lync Server Conferencing Attendant service, Lync Server Conferencing Announcement service, and Lync Server Audio/Video Conferencing service), and Mediation Server.

    Directors

    Lync Server Front-End service

    5060

    TCP

    Optionally used for static routes to trusted services, such as remote call control servers.

    Directors

    Lync Server Front-End service

    5061

    TCP

    Used for internal communications between servers and for client connections.

    Mediation Servers

    Lync Server Mediation service

    5070

    TCP

    Used by the Mediation Server for incoming requests from the Front End Server.

    Mediation Servers

    Lync Server Mediation service

    5067

    TCP (TLS)

    Used for incoming SIP requests from the PSTN gateway.

    Mediation Servers

    Lync Server Mediation service

    5068

    TCP

    Used for incoming SIP requests from the PSTN gateway.

    Mediation Servers

    Lync Server Mediation service

    5070

    TCP (MTLS)

    Used for SIP requests from the Front End Servers.

     

     

     

     

     

     

     

    These Ports should be open from Server side to Client Side

     Required Client Ports

    Component

    Port

    Protocol

    Notes

    Clients

    67/68

    DHCP

    Used by Lync Server 2010 to find the Registrar FQDN (that is, if DNS SRV fails and manual settings are not configured).

    Clients

    443

    TCP (TLS)

    Used for client-to-server SIP traffic for external user access.

    Clients

    443

    TCP (PSOM/TLS)

    Used for external user access to web conferencing sessions.

    Clients

    443

    TCP (STUN/MSTURN)

    Used for external user access to A/V sessions and media (TCP)

    Clients

    3478

    UDP (STUN/MSTURN)

    Used for external user access to A/V sessions and media (TCP)

    Clients

    5061

    TCP (MTLS)

    Used for client-to-server SIP traffic for external user access.

    Clients

    6891-6901

    TCP

    Used for file transfer between Lync 2010 clients and previous clients (clients of Microsoft Office Communications Server 2007 R2, Microsoft Office Communications Server 2007, and Live Communications Server 2005).

    Clients

    1024-65535 *

    TCP/UDP

    Audio port range (minimum of 20 ports required)

    Clients

    1024-65535 *

    TCP/UDP

    Video port range (minimum of 20 ports required).

    Clients

    1024-65535 *

    TCP

    Peer-to-peer file transfer (for conferencing file transfer, clients use PSOM).

    Clients

    1024-65535 *

    TCP

    Application sharing.

    Microsoft Lync 2010 Phone Edition for Aastra 6721ip common area phone Microsoft Lync 2010 Phone Edition for Aastra 6725ip desk phone

    Microsoft Lync 2010 Phone Edition for Polycom CX500 common area phone

    Microsoft Lync 2010 Phone Edition for Polycom CX600 desk phone

    67/68

    DHCP

    Used by the listed devices to find the Lync Server 2010 certificate, provisioning FQDN, and Registrar FQDN.

     

  • SIP Response Codes

    1xx—Informational Responses
    100 Trying
    180 Ringing
    181 Call Is Being Forwarded
    182 Queued
    183 Session Progress

    2xx—Successful Responses
    200 OK
    202 accepted: It Indicates that the request has been understood but actually can't be processed

    3xx—Redirection Responses
    300 Multiple Choices
    301 Moved Permanently
    302 Moved Temporarily
    305 Use Proxy
    380 Alternative Service


    4xx—Client Failure Responses
    400 Bad Request
    401 Unauthorized (Used only by registrars or user agents. Proxies should use proxy authorization 407)
    402 Payment Required (Reserved for future use)
    403 Forbidden
    404 Not Found (User not found)
    405 Method Not Allowed
    406 Not Acceptable
    407 Proxy Authentication Required
    408 Request Timeout (Couldn't find the user in time)
    409 Conflict
    410 Gone (The user existed once, but is not available here any more.)
    412 Conditional Request Failed
    413 Request Entity Too Large
    414 Request-URI Too Long
    415 Unsupported Media Type
    416 Unsupported URI Scheme
    417 Unknown Resource-Priority
    420 Bad Extension (Bad SIP Protocol Extension used, not understood by the server)
    421 Extension Required
    422 Session Interval Too Small
    423 Interval Too Brief
    424 Bad Location Information
    428 Use Identity Header
    429 Provide Referrer Identity
    433 Anonymity Disallowed
    436 Bad Identity-Info
    437 Unsupported Certificate
    438 Invalid Identity Header
    480 Temporarily Unavailable
    481 Call/Transaction Does Not Exist
    482 Loop Detected
    483 Too Many Hops
    484 Address Incomplete
    485 Ambiguous
    486 Busy Here
    487 Request Terminated
    488 Not Acceptable Here
    489 Bad Event
    491 Request Pending
    493 Undecipherable (Could not decrypt S/MIME body part)
    494 Security Agreement Required

    5xx—Server Failure Responses
    500 Server Internal Error
    501 Not Implemented: The SIP request method is not implemented here
    502 Bad Gateway
    503 Service Unavailable
    504 Server Time-out
    505 Version Not Supported: The server does not support this version of the SIP protocol
    513 Message Too Large
    580 Precondition Failure


    6xx—Global Failure Responses
    600 Busy Everywhere
    603 Decline
    604 Does Not Exist Anywhere
    606 Not Acceptable

    http://en.wikipedia.org/wiki/List_of_SIP_response_codes