Tuesday, January 4, 2011

Lync Enterprise Voice Best Practices - Normalization

In my last post, I talked about the importance of using E.164 in your internal Active Directory phone list. Assuming you've got that all straightened out, what's next?  Since users won't always be dialing the wonderfully consistent numbers you've provided them in Active Directory, how do you handle all the different methods used for making calls?  You have to normalize them using normalization rules in Lync.

The end-goal for normalization rules is to ensure you pass a properly formatted E.164 phone number to the appropriate gateway, no matter what the user tries to enter. Call routing and additional number manipulation is much easier when you know you're going to be getting a standard format.

You need to think about the ways users typically dial their numbers. Are they used to excluding the 1 for local calls?  Do they dial 7-digit local numbers without the area code for their specific location?  Do they dial internal extensions?  What do they have to dial to make an international call?

You also have to think about how any PBX you might have in your environment sends numbers to Lync?  Is it capable of sending full E.164 formatted phone numbers, or can it only send extensions?

When you have all the answers to those questions, you can start building normalization rules. Normalization rules are built using regular expressions. If you're not familiar with regular expressions, a good place to learn about them is from regular-expressions.info. Thankfully, the Lync Control Panel has a wizard that handles most typical scenarios. You'll only need to understand regular expressions for more advanced needs.


Dial Plans
Normalization rules are assigned to dial plans in Lync. A dial plan is a collection of normalization rules that are assigned to sites, pools or users. You can even assign a dial plan to an individual gateway, which can be handy for inbound number normalization (as described by VOIPNorm here).  You can re-use the same normalization rules in multiple dial plans, so its best to name the rules so they're descriptive, like NorthAmerica-International, CA-ON-Toronto-Local or Italy-National.

Normalization Basics
Let's start with a very basic normalization rule that normalizes a North American 10-digit number to a properly formatted E.164 number:
^(\d{10})$  --> +1$1
A regular expression should start with a ^ which signifies the beginning of the string, and end with a $ which signifies the end. The \d represents a single number, but since its followed by 10 in curly brackets, it means 10 numbers. A matched number within the round brackets is accessible as a variable: $1.  If you have more than one set of brackets, then each bracket set is represented by $1, $2$3 etc.  You don't have to do anything special to make sure things like dashes, brackets and periods are excluded from the regular expression.  Lync handles that internally.

The right side of the arrow shows the normalized form. Start with +1 and insert the digits represented by the variable $1.  The normalized form does not follow regular expression rules (for instance, to represent a + sign, you'd normally have to precede it with a backslash \).

So, if someone dials 4163334444, the rule ^(\d{10})$ is matched, since its a 10-digit number.  The normalization rule simply sticks a +1 in front, so we get the E.164 formatted number +14163334444.

Advanced Normalization
In my deployments, I've taken that rule and expanded it somewhat to catch a wide variety of scenarios. Have a look at this:
^1?([2-9]\d\d[2-9]\d{6})(\s*\S*)*$ --> +1$1
A bit more complicated, but I'll explain. Since some users will actually enter the 1 when typing a phone number, I want to make sure it falls under this rule, so the 1? is added to the front.  The ? means the preceding number can be either present or not for a match. The [2-9] means "match any single digit between 2-9".  Then there are two single digits, represented by \d\d. Together, this indicates the area code, which can be any number from 200-999. The [2-9]\d{6} represents the local number which is 7 digits long but has to start with 2-9.  The (\s*\S*)* simply means "anything".  This is handy for accepting phone numbers from users' Outlook contacts which could have some phone numbers with oddly formatted extensions at the end of the number, like "ext 443 or "x443". The expression will drop the extension from the number.

The end result is a nicely formatted E.164 phone number. If the user enters "14165551111" or "4165551111" or "4165551111 extension number 42" (from Outlook for instance), it will be normalized as +14165551111.

Incidentally, my post on Normalizing Outlook Contact Phone Numbers includes a very handy script that will clean up users' personal Outlook contacts and ensure that every number is formatted for E.164.

International Normalization
For international numbers, you want to ensure users have to dial their usual international routing code (like 00 or 011) to make sure they really want to dial an international number.  If you stick with pure E.164 dialling, you could dial internationally when you meant to dial locally.  If you were to try to dial a Vancouver number by dialing 6046901111, you wouldn't want it to be routed to Penang, Malaysia by accident (60 is Malaysia's country code, and 46 is the city code for Penang).  In this case, you want your users to dial 011 (or whatever) before they enter an international number.  This rule takes care of that:
^011(\d{7,})$ --> +$1
So, with the first rule described earlier, when a user dials 6046901111, the number is normalized to +16046901111.  If they meant to dial Penang, Malaysia, they'd have to dial 0116046901111, which would normalize to +6046901111.

7-Digit Normalization
If your users are used to dialing 7-digit numbers for local calls AND your 7-digit dialing area includes only a single area code, you can create a normalization rule that goes something like this:
^([2-9]\d{6})$ --> +1613$1
So, if a user dials 2224444, the number will be normalized to +16132224444.

The preceding example works great for smaller sites that can only do 7-digit local dialing to a single area code. However, there are numerous sites that allow 7-digit dialling that encompass multiple area codes, such as Kansas City, MO (816 and 913). Using Kansas City as an example, you can’t simply do a blanket 7-digit to 11-digit normalization for the entire area code, because you won’t know if the 7-digit number is supposed to be expanded to 816 or 913. For instance, if a user dials 204-1111, it should be normalized to +18162041111, but if they dial 205-1111 it should be normalized to +19132051111.

Once again, the Dialing Rule Optimizer gallops in for the rescue! A new option will create the necessary normalization rules for special cases such as Kansas City, MO, so that you can dial 7-digit numbers with confidence.
A very special thanks to Henry Creagh who brought the multi-area code 7-digit dialing issue to my attention and helped test the solution.

Internal Extensions
For internal extensions, things get a bit more interesting. Your users may expect to be able to dial internal extensions directly.  If all your company's internal extensions map directly and consistently to external phone numbers (DIDs), then you'll be laughing.  For example, if your 4-digit extensions that start with 7 all map to DIDs that are in the +14162227xxx range, then your rule will look like this:
^(7\d{3}) --> +1416222$1
If your internal extensions don't have a corresponding DID, then you'll need to do something like this (pretend the main office number is 1 (416) 222-1111):
^(5\d{3}) --> +14162221111;ext=$1
If this is your situation, your users assigned Lync phone numbers will have to be in the same format, of course.  You shouldn't use the user's 4-digit extension as their Lync number.  You should use +14162221111;ext=5000 (for example).

If you're unlucky, your internal extensions and corresponding DIDs might not have anything in common for you to develop a simple set of normalization rules. In that case, you're going to have to either go through the tedious process of developing a large number of normalization rules, or you'll need to tell your users they simply can't use extension dialing anymore. There might be a temporary uprising until they realize they don't need to memorize extensions any more because their frequently called contacts appear in Lync.

If you are routing calls to a PBX that only accepts extensions, it's best to first normalize the extensions to E.164 format (with the ;ext=) and then use a trunk translation rule to revert back to the extension format before sending to the PBX. I will talk about trunk translation rules in a later post.

As a momentary aside, I've been thinking about developing a program that accepts a CSV file with DIDs and corresponding extensions and outputs the Powershell commands to create the appropriate normalization rules. I imagine it would be very helpful in the previous paragraph's scenario. If you think something like that would be useful, please leave a comment in the Comments section.

Putting it all Together
Lastly, you'll need some normalization rules to accept emergency and other non-standard numbers like 411, 611 or 911 (which incidentally is routed automatically if you've defined Location Services properly). If you're not in North America, your rule will be different.
^([2-9]11)$ --> +$1
Once you've got your normalization rules defined, you can assign them to a dial plan.  Since Lync starts at the top of the normalization rule list and works its way down till it finds a match, its best to place your most used rules up top. If a phone number can be matched by more than one rule, put the more restrictive rule first. Your final normalization rules for a simple dial plan might look like this:
NamePatternTranslation
NA-National^1?([2-9]\d\d[2-9]\d{6})(\D+\d+)?$+1$1
NA-International^011(\d{7,})$+$1
7xxx Extensions^(7\d{3})+1416222$1
5xxx Extensions^(5\d{3})+14162221111;ext=$1
NA-ServiceCodes^([2-9]11)$+$1
 
Since everything is normalized to a unique and standardized E.164 phone number, its much easier to modify at the gateway level to comply with local PSTN or PBX requirements. This is accomplished with trunk translation rules, which I will talk about in a later post. 

One last thing to remember is that any number that starts with a + sign is assumed to be already formatted for E.164, and no normalization rules will apply.  It will be dialled as is.  Keep this in mind when formatting phone numbers in Active Directory.

Now that you've got normalization sorted out, its time to handle routing.  My next post will discuss what I think is the best way to route your calls in Lync.

If you've got questions or issues about my methods, please drop me a line in the Comments section.

78 comments:

  1. Ken,

    We have internal extensions that are in the 64xx range. These numbers are in a remote site with the following number pattern - 818922. we have the e.164 formatted numbers in AD i.e. +181892264xx. When we dial the 4 digit ext. or the 9181892264xx from the dial pad in the Lync client they work. However when we use Click to Call we get a recording. I see from your post these are pretty easy and i followed your example for internal ext. (6\d{3}) --> +1818922$1
    Is this an issue on the Cisco CallManager or how the normalization rules are configured. Appreciate any input you can provide to assist with this issue. Thanks, Patrick(pharris@rsui.com)

    ReplyDelete
  2. From your post, it looks like CCM requires a 9 in front of the number when dialing full numbers, but not when dialing 4-digit extensions. Since the 9 isn't included in your AD phone numbers (and shouldn't be), you probably have to create a trunk translation rule to either add the 9 or strip the number down to 4 digits before sending to CCM . See my post on routing best practices for more info.

    ReplyDelete
  3. Hi Ken,

    Good to see your post it is much help full. I am trying to implement the Lync in my environment.No users are having a DID every users have their own analog phones with their 3 digit extensions. We have 6 PSTN lines in which 3 are for international and mobile calls and 3 of them are only for internal land lines. when users press 9 they get any free PSTN line. How do i do this in lync with the normalization rule. another requirement is that when some one calls from analog phone to other user by dialing extensions their analog phone and lync soft phone should both ring together. How do i do this. From your post i understand that the analog phones extensions should remain same and give the other extension numbers to lync as well.

    ReplyDelete
  4. Wow, a bit much to answer in a blog comment, but here goes....
    Your normalization rules should ALWAYS normalize to E.164 format (ie. no 9 in front). You add the 9 in a trunk translation rule (see my later posts for more on that).

    To make your analog and Lync phones ring at the same time involves more detail that I can provide here. Your best bet would be to contact a Lync consulting company in your area to help you out. If you're in North America, the company I work for can definitely help out.

    ReplyDelete
  5. Ken,
    Thanks for the great information you've been posting on your blog -- it's very helpful.

    I do have a question regarding normalization rules: we have successfully configured them for our enterprise voice users, and they apply properly when calling out from the Lync client. However, they don't seem to apply when a Guest joins a conference through the web app. For instance, we have a rule that will add a 9 in front of a 7 digit number. That rule does not get applied to guests, so they can't have the conference call out to them. If they enter 9+7 digits, the call will go out, so we can confirm that outdialing in general does work.

    Any thoughts on what we need to do to enable our existing normalization rules to apply to conference guests?

    Thanks again for the great information,
    Kenneth

    ReplyDelete
  6. Hi Kenneth,
    For some reason, your question didn't appear here for quite some time. Hopefully, you're still monitoring this post for activity.

    It sounds like you've done your normalization improperly. You shouldn't be adding a 9 to your phone numbers in normalization rules. You should only be adding it as a trunk translation rule. Can you confirm where you're adding the 9? If you're adding it in the right place, then it could very well be a bug. Please write back and let me know.

    Ken

    ReplyDelete
  7. Hi Ken,

    I have been trying to create a rule (for UK numbers)that normalises a number like:
    +44 (0) 1234 56789 and converts it to +44123456789.
    I think my problem is the original number has a "+" which then causes Lync to think it is properly formatted.
    Can you help?

    ReplyDelete
  8. Try this:
    ^\+?440(\d{9})$ --> +44$1

    Should work for numbers that either start with a plus or not.

    Ken

    ReplyDelete
  9. Thanks Ken but when I try to add that in I get:The builder does not support advanced regular expressions. To start using the builder, click Reset. To modify the regular expression manually, click Edit.
    Am I supposed to add this some other way?

    ReplyDelete
  10. Yes, you want to manually modify the regular expression. Click Edit and enter the pattern as ^\+?440(\d{9})$ and the translation rule as +44$1

    ReplyDelete
  11. Hi Ken,i really appreciate your time and effort on this but I'm still getting the same error.
    Can I check the exact steps?
    Lync CP
    Voice Routing
    Dial Plan
    Double Click Dial Plan and under "Associated Normalization Rules) click new
    Enter a name and then click edit?????

    ReplyDelete
  12. That's exactly right. Still having issues? Are you available for federation? Want me to have a quick look? Contact me via Lync at klasko at buchanan.com

    ReplyDelete
  13. Hi Ken, I've added you to my lync.
    Cheers Roy

    ReplyDelete
  14. There seems to be a discrepency in your section on "Putting it all Together":
    You have Service Codes as
    ^([3-9]11)$ --> +$1
    while just below that it is
    NA-ServiceCodes ^([2-9]11)$ $1

    ReplyDelete
  15. Hi Ken, really nice post. I wish I could pay back for I really gained a lot.

    My environment is a merged topology (Lync and OCS 2K7 R2). All normalization rules were migrated into Lync. All users have a 4-digit extension number (which is in AD Telephone field).

    Lync client is unable to display these numbers but normalizes them when typed. Any clue on how to get Lync to display 4-digits call manager extension number in AD?

    ReplyDelete
  16. Hey MS,
    When you type a 4-digit number into Lync, the normalization rules you define in Lync determine how its presented. For the numbers in AD to show in contacts, you need to use the Company_Phone_Number_Normalization_Rules.txt file. See this excellent post by Jeff Schertz for how to use it: http://blog.schertz.name/2010/09/lync-2010-address-book-normalization/

    Ken

    ReplyDelete
  17. Hey Ken,

    Thank you for the amazing info. I just have one question.

    For the normalization rules, there is nothing for local numbers. Im in Burlington, Ontario. so when i call a local Burlington 905 or hamilton 289 it adds the 1 to it as if it was long distance. when i create a voice routing test case to test i enter the local 9055555555 number and it normalizes to +19055555555 with the PSTN and Route as ON-Hamilton-National.

    Any reason why? you can email or Lync me at tim at thunder.ca

    ReplyDelete
  18. Hey Tim,
    The normalization rules should always normalize to the full E.164 format of +1xxxxxxxxxx. Since you need to drop the 1 for local calls, you need trunk translation rules. Trunk translation rules are applied just before they leave the mediation server. Users never see this translation, and sadly, it doesn't show in the test case (it really should though).

    If you haven't done this already, use the Dialing Rule Optimizer (http://lync.buchanan.com/LyncOptimizer) to create all the necessary rules for your particular area. It will make sure everything is normalized to E.164, and will drop the 1 for 905 local calls to Hamilton or Mississauga, but keep the 1 for calls to Oshawa (for example).

    I'll try to hit you up tomorrow on Lync!

    Ken

    ReplyDelete
  19. ** I have been trying to create a rule (for UK numbers)that normalises a number like:
    +44 (0) 1234 56789 and converts it to +44123456789. **

    For many reasons why that (0) should never be included in an international number see: http://www.aa-asterisk.org.uk/index.php/(0) and http://revk.www.me.uk/2009/09/it-is-not-44-0207-123-4567.html


    ** Try this: **
    ^\+?440(\d{9})$ --> +44$1

    The above pattern misses the spaces and parentheses.

    Try this:

    ^\+?44\ ?\(?0?\)?\ ?(\d{9,10})$ --> +44$1
    OR
    ^\+?44[()\ 0]*(\d{9,10})$ --> +44$1
    OR
    ^\+?44[^1-9]*(\d{9,10})$ --> +44$1

    It also allows for both 9 and 10 digit numbers.

    ReplyDelete
  20. How about normalizing for dial in conferencing only to CUCM 8.5? Seems sending the leading + is failing. I cannot seem to get this stripped on calls to web app

    ReplyDelete
  21. Hi Anonymous,
    Use a trunk translation rule to strip the +. See the Trunk Translation section at http://ucken.blogspot.com/2011/01/enterprise-voice-best-practices-in-lync_21.html

    Ken

    ReplyDelete
  22. Hai Ken,

    wanna ask about PIN on PABX.

    if i would like to translate the number +6287775908286 with PIN like 123456 after it and "0" for calling to outsite. should it be like this ?

    ^\+?062(\d{11})$ --> +062$1
    this is how i put 0 in front of the number but i dont know what should i do to add PIN after the number. would u like to help me ?

    Thanks anyway.

    ReplyDelete
    Replies
    1. Is the PIN something the user has to enter to be able to dial long distance or something? I would argue that you don't need such a thing, because every user who makes a call is authenticated, so you can assign voice policies to them that prevents them from making long distance calls.

      Ken

      Delete
  23. Ken: Is it possible to give a user a DID and an extension? We are transitioning a client from their traditional PBX to Lync and they are accustomed to dialing a 3-digit extension for easy access to internal staff but also have a DID assigned on their phone

    How can we make this happen in Lync. Your thoughts appreciated!

    ReplyDelete
    Replies
    1. Hey JuMz,
      Sorry it took so long to reply, but I was on vacation for the past 2 weeks. Yes, you can definitely give a user a DID and extension, assuming their extension matches up somehow to their DID. For example, if a user's DID is +15554442345 and their extension is 345, then its easy to create a translation rule that translates 345 to their DID. This assumes that everyone falls under the same DID range (ie 3xx translates directly to +155544423xx). You would create a normalization rule that would prepend +15554442 to 345.

      Like this: ^3\d(2)$ --> +15554442$1

      If there isn't an easy link between the DID and extension (ie +15552223333 maps to 987), then your job is more difficult. You'd have to create normalization rules for every instance, which can be very time-consuming.

      Ken

      Delete
    2. Thanks for the reply Ken. Our scenario is the latter (ie +15552223333 maps to 987). Could you give an example of what the normalization rule would look like for this? I can then use this as a template for the other DID to Extension mappings. Thank you for your feedback!

      Delete
    3. Your normrule would look like this:
      ^987$ --> +15552223333

      Delete
  24. Ken, since you mentioned Kansas City maybe you can answer something that I'm currently working on. The specific problem occurs when I attempt to dial a (913) area code number from a Lync Client. What happens is that the client removes the 9, so a number that is say 913-555-555 normalizes to +135555555. When testing from the Lync Server "Dial number to test" everything normalizes just fine: +919135555555 I suspect this has something to do with the fact that the Lync client is interpreting the first 2 digits of the area code as the outside line number + long distance number, but haven’t figured out how to correct it.

    Since we pass our calls off to another IP/PBX over a SIP trunk we essentially only have 2 rules, one for internal extensions and one for 10 digit dialing. Everything works great on the OCS/Communicator side of the house with the same rules.

    If you have any suggestions I’d love to hear them. Thanks for all the great information that you provide in your blogs, I’ve found them incredibly useful.

    ReplyDelete
    Replies
    1. Hey Brent,
      It looks like you're trying to incorporate the 9 into your normalization and routing rules. That's not the way to do it. You should always normalize to E.164 (ie +19135551111), and use trunk translation rules to add the 9 before sending it to your PBX. To allow your users to dial 9 for calls, follow the instructions in my post on internal extension dialing (http://ucken.blogspot.ca/2011/03/internal-extension-dialing-in-lync.html). Also, consider deleting all your existing rules (after backing them up of course) and use the Lync Dialing Rule Optimizer to create your rules for you. It will even make sure 9 is accounted for where necessary.

      Ken

      Delete
    2. You're exactly correct! Working fine now. Thanks for your help.

      Delete
    3. I get what you are saying, but where would I specify the trunk translation rule to add the 9 if I don't do it in my translation rules? On the Mediation server? Keep in mind that I'm still using a legacy OCS Mediation server at the moment.

      Delete
    4. Hey Brent,
      I didn't realize you're still using an OCS mediation server. OCS doesn't have an equivalent setting for trunk translation rules. Your best bet, if possible, is to have the PBX add the 9. Failing that, I would expedite your switchover to the Lync mediation server.

      Ken

      Delete
  25. Hi Ken - thanks as always for the great info. I have a similar issue to one of the previous posters, where clicking to call from a voice mail or the conversation history list does not seem to process through the normalization rule, and calls that should be translated without the 1 for our local calling area end up dialing with the 1. If we enter the same number in the Lync client manually, it translates properly.

    The full pattern I am matching is a bit long :), but here it is:

    ^\D?9?1?604((217|226|28[6,7,9]|30[0,2,8,9]|381|425|504|55[6,7]|607|61[3,4,5]|62[1,4,5,6,7]|74[3,4,6]|75[1,2,5,6,8]|772|786|80[4,7]|814|82[0,5,6]|83[2,5]|85[0-7,9]|86[4,6]|870|897|996)\d{4})$

    This all translates to +604$1

    For example, +1 (604) 855-5555 translates to +6048555555 if you type it in that way in the Lync client, but when you click to call from conversation history or a VM, it apparently still dials the 1 (we get a message back from Telus saying "the number you have dialed is in your local calling area, and you do not need to dial 1").

    Any ideas?

    ReplyDelete
    Replies
    1. Hi JP,
      To make everything work smoothly, you should be normalizing all numbers to E.164 (ie +16045552222) and strip the +1 via trunk translation rules. If you normalize to +6048555555, you've actually normalized it to a number in Penang, Malaysia. If you don't mind me asking, where did you get the pattern for the 604 area code you're using?

      Ken

      Delete
    2. Hi Ken - I wrote the pattern based on information I found at this link:

      http://theucguy.wordpress.com/2010/09/30/ocs-lync-server-normalization-rules/

      ...and using information from this link to find out which station ID's were in our local calling area:

      http://www.localcallingguide.com/lca_prefix.php?npa=604&nxx=&x=&ocn=&region=&lata=&switch=&pastdays=0&nextdays=0

      I think I'm a bit confused as to what difference it makes doing that translation (stripping the 1) in the Trunk Configuration vs. the Dial Plan. It seems to me that I would simply be copying that pattern match over to the Trunk Configuration, but again, I can't wrap my head around why that would make a difference with regards to the issue we are experiencing (click to dial from the client not translating).

      Delete
    3. Hey JP,
      I gotta ask, how long did it take you to create the pattern? Did you know about my Lync Dialing Rule Optimizer? It does all that for you in seconds rather than hours.

      There are lots of reasons why you should strip the 1 at the trunk rather than the normalization stage. My post on E.164 formatting (http://ucken.blogspot.ca/2010/12/enterprise-voice-best-practices-in-lync.html) outlines that nicely. The way you're doing it, you're painting yourself into a corner. I assume you're storing your numbers in AD as +604855xxxx. What would happen if you put in a user or contact with a number in Penang, Malaysia (country code +60, area code 4)? It would fail to dial. Sure you could store the number in AD with 011 at the start, but then what happens if you create a new Lync site in another country? Users wouldn't be able to dial that number.

      Other side effects include the ones you describe with click-to-dial.

      If you stick with E.164 formatting, then it becomes very simple to manage. Read through all my posts on the subject, and hopefully it will become clear. And save yourself the heartache, and erase all your rules and just run the Lync Optimizer for your area. It will just work.

      Ken

      Delete
    4. Hi Ken - once I found those two sites and had the necessary info, it only took me a few minutes or so to actually type out the patterns. Of course, finding the info took a while!

      I ran through the dialing rule optimizer, and it gave me two txt files - one for the Audiocodes gateway and one for OCS/Lync, which I am presuming is to be used in Trunk Configuration.

      If I'm stripping the +1 in the Trunk Configuration, then aren't the Audiocodes patterns redundant, as the trunk configuration would never pass a number that matches the pattern at the gateway (I.E. it would already have stripped the 1)? The gateway would then just pass the number to the Telus line without translating anything.

      Conversely, if I use the provided Audiocodes patterns to strip the +1 at the gateway for the local station ID's, isn't the OCS pattern redundant?

      Is the idea to have it in both places in case the trunk configuration misses it somehow? If that's the case and the gateway config is the "sure thing" we're relying on (and I say that knowing there is really no such thing as a sure thing :)) then again, why bother with the trunk configuration rule anyway - why not just normalize to E.164 in the Lync dial plan, set up the trunk configuration to just pass the numbers as-is to the gateway, and do all the translation there?

      Delete
    5. JP,
      Run the Dialing Rule Optimizer and use Lync 2010 as the gateway type. Audiocodes/Dialogic is only used for non-Lync deployments (or for older OCS deployments, which this site was originally developed for). The Optimizer will create Powershell commands that you run against your deployment. It is designed to be run against a clean environment without existing norm rules/routes etc. Read the blog post associated with the Optimizer to get a clear understanding on what its doing.

      You should handle all your dialing rules in Lync if possible. Its much easier to update when changes occur, and I'm a firm believer in keeping everything in one place.

      Ken

      Delete
    6. Agreed (about keeping everything in one place where possible), that's why we were going the route we had been. I just hadn't realized there was any significant difference between normalization in the Dial Plan vs. the Trunk Configuration.

      Translating to clean E.164 from the Dial Plan makes sense in terms of the "portability" of the Dial Plan (which, though not an issue for us because we are one location with no intention of ever adding another office, really does seem to be the best practice). My only concern with putting the rules in the Trunk Configuration (and I think this is why we ended up doing it in the Dial Plan instead) is that there is no easy way to test the pattern match, etc. in the Trunk Config - I.E. there is no "Test" button like in Dial Plan rules, and the "Test Voice Routing" function doesn't appear to run the test number through anything in the Trunk Config.

      I realize, of course, that I can "create" the pattern match/translation in the Dial Plan, test it using the handy button, then remove it and re-create the same pattern match/translation in the Trunk Config, but that just seems a bit ass-backwards to me. It almost seems like Microsoft's intent is for us to do the reverse of what you suggest, and do all the translation in the Dial Plan, since that is the only place you can test your pattern matches/translations.

      Of course, just using the Dialing Rule Optimizer will create it for me, and in theory will all be solid and just work out of the box, but as masochistic as it may be, I actually like figuring this stuff out. This is the first project I've done in a while that I actually enjoyed! :)

      Bear in mind, of course, that as the sole in-house IT person for a semi-rural law firm, this is the one and only Lync deployment with which I am involved.

      In any event, thank you again, very much, for your hard work on the blog and the Dialing Rule Optimizer, and your willingness to provide feedback/responses to my often long-winded questions! This is one of my go-to resources for anything Lync-related.

      Delete
    7. Hey JP,
      The lack of testing for the trunk translation rules is an oversight that I've brought up to Microsoft on several occasions. I hope the next version will fix that. Even though you can make things mostly work for your users by not following the guidance for normalizing to E.164, you will come across issues like you're already experiencing, and also issues with federated partners trying to dial your published numbers.

      Glad you're having fun with Enterprise Voice. I don't know what it is, but I feel the same way. I rarely say that about anything computer-related.

      Ken

      Delete
  26. I would also note that click-to-call from a website DOES appear to translate correctly, as if I click the call button on my post above, it dials +6048555555.

    ReplyDelete
  27. I have been trying to create a rule (for Apple Iphone in pakistan numbers)that normalises a number like:
    +9203338202231 and converts it to 03338202231.
    I think my problem is the original number has a "+" which then causes Lync to think it is properly formatted.
    Can you help?

    ReplyDelete
    Replies
    1. If the incoming number already has a + then Lync will not apply any normalization to it. If the phone call is coming from a gateway or PBX, you should be able to strip the + there. If its coming directly from a SIP provider, then the only thing you can do is employ MSPL scripts to direct the call to where you want. See my post on the subject here: http://ucken.blogspot.ca/2012/02/re-routing-incoming-calls-to.html

      Ken

      Delete
  28. I have a normalization problem that I haven't been able to work out yet. Given enough time and espresso, I think I could, but perhaps you can help speed up the process!

    I want to stop users from dialing anything that starts with [2-9]11, (such as 411, 911, etc...) I've written a lovely announcement and normalization rule that uses ^([2-9]11)$ to normalize any 3 digit [2-9]11 to +[2-9]11, but that only works when they dial exactly 3 digits. Since services like 911 will pick up even if you dial 9112345, I want a normalization rule that says, no matter how many digits are dialed, if it starts with [2-9]11, drop all but the first 3 digits and append a + to the front. This way my announment message will pick up, and I can stop having the police drop by every other day. I've monkey'd around with this for a few hours with no luck. Any thoughts?

    ReplyDelete
    Replies
    1. Hey Everett,
      The key is to make sure that all numbers normalize to E.164 format, as I stress repeatedly. North American numbers should normalize to +1 and 10-digits. If you do so, then nobody can dial 9112345, because there won't be a matching normalization rule/route. The best they should be able to do is dial +19112224444, which won't route anywhere. If your provider allows 7-digit dialing, you should just make your life easier by using the Lync Dialing Rule Optimizer. The resulting ruleset won't allow any invalid numbers like 9112345 to be normalized or routable.

      Ken

      Delete
    2. Ken

      In a CUcilync environment (no EV), I am normalizing my phone numbers which are in AD in (XXX) XXX-XXXX format to E.164 format using the simple regex in normalization.txt file (\d{10})
      +1$1

      But Cisco is asking that they need numbers of contacts to be displayed in (XXX) XXX-XXXX basically as it is in AD. If we don't normalize lync will not display any numbers for the contacts, if we do then users will not be able to dial the numbers of contacts. How do I solve this?

      Delete
    3. Hey Raza,
      Sorry for the delay in responding. Just back from vacation. You should be able to normalize to just 10-digits using \d{10} --> $1. Your numbers will show up as a string of 10-digits, without the brackets you normally see. CuciLync should be able to work with that.

      Ken

      Delete
  29. I've used your blog on 3 occasions to write my own normalization patterns. Thank you very much for your efforts. I am one among many who appreciate your efforts.

    ReplyDelete
  30. Hi, could anyone advise me with normalization phone numbers with spaces? We have numbers in format "123 456 789" and I need the Lync client showing only the last 3 numbers. How can I do it? Thanks.

    ReplyDelete
    Replies
    1. Hey ChunKy,
      You don't need to worry about spaces in your normalization rules. If you want to normalize a 9-digit number to only show the last 3 numbers, try this rule:

      ^\d{6}(\d{3})$ --> $1

      Delete
  31. Hi! Please! Help me out with this one..I have issues with translating some swedish national numbers / mobile numbers from the AD. They are not showing up in the Lync contact card. Fails to normalize.
    They look like this: 08-5555 5555 and I want to translate this into —> +46855555555
    And mobile number: 0734-111 1111 translate them into —> +46701111111
    I suppose they fail due to the spaces… Can you assist me in getting this sorted out with correct translation/reg exp so it works out?
    Br
    Andreas

    ReplyDelete
    Replies
    1. Andreas,
      You don't need to worry about spaces. Lync will remove those for you. To normalize numbers from AD so they appear in contact cards, you need to use the Company_Phone_Number_Normalization_Rules.txt to turn AD numbers into E.164 format (Google/Bing it). For your first example, try this:

      ^08(\d{8})$
      +468$1

      For the second one:
      ^0734(\d{7})$
      +4670$1

      Hope this helps!
      Ken

      Delete
  32. Hi Ken,

    I have a problem regarding with normalization rules.We have numbers in format "+90(224) 4100035 x1001" in AD.
    BTW,I have non-DID numbers.
    My question is:
    something like this:+90(224) 4100035 x1001 and I want to translate this into —> +902244100035;ext=1001
    How can I do it?
    Thanks in advance for your help.

    ReplyDelete
  33. Ken,

    Is there a way to dial provider auth codes using Lync? When a user on our system dials out they are prompted for a department auth code that our accounting department uses for internal billing. On a phone attached to our PBX a user can dial the 4 digit code and then the call will be placed, but on Lync it doesn't seem to send out the DTMF until after a call is established, so IVR systems work fine and I can hear the key presses on a call between Lync and my mobile phone, but I can't get past the auth code when dialing a standard LD call. Any help you can provide would be greatly appreciated.

    ReplyDelete
    Replies
    1. Hey Austin,
      For your authcodes, does the user have to dial the authcode first, or after they dial the phone number?

      Ken

      Delete
    2. After, our standard LD phone call goes as follows:

      Dial 9 for outside line
      Enter number
      Call hits carrier who returns tone
      User enters 4 digit dept. based auth code
      Carrier connects call

      Delete
    3. Austin,
      What's probably happening is that your PBX isn't sending the SIP 200 OK signal to Lync until after the authcode is entered. So, without the 200 OK, Lync won't send any DTMF tones that you press. If you can get your PBX to send a 200 OK to Lync before the authcode entry, then this should work. Another long shot would be to see if you can get your PBX to disable early media (but I doubt that will work).

      Ken

      Delete
    4. That answers that. Thanks Ken.

      Delete
  34. Hi Ken,

    We have a legacy PBX and for external calls, we need to add 9. We've created the translation trunk rule to add 9 to external numbert (example: 9416xxxxxx) but it doesn't work. Not sure why we missed here. Do you have any idea? Please let me know if you need more info.

    Thanks,
    Tim

    ReplyDelete
    Replies
    1. Hi Tim,
      When you're adding the 9, are you stripping the 1 as well for 416 calls (assuming 416 is local)?

      Ken

      Delete
  35. Hi Ken,

    is it possible to block international calling for certain countries via Lync Dial Plan/Normalization rules?

    ReplyDelete
    Replies
    1. Hey Santosh,
      Sure is possible. I'm assuming you want to block everyone from dialing numbers in certain countries. Modify your international route to accomplish this. If your international route is currently this (which is what is set by the Optimizer):

      ^\+[2-9]\d{6,14}$

      Say you want to block calls to countries that have 44 or 33 as their country code. Then you just have to modify the international route to the following:

      ^\+(?!44|33)[2-9]\d{6,14}$

      Ta da! Calls to those countries will now be blocked for all.

      Ken

      Delete
  36. Hi Ken,

    I have still having trouble with some extensions that are different. Any help would be greatly appreciated as your article has already helped me alot.

    604xxxxxxx X-225
    (418) xxx-xxxx poste 2320
    (418) xxx-xxxx # 6484

    Thanks in advance,
    Doug

    ReplyDelete
    Replies
    1. Hey Doug,
      What exactly are you having trouble with? Are you needing a way to normalize those to E.164? If so, try this:

      ^(\d{10})\D+(\d*)$ --> $1;ext=$2

      Delete
  37. Hi Ken,

    I was just having trouble getting those numbers normalized so they would display properly in the Lync contact cards. I tried your rule and it appears to have normalized all the remaining numbers that I wasn't able to do on my own. Thanks very much for the help and quick response.

    Much Appreciated,
    Doug

    ReplyDelete
  38. Hi Kenan,

    Thanks for writing such great blogs.

    We are planing to use Lync Enterprise Solution in India.So Please suggest how i caode is +91.

    Thanks:
    Amit Sharma
    amitsharmakp@gmail.com

    ReplyDelete
  39. Hi
    Great blog,
    Did you create a program that is able to accepts a CSV file with DIDs and corresponding extensions and outputs the Powershell commands???

    Let me know
    Abdulp@hotmail.co.uk

    ReplyDelete
    Replies
    1. I've never gotten around to that. Life/work has just been too busy. Still on my list of things to do.

      Ken

      Delete
    2. Hi Ken,

      Thanks for this great post.

      i have Lync deployment where each user has DDI with Extension and extension is not part of DDI. for e.g user1 Line uri is tel:+442097653001;Ext=52111 and user2 Line uri is tel:+442097653002;Ext=52112.

      Lync users want to call other user by dialing extension 52111 and these are 300 odd users.

      do i have to create 300 normalization rule for this ? or can we create few NR to normalized all extensions?

      Note: DDIs are in 1 block like +442097653001 to +442097653300

      Thanks in advance.

      Delete
    3. Hi
      to make situation even worse, we are planning to integrate our Lync with our mobile operator, meaning that there are about 1000 users with random mobile numbers. These would need to have also extensions for internal calling (we have also old analog phones connected to Lync via gateways). For sure it is impossible to manage 1000 separate lines in multiple dial plans.
      The extension part would be unique within our domain, so would it be possible to write some MSPL or other code to lookup the normalized number using the extension as the search key?
      Any ideas greatly appreciated.

      Delete
  40. Hi Ken,

    Thanks for this great post.

    i have Lync deployment where each user has DDI with Extension and extension is not part of DDI. for e.g user1 Line uri is tel:+442097653001;Ext=52111 and user2 Line uri is tel:+442097653002;Ext=52112.

    Lync users want to call other user by dialing extension 52111 and these are 300 odd users.

    do i have to create 300 normalization rule for this ? or can we create few NR to normalized all extensions?

    Note: DDIs are in 1 block like +442097653001 to +442097653300

    Thanks in advance.

    ReplyDelete
  41. Hello Ken,

    I am searching a normalisation rule for the following number xxxx\xxxxx or xxxx/xxxxx
    (real number f.e.: 0681\98915194 )
    The problem is the backslash, slash.
    Do you have any idee how I can get this work?

    Thanks
    Regards Markus

    ReplyDelete
    Replies
    1. Lync doesn't seem to like backslashes in phone numbers. I haven't tried this, but you could try a norm rule like this: (\d{4})(\\|\/)(\d{5}) -> $1$3

      Ken

      Delete
    2. Thanks Ken,

      that is working ;-)
      But just a little fix that I have to do.
      Can I do instead of the "4" numbers at the beginning and the "5" numbers on the end, a "*" => So that it doesn't matter how long the number is?

      Thanks
      Regards Markus

      Delete
    3. Instead of a *, I would do a +. * means "0 or more numbers", where + means "1 or more numbers"

      Delete
    4. Hello Ken,

      I tried to set the "+" and the "*". Both are not working:

      (\d{*})(\\|\/)(\d{*}) --> $1$3

      Any idea?

      Thanks
      Regards Markus

      Delete
    5. Try this instead (no squiggly brackets)
      (\d+)(\\|\/)(\d+) --> $1$3

      Delete
  42. This comment has been removed by the author.

    ReplyDelete