Call Queues using hybrid or Cloud Connector Edition PSTN numbers

Call Queues provide a simple way to distribute calls between users in Office365, in a similar fashion to the historic Response Groups in Lync/Skype. When they were first introduced by Microsoft you could only assign them service numbers provided by Microsoft, which was ok unless you were unable to port the number to Office365.

Late in 2017 it was announced https://techcommunity.microsoft.com/t5/Skype-for-Business-Blog/Announcing-new-capabilities-in-Auto-Attendant-and-Call-Queue/ba-p/122962#M697 that it would be possible to access call queues (and Attendants) using SIP addresses, this opened up the opportunity for using on-premises numbers via CCE or Hybrid.

If you’re using directory synchronisation after creating your call queue you’ll receive a warning to tell you that the Active Directory object is missing and are provided with a powershell command to create it. Unfortunately, this powershell command is included in a Skype for Business management tools update so is of no use if you don’t have a Skype Hybrid environment, for example if you’re using Cloud Connector Edition (CCE) appliances you’re unlikely to have the correct powershell module.

The solution, originally highlighted but now removed in the post, is to create the object manually with a upn that matches the sip address and then assign the required attributes, this can be done using the following powershell for Call Queues:

$OU = “ou=,dc=,dc=”
$displayname = “Queue Name”
$lineuri = “tel:+123456789
$guid = [guid]::NewGuid()
$sipaddress = “sip:hg_xxxxxxxxxxxxxxxxxx@SIPDOMAIN.com
$name = “{” + $guid.Guid + “}”
$objurn = “urn:trustedonlineplatformapplication:11cd3e2e-fccb-42ad-ad00-878b93575e07”
$deploc = “sipfed.online.lync.com”
$cn = “CN=” + $name
$dn = $cn + “,” + $ou
$upn = $sipaddress.replace(“sip:”,””)
New-ADObject -type User -Path $ou -Name $name -DisplayName $displayname
Set-ADObject -Identity $dn -Add @{“msRTCSIP-ApplicationOptions”=256;”msRTCSIP-ArchivingEnabled”=0;”msRTCSIP-DeploymentLocator”=$deploc;”msRTCSIP-OptionFlags”=384;”msRTCSIP-OwnerUrn”=$objurn;”msRTCSIP-PrimaryUserAddress”=$sipaddress;”msRTCSIP-UserEnabled”=$TRUE;”UserPrincipalName”=$upn;”msRTCSIP-Line”=$lineuri}

The process is the same for auto attendants except you require the trusted application to be: “urn:trustedonlineplatformapplication:ce933385-9390-45d1-9512-c8d228074e07”

To route PSTN calls using CCE to a Call Queue requires rewriting the destination sent from the SBC to become the SIP address rather than the E.164 number as is usually expected. Upon making this change I discovered that the CCE mediation server was rejecting the call due to an unknown server error.

The solution suggested in the comments was to add ;ms-skip-rnl at the end of the translated address and sure enough this worked in my case too and inbound calls to the Call queue from the CCE succeeded,  further comments suggest that this isn’t always the case so it is worth lots of testing prior to production.

Migration from Lync hybrid to Skype for business online using own PSTN carrier

I’ve just completed a migration of a customer to Skype for Business Online, that’s right, Skype not Teams. The reason for this is that the customer wanted to retain their existing PSTN connectivity and currently it is only possible with Skype, using your own SIP is currently expected for Teams with a preview due at some point in 2018 but as yet no fixed date.

There are two real choices for PSTN connectivity with Skype for Business Online using your own carrier, maintain a hybrid deployment or use Cloud Connector Edition (CCE). In this case a Sonus Cloud Link appliance containing both a Sonus Session Border Controller (SBC) and CCE was deployed, in the future it will be used to provide SIP straight into Teams.

You might ask, why would they just not port/transfer their numbers over to Office 365 and use Microsoft as their carrier? This particular customer wanted to provide the capability of receiving PSTN calls to all their staff but realised that only a small minority would likely require the ability to make calls, to port all their numbers and use Microsoft as a carrier would require more calling plans than they would actually benefit from. Additionally, by using the CCE they are able to keep the voice traffic off their main internet connection to ensure the best call quality available to them.

Now that the approach and design is taken care of I just want to cover a few points encountered during the switch over.

Firstly, it’s worth noting that using CCE is only possible if there is no on-premises deployment, Microsoft reversed its decision to introduce support for that topology in 2017. Whilst configuring a user to use CCE for telephony Microsoft checks whether they’re a pure online user or part of a Lync/Skype hybrid deployment.

How does it determine this? And how can you check? Well you can use Skype for Business Online powershell to connect and check the attribute interpreteduser, for example:

Get-csonlineuser -identity user@domain.com | select interpreteduser

If the returned value is hybridOnPrem or hybridOnline then Office365 thinks there is a hybrid deployment. Now if there is no hybrid deployment as the users have successfully been migrated, the Lync/Skype deployment has been decommissioned and all relevant hostnames have been changed then how or why does it think there is still a hybrid deployment?

The answer is due to the existence of the msRTC* Active Directory attributes used by on-premises deployments, if a user is synchronised to Office365 with these attributes still populated then it will be automatically assumed a hybrid deployment exists and as the interpreteduser field is a system generated value it cannot be manually changed.

The solution is simple, remove all the msRTC* attributes and resync the user and wait, after Microsoft’s internal replication has taken place, which in my case seemed to be around 5-6hrs, rerunning the command returned a value of DirsyncedPureOnline and the user could be configured for CCE.

This could potentially be one of the reasons why it is suggested to keep the hybrid deployment if using your own carrier, however as not all customers want to maintain complex on-premises deployments I just want to reassure that it can be done.

Sonus Cloud Link – We failed to run publish-ccappliance

During the deployment of a slave CCE appliance when it came to the last step I received an error message: We failed to run Publish-CCAppliance.

failedtorun_1

failedtorun_2

I waited around 5 minutes and ran the step again and it completed successfully and the appliance started handling calls, I was unable to see what the Management service was doing or why the automated process wasn’t able to handle it but I’d thought I would share and reassure people that running it again worked.

Forwarding Cisco Call Manager Call to Skype for Business Cloud Connector fails

During a recent Sonus Cloud Link deployment integrating Skype for Business Online with Cisco Call Manager I ran into an issue with certain calls failing. As the customer were piloting the system we were not yet removing users existing Cisco extension but rather forwarding it to their Skype number.

If Cisco users called the Skype number directly it would work but if they called the forwarded extension it would fail, strange.

So first step was to look at the Sonus logs to see if I could spot anything, on the working call everything looked normal

ciscoforward_1

The only difference with the failing call was the addition of the Diversion header entry.

ciscoforward_2

Now I’d found a difference it was time to see if I could change the forwarded calls header to be the same as the working call. Since we were using the Skype Cloud Connector Edition  we couldn’t make any changes on the Skype side as they’d be lost following any update.

Luckily we were using a Sonus to route calls between the two, so I created a Message Manipulation Rule under Message Rule Tables

ciscoforward_3

I then created a header rule

ciscoforward_4

Which then had an action of Remove for the header name of Diversion, I didn’t add any conditional access expression.

ciscoforward_5

After creating the rule I added it as an Outbound Message Manipulation entry on the Skype CCE signalling group

ciscoforward_6

After which forwarded calls worked as expected. I’m not sure why the Skype CCE or Skype Cloud PBX did not like the diversion header but the customer was happy with the result.

Sonus Cloud Link – Powershell module is not ready

Having just completed my first highly available Sonus Cloud Link I just thought I would mention an error message I came across when installing the second appliance.

The Sonus Deployer tool showed a very nice red error message saying the Powershell module is not ready

powershellnotready_1

This was also shown in the underlying PowerShell window

powershellnotready_2

I had seen a similar message during the installation of the Skype Online Powershell module when you try to load it without having restarted, however the ASM server had been rebooted and I was able to load Skype for Business Online PowerShell module and connect to the tenant.

If you read all of the notices and guides you will see mention that the length of time it takes to deploy the second appliance is dependent on the connectivity and speed of the first, which led me to check the first appliance.

I then discovered that the Primary appliance actually had been configured as standalone! It was then a case of redeploying the CCE configuration, this time ensuring the HA Master option remained selected and then afterwards the second appliance was able to progress.

Lesson of this story, ensure you get the configuration correct on the Master appliance and make sure it is saved!

Skype for Business Addressbook Normalization

The use of regular expressions for dialling and address book normalization have been long been established in the Microsoft Communications product line, but they are not always the easiest rules to construct and then test, especially when doing more advanced manipulation.

Lync 2010 introduced the dialling rule builder in the Control Panel which would construct basic regex rules for you as well as provide a method for testing them (along with the respective powershell commandlets), but the testing of address book normalization has always relied on using Abserver.exe with the -testPhoneNorm switch. Unfortunately, as pointed out by Greig (https://greiginsydney.com/vale-company_phone_number_normalization_rules/) this has been removed in Skype for Business Server 2015  however as he points out there doesn’t seem to be any test-cs commandlet to actually test these rules unlike for voice routing.

Additionally, as blogged by Ken Lesko (http://ucken.blogspot.co.uk/2015/05/skype4b-address-book-normalization.html) the address book normalization rules are now created via powershell rather than saved in the old Company_Phone_Number_Normalization_Rules.txt

So, how do we test these apart from watching the event log and seeing which numbers do not normalize correctly?

Well, I’ve prepared a sample powershell script that will compare a number against all of the normalization rules to see if there is a match, and if there is it will output those details whilst also attempting to apply the transformation so you can see the final normalized number.

Now I’ve only tested this rule against a few simple normalization rules so will be interested in hearing how it works against more complicated rules or if you can refine it but hopefully it provides a little direction on how it could be done.


import-module SkypeForBusiness
$normrules=Get-CsAddressBookNormalizationRule
Write-host "Enter telephone number to check"
$input = read-host
foreach ($rule in $normrules)
{
$testregex=$rule.Pattern
$test = [regex]"$testregex"
if ($test.Match($input).Success -eq "true")
{
$normalizednumber = $input -replace $rule.Pattern,$rule.Translation
write-host ""
Write-host "Priority: "$rule.Priority
Write-host "Name: "$rule.Name
Write-host "Description: "$rule.Description
Write-host "Pattern: "$rule.Pattern
Write-host "Translation: "$rule.Translation
Write-host "Normalized number: " $normalizednumber
}
}