At my employer, the standard taxonomy dictates that a users phone number in Active Directory is in the e.164 format. This makes sense as it is an international telephony standard. If we format all of our user’s phone numbers correctly in AD then it follows that it will be correctly formatted for any future telephony applications or services.
The problem is that the Lync Address Book Service doesn’t handle some of the possible ways of formatting an e.164 address even if the core Lync services do. The Address Book Service will only carry numbers forward if they do not contain a (perfectly legal) extension. In other words, this phone number is permissible: +1 123 456 7890 but this one is not: +1 123 456 7890;ext=1234. Neither of these is in violation of the e.164 standard.
So how do we know which numbering formats are deemed OK by the Address Book Service and which ones are not? We simply ask the Address Book Service to tell us. This is done by running the abserver.exe program with the -dumprules flag.
The abserver.exe file is found in the following directory: Microsoft Lync Server 2010ServerCore. To run it, open a command prompt (not PowerShell) and simply type: abserver.exe -DumpRules. After running this command, you will see the following:
# E164 Phone Number normalization (E164 keyword for regular expression matches up to 14 digits into $1, stripping out any separator characters (space, period, dash, left paren and right paren)
# The result for this rule is ignored and must be null. The actual result if this rule matches is tel:+digits-that-matched
# +dd dddd… Xddddd
# +dd dddd…
Let’s skip the preamble and jump down to the INTERNATIONAL section. They kindly give us a sample format (+dd dddd… Xddddd) followed by the regular expression which will analyze the number passed to it from Active Directory. Should there be a match between the number from AD and the Regular Expression, the Address Book Service will then store the now-normalized number ($1;=ext$2).
There is something really interesting here. In the expression provided by Microsoft, they make the assumption that all phone numbers with an extension in AD will look something like this: +1 123 456 7890 X1234. And if it sees a number like that, it will update the users Lync contact card with the following number: +1123456789;ext=1234.
The positive thing to note here is that the Microsoft-supplied regular expression does not provide a way for removing the spaces. Fortunately, whitespace (and other non-digit characters) get removed before the normalization gets applied. The one exception is that the ‘+’ character does not get stripped.
Looking at the normalized number returned from Microsoft, note that they are replacing the ‘X” from the initial number with the e.164 specified ‘;ext=’ nomenclature.
So other than looking at your Lync contact card for every employee, how do you know if your phone numbers are being thrown away by the Address Book Service? You look for the poorly-named Invalid_AD_Phone_Numbers.txt file. Why is it poorly named? Because it will put perfectly valid AD phone numbers into that file too. Essentially, if your numbers in AD do not conform to one of the 2 formats seen via the abserver -dumprules command, then they get pumped into the text file for you to peruse at your leisure.
Should you not see an Invalid_AD_Phone_Numbers.txt file in your Lync implementation, try seeing this Microsoft article.
So…we have valid number in AD, the Address Book Service is finicky in what it likes, and our users are complaining of empty phone numbers in the Lync contact cards.
What to do?
Well, we could edit all of our AD phone numbers to match what Microsoft expects to see. But yeah….we don’t have the time for that.
Or we could add some new regular expressions for the Address Book Service which does the bizarre task of taking a properly formatted e.164 format, breaking it down, and building it back up as…..a properly formatted e.164 format.
Is it reasons like this why Microsoft recommends 8 CPU’s for your Lync front ends?
To add new rules to support our AD phone number taxonomy, we create a file called Company_Phone_Number_Normalization_Rules.txt. Details on how to do this can be found on Jeff Shertz’s blog.
In short, we added the following regular expression to this file and it solved our problems:
This is essentially the same thing that Microsoft provides (see above) except that instead of looking for just an upper or lower case ‘X’, we are looking for an upper or lower case ‘;ext=’.
So how do we test that the Address Book Service likes our additions? We ask it!
After adding the regular expression and saving the file, return to the abserver.exe command used above and enter the following: abserver.exe -TestPhoneNorm . For example, I now want to test to see if the following is a valid number: +1 123 456 7890;ext=1234. Typing the following in gives the result seen below:
abserver.exe -testPhoneNorm “+1 123 456 7890;ext=1234”
args: +1 123 456 7890;ext=1234
+1 123 456 7890;ext=1234 -> tel:+11234567890;ext=1234
Matching Rule in Company_Phone_Number_Normalization_Rules.txt on line 4
Though a bit terse, we see in the third line of output that the number is now valid due to a matching rule on line 4 of the Company_Phone_Number_Normalization_Rules.txt file. It then spits out that rule on the last line.
And there you have it – how to get e.164 numbers with extensions into Lync, a system that pretty much insists that everything is in e.164 format…most of the time.