In previous versions of Lync, normalizing phone numbers stored in user accounts in Active Directory involved using the Company_Phone_Number_Normalization_Rules.txt text file. This file contained normalization rules to take phone number attributes from users in Active Directory (which are typically written in a nice readable format) and make them E.164 compliant. This allowed the phone numbers to be populated in the user’s contact card as well as available for use when using the “Call Me At” feature when joining a conference.

Skype for Business Server 2015 made a great improvement on this feature. The text file is no longer needed. Instead, PowerShell cmdlets are now available to view, create, and modify these rules:

Get/Set/New-CsAddressBookNormalizationRule

When migrating from Lync to Skype for Business, it is possible to import the existing text file and create new rules using the Import-CsCompanyPhoneNormalizationRules cmdlet.

With this capability, I recently dove into trying to create a rule and getting it to work (and learned a few things).

First, when putting in the values for Pattern and Translation parameters, put them in single quotes. The TechNet article for the New-CsAddressbokNormalizationRule does explicitly state this but I missed it the first time reading the documentation. It does also specify that using double quotes will cause the command to fail, but I did not have this experience, which led to wondering why the rules were not working.

On to creating the rules. The phone number format from Active Directory I worked with is 1(555)123-4567.

First, I started with something a little too complicated:

New-CsAddressBookNormalizationRule -Parent Global -Name ADPhoneNumber -Pattern '(\d{1})[(](\d{3})[)](\d{3})[-](\d{4})' -Translation '+$1$2$3$4'

I wrote the regex to follow the exact pattern of numbers and special characters (parentheses and dashes). This can be seen by those characters enclosed in brackets:

[(]
[)]
[-]

The rest of the pattern is just how many numbers I am looking for each part of the phone number:

(\d{1}) – 1 digit

(\d{3}) – 3 digits

(\d{4}) – 4 digits

If you’ve never done normalization in Lync/Skype, each set of regex components enclosed in parentheses becomes a token to be used later. For example, in the pattern in the command above, (\d{1}) becomes $1 in the Translation parameter, (\d{3}) becomes $2, and so on.

After putting this rule in, running Update-CsAddressBook, and deleting my local address book, my phone numbers were still not normalizing when viewing my phone numbers in my Skype for Business Options menu. I decided to simplify and look for the number of characters in the string (including the dashes and parentheses) by changing by pattern to ‘(.{14})’. When using regex testers from websites, this matched the phone number string but the rule still did not work in Skype.

Finally, I came across Jeff Schertz’s Lync 2010 Address Book Normalization article, which is still relevant for Skype. In the article he is using the text file for his entries but the patterns and translation rules are still the same when creating the rules in PowerShell. In fact, his example phone number to normalize is very similar to mine. Towards the bottom of the article, he states that we do not need regex code to ignore the special characters and spaces in the string. Lync and Skype does this automatically.

This simplified my pattern to match to ‘(\d{11})’ and my translation to ‘+$1’. This pattern is looking for an 11 digit string (automatically ignoring special characters and spaces), turn this into token $1, and placing a plus sign in the front to turn it into E.164 format. My phone numbers now appear in the client as normalized as well as available numbers when using “Call Me At” when joining meetings.

My advice is to be patient when testing these rules as you have to update the global address book first, then force update the client address book as well. If you don’t see immediate results, wait and try again. Also double check your syntax, parentheses, and single quotes when creating the rules. More than once I missed a closing parentheses or other small syntax error that resulted in some extra time troubleshooting and testing.