Wednesday, July 22, 2015

Lync QoS Script

QoS has always been a hot discussion on the table when implementing Lync/SfB ... especially when you have voice traffic to deal with.

There are many great blogs out there that discuss the QoS settings and ports to use, and how to set them up; my favourite is this post by Jeff Schertz which inspired me to write this script.

This is a very simple scripts which I believe picks up where the above post left off; it will read the ports from the current environment, and create the GPO policies required for both servers and clients automatically (provided it has access to the AD environment).

Please run this script with administrative privileges, using a Domain Admin account.

Download
v.0.01 - 2015-03-16 - Create-QoS-Policy.v.0.01.zip
v.0.02 - 2017-01-31 - Create-QoS-Policy.v.0.02.zip


Monday, May 4, 2015

Lync Mirroring Status Disconnected

Ok, this is a very quick one that caught me by surprise. At one of our customers; changes to the Lync settings were not taking affect. Checking the replication status, I found that replication was down for over 10 days. Running "Get-CsManagementStoreReplicationStatus" I found ...

This immediately pointed me to the SQL servers. When I checked the servers, I found the primary server was completely down. The mirror server had taken over as the principle, but apparently, Lync wasn't talking to it :( ... Checking the mirroring status "Get-CsDatabaseMirrorState" confirmed this limbo state ...
Looking at the SQL Managment Studio on both servers; I found that both servers were showing the databases as "Principle"; while the failed server was showing "Principle, Disconnected / In Recovery"; the mirror server was showing "Principle, Disconnceted"

Solution

After a bit of research and asking around; I came to this article, which helped resolve the issue. I have summarized the steps below, so that it is easier for anyone searching for this in the future...
  1. Connect to Mirror DB server
  2. Click on "New Query..."
  3. type the command "alter endpoint mirroring_endpoint state=stopped"
  4. Press the button "Execute"
  5. Wait until the command completes, at this point you have disabled the replication between the servers.
  6. Execute the command "alter endpoint mirroring_endpoint state=started"
  7. This will re-start the mirroring process, and this time, the database server will see the primary server as up, and will start replicating back to it the information that it lost.

At this point you have two options, of either leaving the second SQL server as the principle, and the original one as the Mirror, or you can failover the Databses back to the original state. In both cases, Lync doesn't mind, and doesn't care.

Tuesday, April 28, 2015

Sonus SBC AD Lookup Gotchas

I have recently been troubleshooting issues with a Sonus SBC 1000 doing call routing using AD lookups.

There are many blogs out there about how to do this, including the guide from Sonus themselves which is pretty descent.

Let me however, go into some of the gotchas that caught me by surprise, and are not well documented on the Sonus site...

AD Cache Lookup

There is a very clear note saying that it is "recommended" to have a USB stick attached to the SBC if you are going to use the AD Lookup in cached mode.

What there is no mention of, is the way the Sonus SBC uses the cache, and how it gets updated. This information was provided to me from Sonus TAC/Engineering, and is current as of the date of publishing this blog post; this applies to having the AD Configuration in "Updates" mode...

  1. All domain controllers configured are treated equally; i.e. if any one of them responds back with a successful query, than the cache is valid, even if all the other queries fail.
  2. The cache is dropped before the new cache is read; thus if the AD query fails, the system is left with "NO CACHE" unless you have a USB stick with a backup cache to be used.
  3. if "ALL" domain controllers fail to respond, the SBC switches to online mode, and tries to query the domain controllers in order for the user in question.
  4. The system will not try any failed domain controllers again until the next update cycle as configured in the "Cache Settings"
they have said that they are working on improving the process...

Case Sensitive Lookup

Apparently the lookup is case-sensitive; while simply testing for "=msRTCSIP-Line=" in your transformation table may work most of the time, if a Lync administrator decides to type "Tel:+xxxxx" instead of "tel:+xxxx" the query will fail to return a positive match.

To overcome this issue the recommendation is to use "(?i)=msRTCSIP-Line=" which would make the lookup case-insensitive.

Of course you can use the same "(?i)" in other locations too for matching without case.

 Lookup Limits

Transformation table lookups on the SBC have a hard limit of 256 characters for the string being manipulated. This is a hard limit and as per the Engineering team, the registers were never meant to hold large strings of data (such as memberof fields.

This is a major draw-back if you do routing based on group memberships or on other fields which may exceed this hard limit.

Monday, August 18, 2014

Lync Edge Certificates

Are you getting problems starting your Edge service role ?

Is your Edge service going crazy about the certificate being not accessible ?
Do you get this dreaded error message from EventID: 14591
Event ID: 14591
Error 0xC3FC7D95 (LC_E_VALIDATION_CERT_NO_KEYEXCHANGE)
Cause: The certificate may have been deleted or may be invalid, or permissions are not set correctly.

Fear not, you are not alone, after banging my head against the wall for a few days, rebuilding the Edge server from scratch, and trying out a bunch of different certificate templates; I have finally found the solution...

Although Microsoft Windows is happy with many types of Crypto Providers; alas, Lync on the other hand, only likes the "Microsoft RSA SChannel Cryptographic Provider"

Next time you want to issue a certificate, make sure you choose the "Microsoft RSA SChannel Cryptographic Provider"

To make this more informative, I have added below the certificate template options that should be used for generating Lync certificates...

    • Don't select to publish to AD, as Lync Edge can not access the AD and is not authorized to do so:
      Template - General Tab
      • Choose the Purpose to be "Signature & Encryption" and allow "Private Key to be Exported"
      Template - Request Handling Tab
      • Choose only the "Microsoft RSA SChannel Cryptographic Provider"
      Template - CSP Selection
      • Choose the Application Policies to be "Server Authentication"
      Template - Extensions Tab
      • Choose the Key Usage to be "Allow key exchange only with key encryption"
      Template - Extensions Tab

      Wednesday, July 30, 2014

      Get-CSUserForwards

      I was asked recently to come up with the best way to figure out which users were forwarding their land-line to another number (e.g. mobile) or to another user.

      I came up with the idea of using SEFAUtil to figure out all the currently enabled users' setting.

      # Initialize Variables
      $AllUsers = @()
      $Count = 0
      
      # Define Location of SEFAUtil
      $SEFAUtil = "C:\Program Files\Microsoft Lync Server 2013\ResKit\SEFAUtil.exe"
      
      # Get Application Pool Server to use
      $LyncServer = Get-CsTrustedApplication | ?{$_.ApplicationId -eq "urn:application:sefautil"}|%{$_.TrustedApplicationPoolFqdn}
      
      # Get Lync EV Enabled Users
      $LyncUsers = Get-CsUser | where {$_.EnterpriseVoiceEnabled -eq $true}
      $TotalUsers = $LyncUsers.Count
      
      # Loop for each one and get details
      Foreach ($LyncUser in $LyncUsers){
          $Destination = $Null
          
          #Convert User SIP to lowercase
          $UserSIP = $LyncUser.SipAddress.ToLower().Replace("sip:","")
      
          #Write Progress
          $Count += 1
          Write-Progress -Activity "Processing Users" -status "User $UserSIP" `
              -percentComplete ($Count / $TotalUsers*100)
      
          #Do the magic
       &$SEFAUtil /Server:$LyncServer $UserSIP| Tee-Object -Variable output|Out-Null
      
          #Split the output to lines & convert to an object
          $parts = $output -split "`n"
      
          #Figure Out Destination  
        $Destination = ($parts[4] -split "to: ")[1]
       If ($Destination -eq "") {
          } ElseIf ($Destination -Match "user=phone") {
           # Destination is a number
        $Destination = $Destination.Split("@")[0].Split(":")[1]
       } Else {
        # Destination is a SIP address
              write-output $Destination
        #$Destination = $Destination.Split(":")[1]
       }
      
          #Display information
          $Data = New-Object -Type PSObject -Property @{
              SIP = ($parts[0] -split ": ")[1]
              Name = ($parts[1] -split ": ")[1]
              EVEnabled = ($parts[2] -split ": ")[1]
              SimRing = ($parts[3] -split ": ")[1]
              ForwardTo = $Destination
          }
          $AllUsers += $Data
      }
      

      Your feedback is always welcome.