Tuesday, January 3, 2012

Complete Guide to the Lync Optimizer

UPDATE (21-Aug-2013): Improved UI and additional control options for rule creation. See this post for more information.
UPDATE (09-Jan-2013): Least-cost and failover call routing is now built into the Optimizer.  See this post for information.
UPDATE (05-Dec-2012): Added true customized local dialing rules for the UK.  See this post for information.
UPDATE (31-May-2012): Significant optimizations to North American local rulesets, and fix of normalization rule bug affecting 7-digit dialing rules. See this post for more information.
UPDATE (16-Mar-2012): Now creates separate dialing rules for toll-free and premium calls. Makes it easier to limit dialing to some groups while granting additional dialing rights to others. 

UPDATE (29-Feb-2012): Will allow you to run multiple Optimizer output files against a site to provide localized dialing rules for international users.  See this post for more information.
UPDATE (17-Feb-2012): Program will now create separate dialing rules/usages for mobile networks in non-North American dial plans. Allows for administrators to easily control who is able to dial mobile numbers, which usually cost more than land-lines.

Introduction
Whenever I've added new features to the Lync Dialing Rule Optimizer, I've created a post outlining the new functionality.  This has led to information being scattered across several different posts and isn't readily available.  I figured it would be best to create a single, all-encompassing post that outlines how to get the most out of the Lync Optimizer.  It will be updated over time as new features are added.

The Lync Optimizer began its life in February 2009 as a locally run VBScript designed to create optimized dialing rules for Dialogic and Audiocodes gateways, as detailed in this post dug up from ancient times (2010).  Its primary purpose was to figure out what phone numbers were local and which were long distance for any given area.  People who knew me would email me the phone number they would want optimized and I would run the program and email the results.  The earliest known versions of this code are now archived in the Smithsonian for future historians.  It has since grown and evolved into the well-oiled Lync-centric online machine it is today.

There are tons of documentation available on how to setup Enterprise Voice in Lync Server 2010/2013, but reading through them all can be daunting and there is not very much guidance on the WHYs as much there is on the HOWs.  The Lync Dialing Rule Optimizer is designed to take care of 95% of the typical setup required to make Enterprise Voice work in Lync Server 2010/2013.  It takes advantage of the knowledge gained from multiple deployments from several Lync professionals on the best way to do things in Lync. All this knowledge is funnelled down into a simple set of options that outputs a Powershell script that takes care of almost all the work for you.

For some more background on Lync Enterprise Voice Best Practices, I encourage you to read through some of my posts on the subject:

Tested Scenarios
The Optimizer has been tested to work with the following topology combinations:
  • Single central site
  • Multiple central sites
  • Multiple central sites with multiple branch sites
  • Single central site with multiple mediation pools
  • Multiple central/branch sites with multiple mediation pools/PSTN gateways
Before You Start
Before you jump in and use the Optimizer, its best to make sure your Lync environment is up to speed.
  1. Make sure that all your user's phone numbers in Active Directory are in E.164 format, as described in my post on E.164 formatting.  
  2. Make sure you have a PSTN gateway defined in your Lync topology for each Lync site you wish to run the Optimizer.
  3. Don't mess around with any of the Enterprise Voice sections at this time.  It will just complicate your life.  If practical, delete any routes/usage/policies you've already defined.
  4. If you do have existing policies/routes etc. back them up by going to Action - Export Configuration under the Voice Routing section of the Lync Control Panel.
Using the Lync Optimizer
  1. Ensure the Lync site you wish to apply the rules have at least one PSTN gateway assigned to it.  If you don't, the script will not run.
  2. Go to http://www.LyncOptimizer.com.  
  3. Pick your country from the drop-down list.

  1. For North American (including Hawaii and Alaska) and Caribbean users, enter the area code and local exchange information for the Lync site you want to apply the script to.  For other countries, pick the city or area where your Lync server resides from the list provided.
North American Area Code Selection

International Area Code Selection (UK example)
  1. To use simplified call routing which uses only a single all-encompassing route for all calls, instead of the default local, national, international etc routing, select the Simple Ruleset checkbox. You'll notice the Rule example will update to show the effect on the ruleset. Keep in mind that least-cost routing is not possible in this configuration. 

  1. To force English language rulenames and descriptions for countries that would normally use the local language, select the Force English Rulenames checkbox. This option only appears on countries where the default language is other than English. Again, you'll see the effects on the Rule example line.

  1. The rule naming convention can be changed if desired.  The country abbreviation prefix and rule type suffix can't be modified to ensure least-cost routing calculations can function normally. Select the Change Rulename Base checkbox and type the new rulename base to use for all rules.
Toronto Rule Name Change Examples
  1. Some countries (Brazil for example) requires a carrier access code to be dialed when dialing long distance phone numbers.  If your country requires a carrier access code (Brazil is the only one in the Optimizer so far), you can enter it here.  The carrier access code will be added to the dialed number after the national/international access code and before the subscriber number.  For example, if you select 19 as the carrier access code, then long-distance numbers will be sent to the PSTN as 019xxxxxxxxx, instead of just 0xxxxxxxxxx.

  1. If you have to enter 9 (or some other digit) to get an outside line, enter it in the External Access # box. This should only apply to connections to an existing PBX.  Don't enter numbers you would normally have to use to make a call from outside the office (ie. 00).

  1. If you want your users to be able to enter an extension to reach someone, select the Use Extensions checkbox. When you select the checkbox, it will show an Edit Extensions button.  Clicking it will bring up the Extension Entry screen.


If none of your users are directly dialable (ie. have to go through a receptionist), then enter the full main phone number and the corresponding extension range.  In the above example, if a user dials 244, it will normalize to +14165551111;ext=244.  This assumes that you've assigned the phone number to the user in the format tel:+14165551111;ext=244.  If you entered it as just 244, this will not work.  See my post on Extensions for more information.

If your extension range maps to an external DID, select the DID checkbox and enter the prefix and extension start/end range.  This will create a normalization rule that will translate typed extensions to the full DID.  As in the above example, if a user dials 3055, the number will be normalized to +14165553055.  Again, this assumes you've assigned the phone number to the user in the format tel:+14165553055.  If you've used the extension only, this will not work.

You can enter up to 10 extension ranges here.  If you need more, please send me a note, and I will see about increasing the limit.  Make sure you press Submit when done, or else it won't save your work.
  1. If you are using a SIP trunk that accepts E.164 phone numbers, select the SIP Trunk Connection option.  If selected, the program will not create trunk translation rules.  All numbers will be sent to the next hop formated as E.164.  It will also set encryption on the trunk to Optional and will disable REFER support, as this is not supported by most SIP providers.  Note: Don't select both an external access number AND SIP trunk options.  The two options are mutually exclusive. 

  1. If you want Lync to block premium rate phone numbers (like 900 in North America) for all users, select the Block Premium Numbers checkbox.  The program will use the Announcement service to let the user know they can't dial those numbers.  This will apply to ALL users in the company, so don't use this option if you want to be more selective.  See the original post for more information.

  1. If you want to use the Call Park feature, select the Enable Call Park option.  When selected, you will be able to enter a range for the call park orbit.  The range must be 2-digits or longer and can include * or # at the beginning.  To ensure the call park orbit doesn't conflict with an existing normalization rule, the program will create a Call Park specific normalization rule to make sure those numbers are not normalized to something else.  Check out the Call Park Deployment Guide for more information on Call Park.

  1. If your North American local dialing area supports 7-digit dialing, select the 7-Digit Normalization checkbox.  If you're unsure if your local dialing area supports 7-digit dialing, leave this blank. Selecting this option when 7-digit dialing isn't available can lead to unpredictable results.  Doesn't apply to other countries other than North America.

  1. To receive updates should the ruleset change, enter your email address.  Only applies to North American users.
  2. After pressing Generate Rules, wait a minute for the rules to be generated.
  3. The program will generate a single .PS1 file.  Save this file onto your desktop.  
  4. Right-click the .PS1 file and click Properties.  Click the Unblock button to allow the script to be run.  Alternatively, run the Powershell command Set-ExecutionPolicy -ExecutionPolicy Unrestricted on your Lync server.

  1. Run the .PS1 file by typing .\Filename.ps1. For the above example, use .\Toronto-ON-416678-Lync.ps1. You will be prompted to select the site to apply the dialing rules.

  1. If there are multiple mediation pools or PSTN gateways in the specified site, the script will prompt you to select one.  
  2. If the Optimizer detects multiple Lync sites, it will ask if you want to apply least-cost/failover routing to the new voice policies.
  3. If the Optimizer detects the presence of Lync network sites, it will ask if you want to enable location-based routing at a site (Lync 2013 only).  See this post for more information.  You will also be prompted to select the network site to apply location-based routing, as well as which class of calls to allow users at that site.
  4. The script will then create all the necessary dial plans, routes, usages etc. to get you going.


After Running the Optimizer Script
  • If you have multiple mediation pools and/or PSTN gateways in the site, you can re-run the script and select the other gateway.  The script will add the gateway to the existing routes.  Calls using that route will round-robin between the gateways.
  • If you want least-cost/failover routing applied to all the sites where you've applied Optimizer-generated scripts, run each of the scripts again, ensuring you select the option to configure least-cost/failover routing.  It will update the voice policy to include the additional PSTN usages.  See this post for more information.
  • If you have users from different countries using a single Enterprise Voice deployment, run the Optimizer for each country and run the resulting script.  It will create user-level dial plans so those users can have localized dialing rules, as described in this post.


Verifying Settings
To verify the settings were applied properly, go to the Voice Routing section of the Lync Control Panel.

Dial Plan Settings
The script creates a site level dial plan for the site you selected in the script.  All users assigned to the Lync servers in that site will have this dial plan automatically applied to them.

Drilling down into the details of the dial plan shows the normalization rules applied to the dial plan.  You'll note the External access prefix has been set in this example.  For more information on what this does, see my post on internal extension dialing.

If you've setup localized dialing rules against a central Lync deployment, there will be user-level dial plans here.  This will allow people homed in different countries to use their local dialing rules, instead of the rules assigned to the central pool.  You will have to manually assign the dial plan to the appropriate users, or use a Powershell script.

The normalization rule for call park is highest in the list (if selected), followed by internal extensions (if selected), then national, international, service and in the specific case of Canada, 310 numbers.

Voice Policy Settings
The script then creates multiple voice policies.  Voice policies are used to assign calling features to groups of users.  A site-level policy is assigned to everyone by default and allows local, national and international calls. Three user-level policies allow varying degrees of calling rights.  The Local policy allows only local calls (excluding mobile phones in non-NA countries), the National policy allows local, mobile and national calling, and the International policy allows all calls, including premium rate calls.

NOTE: If you selected the Simple Ruleset option, then none of this applies, because only a single voice policy that allows all calls is assigned.

The calling rights assigned to each policy is summarized in the table below:

Calling Rights
PolicyLocalServiceNationalMobileToll-FreePremiumInternational
Site
X
X
X
X
X
X
User-Local
X
X
X
User-National
X
X
X
X
X
User-International
X
X
X
X
X
X
X

You can elect to change any policy to allow any combination of dialing abilities. You do this by editing the appropriate policy and adding or removing the appropriate PSTN usage records as shown below.  You can also change the calling features available to users.  You can always create new policies if the default ones don't match your needs.

Routes
Each route created are assigned to a PSTN gateway as selected at the beginning of script execution (if there are more than one choice).  If you have multiple PSTN gateways assigned to a mediation pool, you can run the Optimizer script multiple times, selecting a different PSTN gateway each time.  The script will add the gateway to each route.  With multiple PSTN gateways in a route, calls will round-robin between the gateways.

PSTN Usages
Usages are the links between voice policies and routes.  A usage can have multiple routes assigned to it, and can be assigned to multiple voice policies.  This provides a very flexible and easily modified structure for voice rules.  There are 5 usages for each site (6 for non-NA countries):  Local (if local dialing available in selected country), National, International, Mobile (for non-NA countries), Premium and Service.  Each usage has the appropriate routes assigned (ie. the Local usage has routes for local, internal and toll-free numbers). 

Trunk Configuration
The trunk configuration does final outgoing phone number manipulation before sending the call to the PSTN gateway.  Since all phone numbers are coming to the gateway in E.164 format, its simple to strip digits as required.  For instance, local calls strip the national prefix, international calls add the international prefix for the selected location, and so on.
If the SIP Connection option was selected in the Optimizer, there will be no modification of outbound phone numbers.  Everything will be sent to the SIP provider in E.164 format.  Also, REFER support will be turned off, and encryption will be set to Optional.  


Blocked Premium Numbers
If you selected the Block Premium Numbers option, the program will automatically setup the unassigned number range and relevant announcement for your country.  For more details on this feature see my post on blocking premium numbers in Lync.

Call Park
If you selected the Call Park option, the script will create the relevant call park orbit, and also a normalization rule to ensure the number range is never normalized to something else.


Next Steps
If you only have a single Lync site, then your work is pretty much done.  You can enable users for Enterprise Voice and things should work just fine (assuming your PSTN gateway connection is setup properly).

If you have multiple sites, and selected the option to apply least-cost/failover routing, ensure the ordering of the usages meets your requirements.  Change the order as required.

Conclusion
This should give you a good overview on what the Lync Dialing Rule Optimizer does.  As mentioned earlier, this page will be updated as new features are added.  If you have any questions, feel free to drop me a line.

Also, if you find the Lync Optimizer useful, please consider donating using the PayPal link on the bottom of the Optimizer page.  I've invested a significant amount of my own time putting this tool together (and continue to do so), and I do have hosting costs to consider.

168 comments:

  1. I found a good resource to determine if a particular area code in North America requires 10 digit dialing. Not sure how up to date it is...

    http://www.nanpa.com/nas/public/npasRequiring10DigitReport.do?method=displayNpasRequiring10DigitReport

    Also area code 976 is not a premium rate number. It is currently an unassigned area code: http://areacode.org/976

    976 used to be a premium rate prefix (i.e. 976-xxxx, with no area code)
    http://en.wikipedia.org/wiki/Area_code_900

    ReplyDelete
  2. Hey Michael,
    Thanks for that...I've always just assumed 976 numbers were 10-digit. Guess I don't call enough late-night chat lines. I'll remove the 976 option from the program.

    Ken

    ReplyDelete
  3. How do you handle area codes that can be local and long distance for instance Ottawa is a 613 area code however there are areas such as Brockville/Kingston etc that require a 1 before dialing.

    ReplyDelete
  4. Hi Habib,
    If you read the linked post in the introduction ("post dug up from ancient times"), the Lync Optimizer was originally designed to deal with exactly this issue. I'm from the 905, so I'm very familiar with the issue. :)

    Ken

    ReplyDelete
  5. I believe the 976 is still valid, just at the nnx level for each NPA, i.e. 404 976-1234.

    ReplyDelete
  6. Thanks for the response Ken, it has been messing with my brain for sometime now. Everything worked like a charm in the AudioCodes GW and the Rules into Lync.

    Much Appreciated.
    Habib

    ReplyDelete
  7. Hi Ken,

    Kudos on the Lync Optimizer. It has come in quite handy for us here especially living in the Dallas, TX area with several overlapping area codes.

    I have come across an issue with a couple of straggling phone numbers.

    Issue 1:
    One of them is automatically sending the number to the PBX with a 1 before the area code and we are getting the message "It is not necessary to dial a 1....". Wondering how I should handle numbers that are like this?

    Issue 2:
    I have a number that DOES need a 1 before the number and Lync rules are stripping the 1 due to the optimizer rules saying that it doesn't need the number. But when calling, we get the message "You must dial a 1....". Any ideas?

    ReplyDelete
    Replies
    1. Hey John,
      Can you tell me what your NPA/NXX is and the numbers in question? Since I grab the information from a 3rd party source, I don't have any control over the content. However, I'd like to verify my program isn't screwing up.

      If the program is working properly, then I can help you modify the dialing rules to suit your needs.

      Ken

      Delete
    2. Hi Ken,

      For instance. I am calling from 972-883-xxxx.

      According to your call source (localcallingguide.com) it says the following number are NOT local to me (they aren't listed in the query):

      (214)449-xxxx
      (817)583-xxxx

      However, if you go to a site like http://www.usa.att.com/localcallingarea/index.jsp you will see that these prefixes ARE listed as local.

      We are currently entering the pilot phase of our Lync Deployment and as more users begin to use the system, I am getting a few numbers per day that cannot be dialed due to the incorrect local call info. I appreciate any help or suggstions you could give. If you would prefer to contact me directly, my e-mail address is below.

      Thanks.

      John B.
      johnb@utdallas.edu

      Delete
    3. Hey John,
      I agree that the information coming from AT&T would be the final word on what's local. However, it doesn't look like they provide a programmatic interface that I can use to query against. That's the beauty of the localcallingguide.com. Unfortunately, I don't know how often they update their lists, but they do say they get their info direct from companies like AT&T. I'll try to find out how often they do updates. In the meantime, I can show you how you can edit the Powershell to add in the additional local numbers. I'll email you separately to show you an example.

      Ken

      Delete
    4. Thanks Ken.

      I've been working with it all day trying to figure out a way to add in the additional numbers to my current dialing rules. If you can show me a faster way, I am ALL EARS! :)

      Delete
    5. Dallas has optional expanded calling areas (Metro), so you would almost need an option to define the expanded area in these locations. This is true with any metropolitan areas.

      Delete
    6. Jeff,
      Correct me if I'm wrong but as far as I know, metro calling areas in Texas are assigned to specific NPA/NXX, so if you enter a number assigned to a metro calling area, it should create the proper dialing rules for the expanded call area.

      Ken

      Delete
    7. Hi Ken,

      My understanding is the allowed NPA/NXX expands if you purchase the Extended Metro service. I believe the source I used on a previous implementation was localcallingguide, which is your reference. I located the old NPA and looked this up, it does list these (believe reference of EMS, i.e. Lake Dallas EMS), but if the service was not purchased it would not be a local call. The last Dallas gig I did was 2009, I will check with a co-worker who is local.

      Delete
    8. Hi Ken,

      The response I received is the business purchases this option to allow their number to be called. This is not the description I received from the company I was working with. Sorry to confuse the matter, but maybe someone else will provide more definition than I have. You are most likely correct in they recieve a specific assignment which allows this and therefore your rules are correct.

      Delete
  8. Hi Ken,

    Just want to thank you for the hardwork that you have put in here and have learned so much from it.

    I have a question which might be very basic but for the life of me I can't seem to figure out.

    I have a main number with extension range 2000-2999. For some of my users only I also have a DID however the last 4 digits of the DID are not the same as their extension. So in Lync I have them added as e.164_User_DID;ext=2018. With my current setup everything works however I want to use Lync optimizer to have it properly formatted and routed as right now if someone calls the DID it goes out the network and back in using up 2 channels on the trunk. So just trying to figure out how I can do this in LyncOptimizer

    Any help would be great!

    ReplyDelete
    Replies
    1. Hey Hamad,
      To deal with these one-offs is pretty straightforward, but can be time-consuming. Run the Optimizer, making sure you put in your extensions for the range 2000-2999. Run the resulting script on your server. The top normalization rule should be the Internal one with your extensions. For the exceptions, just create a new normalization rule that normalizes their extension to their DID. Make sure its HIGHER in the list than the Internal rule. So, for your example you'd have the following rule at the top: ^2018$ --> +e164_User_DID. You should be able to leave off the ;ext=2018 and it should still go to him, assuming nobody else has that same number.

      Make sense?
      Ken

      Delete
  9. Hi Ken,

    I just want to let you know there is a bug in the Dial Plan optimizer for the 310 area code in Los Angeles, CA. In July of 2006 area code 424 was overlayed over 310. Since then we have needed to dial 1+area code+number. However your script specifically strips +1 when forwarding to the gateway.

    I was able to fix my test environment by just encapsulating the 1 + everything else in parentheses. Doing this only dropped the +. An alternative was to change the translation pattern from 8$1 to 81$1 however I didn't like that solution as it made this specific rule different than all the others.

    Thank You for the great blog and a great tool.

    Keith

    ReplyDelete
    Replies
    1. Hey Keith,
      I was unaware that the 310/424 overlay necessitated 11-digit dialing, rather than 10-digit as in most overlays. Any idea why they did that? Know of any other done that way? I'll have to think of a workaround for that particular area code combination. So, to be clear, can you still dial 10-digits to other local area codes like 323, or do you have to do 11-digit to everywhere?

      Ken

      Delete
    2. Hi Ken,
      That's a good question that I don't have an answer to. Unfortunately I trained my self a long time ago to always dial numbers with 11 digits. I do know that at our office we need to send 11 digits to the PSTN. I believe we use Verizon as our Telco. Interestingly enough from our Verizon cell phones we can do 10 digit dialing.

      Keith

      Delete
  10. The Optimizer is great, Ken. This has probably saved me several days of work.

    One potential problem--dialing "0" sends the call instead to the corporate number. Here's the generated script ,slightly obfuscated, in this example the call to "0" actually goes to 9725551234 instead of the extension (when dialing internally):


    New-CsVoiceNormalizationRule -Name 'NA-TX-Plano-972555-Internal-4' -Parent $CSSite.Identity -Description 'Normalization rules for Internal (x0 - x0)' -Pattern '^(0)$' -Translation '+19725551234;ext=$1' -IsInternalExtension:$TRUE -Priority 0 | Out-Null
    New-CsVoiceRoute -Name 'NA-TX-Plano-972555-Internal-4' -Description 'Internal routing for +19725551234 (x0 - x0)' -PSTNUsages 'NA-TX-Plano-972555-Local' -PSTNGatewayList $PSTNGateway.Identity -NumberPattern '^\+19725551234;ext=(0)$' -Priority 0 | Out-Null
    Set-CSVoiceRoute -Identity 'NA-TX-Plano-972555-Internal-4' -PSTNGatewayList @{Add=$PSTNGateway.Identity} | Out-Null
    New-CSOutboundTranslationRule -Name 'NA-TX-Plano-972555-Internal-4' -Parent $PSTNGateway.Identity -Description 'Removes +19725551234 for internal calls from Plano, TX (x0 - x0)' -Pattern '^\+19725551234;ext=(0)$' -Translation '$1' -Priority 0 | Out-Null

    ReplyDelete
    Replies
    1. Actually, I think that '0' is a special number in the phone system. I was able to modify the OutboundTranslation rule to the following and it works:

      New-CSOutboundTranslationRule -Name 'NA-TX-Plano-972555-Internal-4' -Parent $PSTNGateway.Identity -Description 'Removes +19725551234 for internal calls from Plano, TX (x0 - x0)' -Pattern '^\+19725551234;ext=(0)$' -Translation '6532' -Priority 0 | Out-Nu

      Of course, 6532 has to exist in the PBX in some way that relates it to the operator at 0.

      Delete
  11. Hi Ken,

    Just used the Optimizer for an SBA deployment in Rotterdam NL. I was unable to make international calls and found that the Outbound Translation rule for international calls removed the "+" and set the number to just "00"

    Here is the line in the PS script:

    New-CSOutboundTranslationRule -Name 'NL-Rotterdam-10-WPL25-International' -Parent $PSTNGateway.Identity -Priority 6 -Description 'Adds 00 for international calls from Rotterdam, NL' -Pattern '(^\+1[2-9]\d\d[2-9]\d{6}$)|(^\+?(?!(31))([2-9]\d{6,14}$))' -Translation '00$1' | Out-Null

    Regards

    ReplyDelete
    Replies
    1. Hey Chris,
      I think I know where the problem is there. I got the brackets screwed up. The pattern should be -Pattern '^\+((1[2-9]\d\d[2-9]\d{6})|(?(?!(31))([2-9]\d{6,14})))$'

      I fixed the rule, so try it again.

      Ken

      Delete
  12. Wondering about local dialing (specifically GTA! Hello to a fellow GTA'r)

    In the optimizer, it's sending +1 to numbers dialed 10 digits to my gateway - which then results in an intercept from the provider that we do not have to dial 1... Is there a specific option in the optimizer regarding this?

    Also - for modifications - do you recommend re-running the optimizer?

    ReplyDelete
    Replies
    1. Hey Justin,
      Did you create rules for 416-988 yesterday? If that was you, then you selected the SIP trunk option. That option is meant for direct SIP connections to an external SIP provider. It's not meant for SIP connections to a SIP gateway (ie Audiocodes/Dialogic etc). When you select that option, it will not create the necessary rules to strip the +1 for local calls, as most SIP providers expect full e.164 phone numbers.

      What I would do is delete all the existing rules/usages etc and re-run the Optimizer without selecting the Direct SIP option. Then it will create the proper outbound translation rules.

      Ken

      Delete
    2. Ken;

      That was not me... I will re-run the optimizer to ensure I select that. It's actually a 905-629 i'm running it for.

      Delete
    3. Hey Justin,
      If you didn't select the "Direct SIP Connection" checkbox, then you're doing it correctly. It looks like something isn't working right. Are you available for testing things out? You can reach me via Lync at klasko AT buchanan.com

      Ken

      Delete
  13. Hi Ken, could you explain me better the use of the "Gateway type" field? We are using Lync 2010 with an AudioCodes gateway "behind" our TDM PBX.
    TIA
    David

    ReplyDelete
    Replies
    1. Hi David,
      You should always use "Lync 2010" as the gateway type unless you have a good reason not to. The generated ruleset will pretty much take care of your entire Lync Enterprise Voice deployment from end-to-end. All the Audiocodes will have to do is make sure it will route calls to/from the PBX properly (which I can't help with). Audiocodes number manipulation should not be required.

      Ken

      Delete
    2. Hi Ken,
      thank you for your quick reply, we have a site in Mechanicsville (VA) with three different NXXs. We have only a PBX and only one Lync Site. How can I use your tool to have only one set of rules?

      Delete
    3. Hey David,
      If you have multiple NXXs coming into your one site, then you should be fine running the ruleset only once, selecting any one of the 3 NXXs. The dialing rules should be the same for all three.

      Ken

      Delete
    4. Hi Ken, thank you. Really a great tool.
      David

      Delete
  14. Our environment has an existing set of dial plans that were migrated from our OCS system. We are now fully Lync, and I want to create a new dial plan to include additional numbers and various changes. This tool seems like a perfect fit, but I am concerned about testing before committing any changes. Since this is a production system, downtime due to any misconfiguration is not an option. If I generate and run the PS1 script, will the new rules be uncommitted, so that I can run a few test numbers through it before committing it? Or does the script automatically commit the rules?

    ReplyDelete
    Replies
    1. Hi Everett,
      The PS1 script will automatically commit the rules. There isn't any way around it. I recommend that you back up your configuration by going to Action - Export Configuration under the Voice Routing section. That way, if the rules don't work for whatever reason, you can revert to the original settings very quickly. As such, I would recommend that you try this out after normal business hours to minimize any possible disruption to your users.

      Ken

      Delete
  15. Hey Ken, thanks for this fantastic tool. I had one question. We have our business in the Kenmore, WA area and we just changed phone providers which has made the local area code (425) go a little haywire w.r.t dialing a '1' or not dialing a '1' (for some reason you gateway rules for stripping the '1' or not isn't correct anymore. I've been changing the rules as I go (ad hoc) to make it work but would love to get a more definitive list somewhere. So, is there a good resource for getting the lists that I can go to in order to see why things aren't up to date anymore? Let me know and thanks again for this amazing tool
    Steve

    ReplyDelete
    Replies
    1. Hey Stevo,
      Did your phone number change after you switched providers? Who did you switch from and who did you move to? The provider I use is http://www.localcallingguide.com, which pulls in information from all kinds of different sources. For an accurate look at the local calling guide for your new phone provider, you'll have to contact them.

      Ken

      Delete
    2. Hey Ken, just wanted to get back to you in case you were wondering. It turned out that our prefix is listed as Kirkland, WA (by your tool and the Local Calling Guide etc) but we only have that prefix as a leftover\grandfather type of thing as we aren't in Kirkland, WA. So, I had to find the prefix our carrier used for our new account (even though we don't use that actual number). Once I used that prefix to plug into your tool I got the correct routes so all is well. I guess the lesson is that sometimes the prefixes aren't what they appear.
      Steve

      Delete
    3. Hey Steve,
      Glad it worked for you after all that. You were making me nervous about the quality of the stuff coming out of the Local Calling guide. Thanks for letting me know!

      Ken

      Delete
  16. Hi Ken, great utility but i am having an issue hope you can assist .. when it asks for the Site Id i keep getting a message no mediation pools in site.. i ran a get-cssite to confirm they are there and i was not cracking up .. lol .. any thoughts .. did i miss something basic .. thanks ..

    ReplyDelete
    Replies
    1. Hi there,
      Can you type "Get-CSService -MediationServer" and post the results?

      Ken

      Delete
    2. PS C:\Users\dulrich> Get-CSService -MediationServer


      Identity : MediationServer:OCSENT001.DOMAIN.lan
      Registrar : Registrar:OCSENT001.DOMAIN.lan
      EdgeServer :
      SipServerPort : 5070
      SipClientTcpPort : 5060
      SipClientTlsPort : 5067
      AudioPortStart : 49152
      AudioPortCount : 8348
      DependentServiceList : {PstnGateway:67.16.118.132, PstnGateway:68.68.120.47, Ps
      tnGateway:159.63.85.52, PstnGateway:208.79.53.214}
      ServiceId : 1-MediationServer-4
      SiteId : Site:DOMAIN
      PoolFqdn : OCSENT001.DOMAIN.lan
      Version : 5
      Role : MediationServer

      Identity : MediationServer:miamedpool.DOMAIN.lan
      Registrar : Registrar:miapool.DOMAIN.lan
      EdgeServer : EdgeServer:mialedg01.DOMAIN.lan
      SipServerPort : 5070
      SipClientTcpPort : 5060
      SipClientTlsPort : 5067
      AudioPortStart : 49152
      AudioPortCount : 8348
      DependentServiceList : {PstnGateway:gcgtw001.DOMAIN.lan, PstnGateway:ipgtw00
      1.DOMAIN.lan, PstnGateway:ipgtw002.DOMAIN.lan, Pst
      nGateway:gcgtw002.DOMAIN.lan}
      ServiceId : 2-MediationServer-1
      SiteId : Site:MiamiDC
      PoolFqdn : miamedpool.DOMAIN.lan
      Version : 5
      Role : MediationServer

      Identity : MediationServer:BONBRANCH001.DOMAIN.lan
      Registrar : Registrar:BONBRANCH001.DOMAIN.lan
      EdgeServer : EdgeServer:SLCEDG001.DOMAIN.lan
      SipServerPort : 5070
      SipClientTcpPort : 5068
      SipClientTlsPort : 5067
      AudioPortStart : 49152
      AudioPortCount : 8348
      DependentServiceList : {PstnGateway:bonux-001.DOMAIN.lan}
      ServiceId : 3-MediationServer-1
      SiteId : Site:Manila
      PoolFqdn : BONBRANCH001.DOMAIN.lan
      Version : 5
      Role : MediationServer



      PS C:\Users\dulrich>

      Delete
    3. Which site are you trying to apply the rules to?

      Delete
    4. Miami and than the one that says Domain

      Delete
    5. Let's work on this live.....can you email me at ken.lasko@gmail.com with your contact info?

      Ken

      Delete
  17. Hello Ken, good morning.

    I am here in Brazil, Lync optimizer used to create all my settings for Enterprise Voice, the tool works like a charm, congratulations .... More'm a difficulty. Here in Brazil to make a call to another state for example, we use the code from an operator, so how do I connect using this setup is that I said Lync Optimizer?

    ReplyDelete
    Replies
    1. Hi Henrique,
      For Brazil, I enabled a feature called "Carrier Code", which allows you to enter the operator code required for calls to another state. I've never been to Brazil, so I can't say for sure if it works, but its worth a try.

      Ken

      Delete
  18. Hi Ken, thanks for the responses. Where has this option in the optimizer, and how do I link to another state in Lync client, I tried all the options and can not, below is the formats that I tried to call.

    0 21 11 33667773 21 is the code and carrier 11 is the code of the state.

    How do I get connected to the national Lync client what format numbers.

    ReplyDelete
    Replies
    1. Henrique,
      When you select Brazil, you should see "Carrier Code:" appear above "External Access # (optional):". Enter 21 there, and the Optimizer will take care of the rest. When you dial a number in Lync, the Optimizer-generated rules will automatically add a 021 to calls out of state.

      Ken

      Delete
  19. Hi Ken - in Arizona the optimizer is listing 602/623/480/928 however southern AZ also uses 520. Can this be updated?

    ReplyDelete
    Replies
    1. Can you dial 520 phone numbers locally from Phoenix? I'm assuming you ran the Optimizer for 602-470 yesterday afternoon.

      Ken

      Delete
    2. Yes I did. Both 520 and 928 are AZ area codes however one has to dial a '1' to get to either from the 602/480/623 area codes.

      Delete
    3. Then the Optimizer is working correctly. It creates rules for phone numbers that don't require a 1. Everything else is captured by the NA-National rule. You don't need to create specific rules for other Arizona area codes that aren't local.

      Ken

      Delete
    4. In that case 928 would have to be removed.

      Delete
    5. According to the Optimizer, there are two exchanges (252 and 501) in the 928 area code that are local calls from your dialing area. Can you confirm?

      Delete
    6. Greater Phoenix is 602/623/480 and all are 10 digit dialing. 928 is northern Arizona, 520 is southern Arizona and both require a 1 to dial. There are no other area codes in Arizona.

      Delete
    7. According to my source and also this page (http://phoenix.about.com/od/telephone/qt/localcalls.htm), 928-252 and 928-501 are both local calls from your area.

      Ken

      Delete
    8. I ran across an old school POTS line today and actually tested this and can confirm that 928252 and 928501 are both local calls. I dont think anyone else in the state actually is aware of this :P

      Delete
    9. I'm glad everything worked out. Thanks for confirming that for me.

      Ken

      Delete
  20. Ken, this tool does not seem to work with sites which are SBA Branch sites. I run the script and select the Branch Site that is returned to the PS view, but then all that gets created is the Dial Plan. Nothing else is created & the script returns finished.

    My sites have Mediation and PSTN Gateways and are functioning systems.

    Any ideas or is it not implemented yet for the Branch sites?

    Thanks
    Anon

    ReplyDelete
    Replies
    1. Hey Anon,
      The tool should run the same whether its a central or branch site. I've tested it in both with success. Have you previously run the Optimizer for your branch site? Are there existing dialplans/routes etc there?

      Ken

      Delete
  21. Hi Ken, great blog, I've learnt a lot from here.

    I'm trying to setup Lync with an Audiocodes MP-114 FXO for PSTN over a single analogue line.
    I used your optimizer and chose UK > Birmingham 121 and applied the rules.
    However I don't seem to be able to route national calls. If I try test a number such as 01922 123456 it comes back with no route. It does work for mobile numbers though.

    Any idea where I could have gone wrong?

    Thanks

    Andy

    ReplyDelete
    Replies
    1. Hi Andy,
      Turns out there was an error in the regular expression for UK national calls that would result in there being no route for any UK national calls. I've fixed the error now. If you erase what you've got and re-run the Optimizer, you will be able to dial national numbers.

      Thank you very much for pointing out the problem.

      Ken

      Delete
    2. What was the pattern before?

      The pattern is now:
      ^0((1\d{8,9}|[23]\d{9}|5[56]\d{8}|8(4[2-5]|70)\d{7}|45464\d))(\D+\d+)?$
      and that has an error too.

      The pattern should be:
      ^0(1\d{8,9}|[23]\d{9}|5[56]\d{8}|8((4[2-5]|70)\d{7}|45464\d))(\D+\d+)?$
      moving one bracket to a different location.

      Delete
    3. Hey there,
      I always defer to your understanding of the finer details of UK dialing behaviour. I've updated the UK-National rule as per your suggestion.

      Ken

      Delete
    4. Thanks, but I can still make a simple typo somewhere without noticing it, so please test any changes. :-)

      In this case, 0845464X is valid and 045464X is not valid (where X replaces a single missing digit).

      I also dropped you an email with some other much more detailed stuff.

      The list here: UK Phone RegEx and Local Dialling Rules has also been updated.

      Delete
    5. >> If I try test a number such as 01922 123456 it comes back with no route.

      You need to be careful with test numbers. 01922 123456 is an NDO number and cannot be dialled as a six-digit "local number" from anywhere.

      It's better to test with a local number beginning in the range 2 to 8 if you can. Be careful to use the right number of digits too.

      Delete
    6. I have also committed an XML file with the +44/GB local dialling rules for anyone that wants to use it. It matches all existing 5, 4, 3 and 2 digit area codes.

      Delete
    7. It's nice to see the detailed local dialling rules for GB/UK telephone numbers as detailed in the XML file above are now incorporated in Lync Optimizer from version 8.2 onwards.

      Delete
  22. Hi Ken, great tool!

    I did get an error when trying to run the .ps1 file generated for Sweden with an area code that contained Swedish characters (Örnsköldsvik):

    'Missing file specification after redirection operator.'

    It worked with Swedish and Stockholm as area code.
    Any ideas?

    Best Regards
    /Peter



    ReplyDelete
    Replies
    1. Hi Peter,
      I ran the tool for that area code, and it worked fine for me. What are you using for browser etc?

      Ken

      Delete
  23. I used Firefox
    I generated the file with with Internet Explorer and the import worked fine!

    Thanks!

    Best Regards:
    /Peter

    ReplyDelete
  24. Hi Ken,

    There seems to be a problem with the rules for France here are some of the results:

    PS C:\Users\admin> C:\Users\admin\Downloads\FR-Lille-320-Lync.ps1
    Unexpected token '\d' in expression or statement.
    At C:\Users\admin\Downloads\FR-Lille-320-Lync.ps1:143 char:151
    + New-CsVoiceNormalizationRule -Name 'FR-SansFrais' -Parent FR-Lille-32
    0 -Description 'SansFrais la normalisation des numéros de FR' -Pattern '^0(80\d
    <<<< {7})$' -Translation '+33$1' | Out-Null
    + CategoryInfo : ParserError: (\d:String) [], ParseException
    + FullyQualifiedErrorId : UnexpectedToken

    PS C:\Users\admin> C:\Users\admin\Downloads\FR-MarcqenBaroeul-320-Lync.ps1
    Unexpected token '\d' in expression or statement.
    At C:\Users\admin\Downloads\FR-MarcqenBaroeul-320-Lync.ps1:113 char:160
    + New-CsVoiceNormalizationRule -Name 'FR-SansFrais' -Parent FR-MarcqenB
    aroeul-320 -Description 'SansFrais la normalisation des numéros de FR' -Pattern
    '^0(80\d <<<< {7})$' -Translation '+33$1' | Out-Null
    + CategoryInfo : ParserError: (\d:String) [], ParseException
    + FullyQualifiedErrorId : UnexpectedToken

    PS C:\Users\admin> C:\Users\admin\Downloads\UK-London-20-Lync.ps1

    SiteId Identity
    ------ --------
    1 Site:xxxxxx-Lille


    Enter the Site ID to apply the dialing rules for London, UK:

    I generated for London just to make sure I wasn't going mad.

    Regards,

    Ken

    ReplyDelete
    Replies
    1. Hey Ken,
      There was a problem with the script where any words that had a single quote in it, like l'equipe, would cause the script to fail. I've fixed the error, so it should work fine for you now.

      Ken

      Delete
    2. Thank you for your quick reply, works perfectly now.

      Delete
  25. Ken,

    Would it be possible to have the 7 digit dial feature only perform the 7 digit dial for the specified area code? For example in washington DC or NYC, there are multiple area codes that are consider local calling rates. because 7 digit dial is enabled, it doesn't always choose the right area code if someone only dials 7 digits. I know can i can go back and modify the settings after but if you could do it in the tool it would let me keep things up to date.

    thanks!

    ReplyDelete
    Replies
    1. Hey Jim,
      Yes, that is a good idea. I'll see about making it work. Thanks for the idea.

      Ken

      Delete
  26. Ken,

    One other question. We are spinning up a branch office in a different area code (212) from our HQ (202). However we are going to have all the numbers terminate at our trunk in our HQ office. I plan on using a user level dial plan for that so that the numbers don't overlap the site policy. Can the dialing rules optimizer handle that or will creating a new policy to the same site mess up my current site configuration?

    ReplyDelete
    Replies
    1. Hey Jim,
      Yes, the Optimizer will handle that nicely. If the Optimizer detects you already have a site-level policy (ideally created by the Optimizer), it will create a user-level policy with the appropriate dialing rules for the local area. It was originally intended for companies with offices in different countries, but only 1 SIP exit point, but it should work fine for you.

      Ken

      Delete
  27. Trying to create rules for the 709 area code which is in St John's, NL. Cannot save the out out as the web server is gettuing stuck on the ' in St John's

    Great tool

    ReplyDelete
    Replies
    1. Hi Robert,
      Turns out it doesn't like apostrophes in the filename. I've taken care of it, so it should work fine now.

      Ken

      Delete
  28. "UPDATE (12-Oct-2012): Added dial rules for Saudi Arabia and United Arab Emirates (UAE)." has a mistake -
    "Shared Cost" numbers (600\d+) is not covered

    Also, I have some doubts about 400\d+ and 900\d+ numbers, as I've never seen these numbers live

    ReplyDelete
    Replies
    1. Previous post was about Dubai, AE

      Delete
    2. Also,
      1) Emergency numbers here has format (99\d), thus it seems that "service numbers" rule shall be modified - currently it refer to (9\d\d).
      2) Telco services numbers here depends on provider by comply with rule (1\d\d), which is not covered in this release

      Delete
    3. Hi Ken,

      Thanks for the great tool. We use it in all our projects. Recently, we notice one thing. For the local call routes(North Amercia), they only detects the pattern of the first 8-digit, for example: "+1416460", but not restricts the number of digit to be 12 digits in E.164. When Lync tries to route a non-existing internal ext, for example +14164608888;ext=5003. Instead of returing busy tone, Lync sends this call to PSTN, since the first 8 digits matches one of local call routes. We just add ^(\d{4})$, and fix the issue. Thanks!


      Jiang

      Delete
    4. I added the 600 number range and adjusted the service rule for UAE as you described. Thank you for the corrections.

      Ken

      Delete
  29. Hey Ken any idea why my script finishes after it creates the normalization rules? It doesn't create anything else after that (voice policy translation rules, routes, etc). What it does create works, but its going to be a lot of work if I have to go through and finish the rest of the rules on my own!

    ReplyDelete
    Replies
    1. I took a look in the script and while code isn't my strong point, I can see the lines that create all the missing pieces but they are tucked under an else statement so its running the first If part where it creates a user dial plan and normalization rules, but thats not what I need!

      Should I just run the commands on the Else part manually?

      Delete
    2. Sam,
      Do you already have an existing site-level dialplan? If the Optimizer script sees an existing site-level dialplan, it will create a user-level dialplan instead to avoid damaging the existing one and won't create any new routes etc. Its done this way so that a company can create country-specific dialing rules for users from other countries who are homed on a single server.

      Ken

      Delete
    3. Thanks for the quick reply!

      We do have one, I figured that was the problem. I need to get outbound international calls to work without damaging what we already have in place for domestic calls. Any recommendations?

      Delete
    4. You can pull out the international dialing specific lines from the Optimizer script output, modify them so they'll work standalone and run them in Powershell...something like this:

      Set-CsPSTNUsage –Identity global –Usage @{Add='NA-XX-City-555111-International'} -WarningAction:SilentlyContinue | Out-Null
      New-CSVoiceRoute -Name 'NA-XX-City-555111-International' -Priority 8 -Description "International routing for City, XX" -PSTNUsages 'NA-XX-City-555111-International' -PSTNGatewayList $PSTNGateway.Identity -NumberPattern '^\+[2-9]\d{6,14}$' | Out-Null
      New-CSOutboundTranslationRule -Name 'NA-XX-City-555111-International' -Parent $PSTNGateway.Identity -Priority 7 -Description "Adds 011 for international calls from City, XX" -Pattern '^\+([2-9]\d{6,14})$' -Translation '011$1' | Out-Null

      Strip the -PSTNGatewayList $PSTNGateway.Identity and the |Out-Null from above before running. Change the last $PSTNGateway.Identity in the New-OutboundTranslationRule to Global.

      Then using the control panel, add the PSTN gateway to the route and the translation rule to your gateway. Then add the International usage to the site-level policy and you'll be good to go (hopefully!)

      Good luck!
      Ken

      Delete
    5. Thanks so much Ken! Really appreciate it! I will try this out on Monday and let you know how it went!

      Delete
    6. Hey Ken-

      I ended up building the rules with the GUI. I copied one of the normalization rules from the user dial plan it made to the one I have. I then built a voice policy that matches the normalized number and connected everything up how its supposed to look. When I test the normalization rule with a number I took off google, it matches it to the rule I copied (so that works). When I test the normalized number against the voice policy that also matches correctly.

      The problem is when I dial the same number I tested the normalization rule with, it doesnt work as if these rules werent even place. I feel like I'm not missing anything, what else could be wrong?

      Delete
    7. Actually, disregard that. I deleted the user dial plan and it worked!

      Delete
    8. I've had some other stuff come up so I havent been working on this. Came back to it today. I've got it so when I dial a number to london (44 with 20 area code) it will translate to "+0114420" regardless of whether i dial with or without the 011. I can confirm this because when I enter it into the soft phone dialer, it translates it there to what looks like the correct format example 44-020-7611-2400 translates to +011442076112400.

      My problem is that it attempts to make the call but I hit an automatic "we're sorry but your call could not be completed at this time" message every time. We have checked with our phone company and we have international calls enabled. What am I missing? I have all my routes and usages set up correctly...if I do a test case in test voice routing everything goes through the correct routes/usages/plans/etc and is all green.

      Delete
    9. Hey Sam,
      You shouldn't be normalizing your phone numbers to include the 011. Everything should normalize to the proper E.164 number (ie. +4420123456). What I do for international normalization is create a rule that requires users to type in 011 to indicate an international call, but it gets dropped for routing purposes (like ^\+011(\d{6,14})$ normalized to $1). Then create a trunk translation rule that will add the 011 before sending it to the PSTN (like ^\+([2-9]\d{6,14})$ translates to 011$1).

      This all assumes that your phone company requires 011 for international calls. If they're a SIP provider, they may be expecting straight E.164.

      Ken

      Delete
    10. Thanks for the info Ken. I have tested it so when I dialed the number it translated it to +442076112400 on the soft-phone. This did not work either. Sometimes it says the number is not in service, sometimes it connects and dials but I get a voice mail that sounds like a domestic line (no UK accent). I am calling business and stores that should have active lines. +01144 and +44 aren't working, it seems like one or the other should, but they arent!

      Delete
  30. Sir, your blog has lots of useful information is there any chance of adding a search utility in your site ?

    ReplyDelete
    Replies
    1. Search box added. Search results aren't all that readable against the background, though.

      Delete
  31. Hi Ken,

    I noticed some rules for Local calling having the carat before the numbers i.e. |20[^248]|21[267]|.... What is this doing and why would it be included in some definitions, but not others within the Normalization and Outbound Translation strings?

    ReplyDelete
    Replies
    1. Hey Jeff,
      The carat means NOT. I do whatever it takes to make the rule as short as possible. Since [^248] is shorter than [0135679], I'll use it to keep rule length short. I only use that for local normalization rules/routes/outbound translation rules, just because I don't need them elsewhere to keep rules short. Only the local rules tend to be long enough where optimizations like this are necessary.

      Ken

      Delete
    2. Hi Ken,

      Thanks for the explanation. I think I learn more regex and Lync Voice from you and your dialing optimizer output than other reading.

      Cheers,
      Jeff

      Delete
    3. Generally, using a pattern such as [^248] instead of [0135679] can sometimes cause unexpected problems.

      [0135679] matches only the listed digits and nothing else whatsoever.

      [^248] matches the other digits as well as all characters and all punctuation.

      If letters and punctuation enter the dial string, the second pattern will not reject them - unless some other part of the code enforces a 'digits only' rule.

      Delete
  32. Hi Ken

    I ran the optimizer a couple of time in the past and it's the first time I run it with the following warning: WARNING: No PSTN usage specified. Users granted this voice policy will not be able to make outbound PSTN calls. outboud call are not working. I'm pretty sure my setup is like the ones i did in the past. Is it something I did wrong or it comes from the script ?

    Thank you

    ReplyDelete
    Replies
    1. Hey Alexandre,
      Can you tell me what country/city you were running the Optimizer for and when you ran it? I'd like to check things out to make sure all is OK.

      Ken

      Delete
    2. Hi Ken
      I ran it this very morning for Saint-Hyacinthe, Quebec, Canada
      NPA 450
      NXX 774
      extensions: +1450774XXXX 2400 to 2450 DID not checked
      Enable call park 7000 to 7020
      (XXXX was an acutal phone number). All other option were not checked or left blank.

      Thanks a lot

      Delete
    3. Forgot to mention that I deleted asll previous entry in the voice routing sections prior running it. If it can help, this is the output of the powershell window.

      Enter the Site ID to apply the dialing rules for Saint-Hyacinthe, QC: 1
      Creating user-level dial plan for NA
      Creating normalization rules
      Creating voice policies
      Creating PSTN usages
      Assigning usages to voice policies
      WARNING: No PSTN usage specified. Users granted this voice policy will not be able to make outbound PSTN calls.
      Creating voice routes
      Creating outbound translation rules
      Creating optimized local dialing rules #1
      Creating call park orbits
      Creating internal dialing rules
      Finished!

      Delete
    4. Hey Alexandre,
      I see the same thing you are when I run the script against Lync 2010. It works fine on Lync 2013. Are you on Lync 2010? I'm looking into it right now.

      Ken

      Delete
    5. Hi Ken

      Yes unfortunately, I'm still stuck with 2010. We wont do any migration to Lync 2013 before Q3 2013.

      Thanks again for your assitance

      Delete
    6. Hey Alexandre,
      There appears to be a difference in the way that Lync 2010 parses the following command in the Optimizer:
      Get-CsDialPlan $CSSite.Identity | Where {$_.NormalizationRules.Name -like 'NA-*'}

      Lync 2013 returns a valid dialplan, while Lync 2010 returns blank. I've changed it to what it is below and it works much better on both 2010 and 2013:
      (Get-CsDialPlan $CSSite.Identity | Where {$_.NormalizationRules -like '*NA-*'})

      If you re-run the Optimizer against your area, it should work fine. I confirmed it on both Lync 2010 and 2013.

      Looks like I'll have to test future changes against both environments from now on.

      Ken

      Delete
    7. Hi Ken

      Thank you so much, it's working like a charm now. You 're such a Lync GURU! I'll go hit that donation button now. Again, Thank you for all the time you put in the Lync Optimizer, it's really appreciate!

      Delete
    8. Ha ha! Thanks for that Alexandre. Glad it works better now. And thanks in advance for donating. Much appreciated!

      For those of you watching at home, if you ran the Optimizer since the last update (Jan 9) and had issues running the output against Lync 2010, re-run it against the fixed code.

      Ken

      Delete
  33. Ken,
    I just started using you tool earlier this month for our Lync 2010 environment. I generated a script on 01/18/2013 for Madrid Spain 914 and it worked great. I wanted to redo the rules to include internal extensions, so I generated a new script on 01/24/2013. Before running the script, I removed all Dial plans, Policies, Usages, routes and trunk configurations. When I ran the latest script, it only generated the following output.

    Creating site-level dial plan
    Creating normalization rules
    Creating internal dialing rules
    Finished!

    Looking in Lync I found it did not generate polices, usages, routes, or outbound translations.

    I compared the code between the two scripts and found the if statement for the Voice route was updated to use a greater than instead of a not equals

    OLD Code:
    If (((Get-CsVoiceRoute | Where {$_.PstnGatewayList -like $PSTNGateway.Identity -and $_.Name -like "ES-Madrid-914-*"}).Count -ne 0) -or ((Get-CsVoiceRoute | Where {$_.PstnGatewayList -like $PSTNGateway.Identity}).Count -eq 0))


    New Code
    If (((Get-CsVoiceRoute | Where {$_.PstnGatewayList -like $PSTNGateway.Identity -and $_.Name -like "ES-Madrid-914-*"}).Count -gt 0) -or ((Get-CsVoiceRoute | Where {$_.PstnGatewayList -like $PSTNGateway.Identity}).Count -eq 0))

    I updated the new script to use a -ne instead of the –gt and it worked as expected, giving the following output:

    Creating site-level dial plan
    Creating normalization rules
    Creating voice policies
    Creating PSTN usages
    Assigning usages to voice policies
    Creating voice routes
    Creating outbound translation rules
    Creating internal dialing rules
    Finished!

    Not sure if this is another difference between Lync 2010 and 2013 like you found a couple of days ago for the CS-DialPlan or something else.

    Your help would be much appreciated.
    Tim.

    ReplyDelete
    Replies
    1. Tim,
      Thank you very much for pointing out the problem. I did that to fix one issue that arose in certain circumstances, but obviously broke things in other circumstances.

      When you run the following command in a clean environment like yours:
      (Get-CsVoiceRoute | Where {$_.PstnGatewayList -like $PSTNGateway.Identity -and $_.Name -like "ES-Madrid-914-*"}).Count

      ...Lync 2010 returns $NULL, while Lync 2013 returns 0. That screwed up my IF statement because the original code's NOTEQUAL 0 returns TRUE in 2010 and FALSE in 2013. I want it to actually be FALSE in both cases.

      To fix it, I updated the second part of that line to add another OR statement to handle both $NULL and 0 being returned. So, the new code looks like this:

      If (((Get-CsVoiceRoute | Where {$_.PstnGatewayList -like $PSTNGateway.Identity -and $_.Name -like "ES-Madrid-914-*"}).Count -gt 0) -or ((Get-CsVoiceRoute | Where {$_.PstnGatewayList -like $PSTNGateway.Identity}).Count -eq 0) -or ((Get-CsVoiceRoute | Where {$_.PstnGatewayList -like $PSTNGateway.Identity}).Count -eq $NULL))

      Thank you very much for the detailed report. That's exactly the sort of thing I need to hear when things don't work right.

      Ken

      Delete
  34. Hi Ken,

    First of thank you very much for your blogs on Lync, they have helped me install Lync in our environment.

    I'm trying to get enterprise voice up and running and i have used your Lync optimizer, i have run the script and allocated my gateway. When i try to make a call i get the error " Call was not completed or has ended" i also get reference error ID 10001 Source ID 243

    Do you have any idea what could be causing this?

    Regards

    Brenton

    ReplyDelete
    Replies
    1. Hi Brenton,
      I suspect you are not talking to the gateway on the right port. Check your topology and your gateway. Also, look in the Lync server event logs for any warnings about not being able to reach the gateway.

      Ken

      Delete
  35. First off, thanks a bunch for thise great tool. I am deploying Lync 2013 and could not get the External calling to work. This great tool did the trick.

    Question 1: I am integrating into a Cisco 2821 with CME 7.0 running and it works pretty well. But I am trying to figure out where/how to configure calls to/from the lync clients to the cisco phones. Lync clients have an extension in 5xxx range and the Cisco Phones in the 8xx range. I had it working as a first step prior, but that was before I used your tool to generate everything. Now I am not sure where to add the configs to allow lync<->cisco calls.

    Question 2: What is the best place to add rules to take a 7digit local number entered in the lync client and add +1616 to make the call go through?

    Thanks again for this great site,

    Pete

    ReplyDelete
    Replies
    1. Hey Pete,
      When you ran the Optimizer, did you use the Extensions option to define your extension ranges? If not, you can create a normalization rule to normalize 8xx numbers to an E.164 equivalent like this:

      ^(8\d{2})$ --> +16165551111;ext=$1 (use your PBX pilot num in place of 5551111)

      You should already have the necessary routes to handle routing to the PBX, I'm assuming. Then create a trunk translation rule to strop the +1616 etc before going to the PBX, like this:

      ^\+16165551111;ext=(8\d{2}) --> $1

      That's the preferred way to do things, but you could also do it by just creating a normalization rule and route to handle 8xx.

      Ken

      Delete
  36. Hi Ken, thanks for great tool :) Any plans to add support for Finland?

    ReplyDelete
    Replies
    1. Hi Leif,
      Not sure how Finland slipped through the cracks, but I will add it when I get some time.

      Thanks,
      Ken

      Delete
  37. Hi Ken,
    I am very new to Lync and your blog help me a lot to understand the Lync Enterprise voice. I would like to say "thank you" for your all hard work for posting such lengthy information for others to refer.

    I am having "Learner" plate for Lync.
    Before I apply the Lync Optimizer out put ".PS1" file to PS, Is there any way I can see the output like lync simulator(other than notepad)? OR Is there any way to remove the file so that Lync will be back to normal before applying Lync Optimizer output?
    In my lab, I don't have PSTN gateway and that's the reason I am asking you about the above question, in case the scripts doesn't work and I want to come back on a point from where I can restart.

    Thanks and Regards,
    N Patel
    UK

    ReplyDelete
    Replies
    1. Hey there,
      If you back up your voice configuration before running the .PS1 script, you can revert back to your original state with just a few clicks. Go to Action - Export Configuration under the Voice Routing section of the Lync Control Panel. Just an FYI, this is step 4 in the "Before You Start" section. :)

      Ken

      Delete
  38. hi guys,
    how can i play a message to a inbound call for a number +574XXXXXXX, the message have to say "this call has been recorded"
    thanks

    ReplyDelete
  39. Hey Ken!

    Great job on the lync optimizer! We've been having issues with it here though because our DID ranges are all over the place. Our numbers begin with 416-862, 416-646 and 416-945. There are 30 DID ranges for our 416-646 block alone and in the script you only have included room for 10 DID blocks.

    Any suggestions on how to make this a little easier for us?

    ReplyDelete
    Replies
    1. Well, I guess you could just run the Optimizer once for each batch of 10 extension ranges, and do a quick search-replace to change the rule names. Paste in the Internal rules into your original PS1 and give it a go. I've toyed with the idea of increasing the number of extensions, but I'm trying to achieve a balance between number of extension ranges and usability.

      Ken

      Delete
  40. Ken,

    I used this Dialing optimizer for a customer site in NY. However, they are unable to dial internationally. When doing the tests, it does not add the +9011. For example, if I enter in 01131135788300, it translates to +31135788300. Any ideas?

    Pattern to match: ^(011)?([2-9]\d{6,14})(\D+\d+)?$
    Translation Rule: +$2

    ReplyDelete
    Replies
    1. Did you select the "SIP Trunk Connection" option in the Optimizer? If so, the Optimizer won't apply outbound translation rules that will add the 011 for international calls that is typically required for traditional PSTN connections. If you have a traditional PSTN connection or if your SIP provider expects 011 for international calls, re-run the Optimizer and don't select the "SIP trunk connection" option.

      Ken

      Delete
  41. I ran the optimizer for the 813 area code with a 280 exchange and 7 digit dialing the beginning of the rule has a question mark which I thought was to be used after a number. The rule causes our snom phones to show the error "Cannot understand this RegEx: ^((?, error is: Invalid preceding regular expression" is this rule currently formed wrong?

    New-CsVoiceNormalizationRule -Name "NA-FL-TampaCentral-813280-813-Local" -Parent $CSSite.Identity -Priority 0 -Description "7-digit local dialing for area code 813 in Tampa Central, FL" -Pattern '^((?!([01]|32[78]|37[08]|43[79]|45[029]|46[0127]|48[58]|49[279]|51[189]|52[124]|53[^12]|54[^1569]|55[^248]|56[^279]|57[^1249]|58[^4]|59[^478]|60[^0124]|61[14679]|64[0678]|65[26]|66[0589]|67[08]|68[^1459]|69[2678]|70[0569]|71[01]|72[^078]|73[03468]|77[1236]|79[01789]|80[79]|81[^0478]|82[^6789]|83[46]|84[578]|85[1389]|86[019]|89[3467]|90[46]|91[126]|93[479]|94[^3489]|95[^1267]|211|255|278|284|291|311|392|411|742|755|768|923|970|981|993))(\d{7}))$' -Translation '+1813$1' | Out-Null

    ReplyDelete
    Replies
    1. The regex is formatted correctly, but it appears that the Snom phones aren't parsing the regex properly. The only course of action is to either not use 7-digit dialing or open a ticket with Snom to have them fix the issue.

      Ken

      Delete
  42. Yea it looks like the snom sees the ! as a separator for each normalization rule so when it runs into ! in the above rule it thinks ^((? is a complete rule and formatted incorrectly. I will need to turn on some more detailed logging on the snom to see how the normalization rules are delivered to it. Not sure if Lync sends out the normalization rules for the location profile stitched together with the ! already or each rule is sent separate and the phone is putting them together.

    ReplyDelete
    Replies
    1. Jim,
      Let me know what you find out. Weird that snom would use a valid regex character to be used as a separator.

      Ken

      Delete
  43. Hi Ken,

    Any chance you could add Bahrain as a country as would help me tremendously as have an site going live soon.

    I've used your optimizer for sites in the UK and Central Europe so far with huge success and we are now extending our lync enterprise voice deployment to other regions

    Cheers :)

    ReplyDelete
    Replies
    1. I'm glad the Optimizer has worked well for you so far. I'll add Bahrain sometime in the next little while. Been busy these days.

      Ken

      Delete
  44. It would also be great if you could add New Zealand in at some point when you have time.

    Cheers

    ReplyDelete
    Replies
    1. Not likely to happen anytime soon, unless there's a resource out there that shows what numbers are local for a given phone exchange. It seems that New Zealand is as messed up as North America in terms of dialing rules. Fortunately, I have a good source for local numbers for every phone exchange in North America. If you can find me one for New Zealand, then we may be able to do something.

      Ken

      Delete
  45. When i generate the file i don't have the button "to allow the script to be run" it doesn't show up, I'm i doing something wrong? Also, when i try and run the ps1 file on power shell i receive this error

    The term '.\filename-Lync.ps1' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try
    again.

    Any ideas?

    ReplyDelete
    Replies
    1. Are you sure the .PS1 file is named like "filename-Lync.ps1"? Did you create the file in Notepad and maybe got created with a .TXT extension? The error doesn't seem like a script-specific error.

      Ken

      Delete
  46. Hi Ken,

    What i have to do, if our Area-Code is´nt in the drop down list.
    Can i Change the generated PS1-File and if so, which entries?

    Regards

    ReplyDelete
    Replies
    1. Hi Thomas,
      What area code is missing for which country? I can add it easily.

      Ken

      Delete
    2. Hi Ken,

      four our Installation, i need for Germany:

      6403 Linden

      You made a very great work. I think, if it´s usefull, i can send you a list of area codes for Germany.

      Regards

      Thomas




      Delete
    3. Thanks Thomas.
      6403 Linden has been added. It may take a while to clear the cache. I find opening a browser window on a new machine works well if you need it right away. If you can send me a list of area codes for Germany, that would be greatly appreciated.

      Ken

      Delete
  47. Hi Ken, I have used this before but for some reason the Dial Plans are not showing up when i check, the script says it ran
    Creating site-level dial plan
    Creating normalization rules
    Finished!
    PS C:\Users\dulrich\desktop>

    ReplyDelete
    Replies
    1. Hi there,
      This will happen if you've already got voice routes defined for a specific gateway that were not created by the Optimizer during a previous run. I'm working on asking the user for input on whether to overwrite the existing routes. If you're cool with it, backup your current config and delete any routes assigned to your PSTN gateway, then re-run the Optimizer.

      Ken

      Delete
    2. Hi Ken,
      I'm experiencing DUlrich1227's same issue. I ran the Optimizer to create my original dial plan, voice policy, etc. It created it as a site scope dial plan since there wasn't any existing ones. I reran the Optimizer with a new NPA, etc. and ran the PS1 file hoping that I would just create another User scope dial plan. So the intention here is multiple area codes in one central site. Any ideas?

      Thanks!

      Delete
    3. So, what exactly are you trying to accomplish? What's your topology look like? How many Lync servers/sites/PSTN trunks/gateways do you have and where are they pointing? If you only have one Lync server with one PSTN gateway, then the Optimizer will do a full run the first time. If you download a second set of rules for a different country, then it will create a user-level dialplan to give remote users localized dialing rules, even though their calls are routing via a different country.

      The Optimizer is not designed to handle a scenario where you run two different rulesets from the same country against a single Lync server/site/GW combination.

      If you describe what you're trying to do, maybe I can help you better.

      Ken

      Delete
    4. Single Lync Site, Singe Mediation Pool (3 servers), Single Trunk, Single Gateway, Single SIP Trunk (breakout). I ran it once. I want to run a second set of rules for a different Area Code. So in the end I can have a Seattle dialplan, San Francisco dialplan, New York dialplan, etc. all in a single Lync site. I think you second paragraph answers it though. I guess my option is to manually create what I need correct? Any recommendations on that?

      Delete
    5. What do you need multiple dial plans for? Won't the dialing behaviour be the same for each of them? Or are you looking to add extension dialing that's specific to each site and can't be shared for whatever reason? Or am I missing something...it's always possible, I'm not as smart as my picture would imply.

      Ken

      Delete
    6. We have a centralized SIP trunk for several DID ranges by city. The effective purpose would be to accommodate the behavior of 7 digit dialing for all users in each of their city. Yes all the calls break out of one location but I'd like for the user, not matter which DID range, be able to dial 7 digits. I'm assuming I'll create dial plans for each city and have a unique 7 digital normalization rule for that locale. Does that make sense or a good workaround?

      Delete
    7. OK, I get what you're doing. Sadly, there's no support in the Optimizer for that scenario, but you can enable it, and hopefully not make a mess by going to line 163 where it says:
      If (((Get-CsDialPlan $CSSite.Identity | Where-Object {$_.NormalizationRules -like '*NA-*'}) -eq $NULL) -and ((Get-CsDialPlan $CSSite.Identity) -ne $NULL))

      and modify that line to look like:

      If ( (Get-CsDialPlan $CSSite.Identity) -ne $NULL)

      It should let you create a user-level dial plan the way you want. Let me know how it works out, and I may make that change permanently, after I consider why I put it there in the first place.

      Ken

      Delete
  48. Hi Ken, how about adding NZ?

    ReplyDelete
    Replies
    1. Been looking into it. Have always thought it was too hard, but may be able to work something out.

      Delete
    2. And its done. Only took 3 months to do. Check it out and let me know what you think.

      Ken

      Delete
  49. Hi Ken,
    Your site has been very helpful. I have a couple questions. About dialing rules and the optimizer. We are a company based in the US, though we have conference calls with several different countries. In an effort to reduce cost to these other companies we have purchased local numbers in the different countries.

    1. Is there a reference that I could use to setup the dialing plan/normalization rule for the different countries
    2. Some of the international numbers that we have - like the UK is a national number and foes not have an area code that matches up on your optimizer. What can I do in this case?

    ReplyDelete
    Replies
    1. To answer your questions:
      1. I use Wikipedia to find out details of other countries, as well as references from the ITU (http://www.itu.int/oth/T0202.aspx?parent=T0202). The Optimizer has 34 countries, with more added all the time, so if you ask nicely, I may move some up the queue

      2. I'm starting to add non-geographic area codes to the Optimizer, starting with the UK for 3 and 5. You'll see them at the very bottom of the area code list. Others will follow (again, let me know what countries you need).

      Hope this helps.
      Ken

      Delete
  50. Hi Ken,

    I wanted to thank you for the DRO - it is a fantastic piece of work. I used it recently for a company with multiple small offices around Europe. I only hit one bug related to the normalisation rule created for German toll free numbers: the script creates a matching regex entry of ^(((0|00)800\d{7}))$ but this retains the leading 0 or 00 in the output. I modified it to ^(0|00)((800\d{7}))$ and the translation rule to +49$2 to omit the leading 0 or 00.

    Cheers,
    Garry

    ReplyDelete
    Replies
    1. Thanks Garry,
      I've updated the rule so it will accept just a single 0 in front of the number and will strip it on normalization. Thanks for the heads up!

      Ken

      Delete
  51. Hey Ken,

    it will be nice to have Nigeria in this tool. Can you consider that pls.

    Theo

    ReplyDelete
  52. I was trying to create some rules and added option for 7 digit dialing for area code 206 with prefix 438.
    The 7 digit normalization rule for 206 area code does not work. The rule ends with an extra close parenthesis and when testing by entering 7 digits it does not normalize at all - gives an error. It looks like that rule is trying to generate a rule set to exclude any number that begins with any of the 3 digit area codes and then if that passes take the 7 entered digits and add +1206 as the last part of the rule is (\d{7}) which would be any 7 digits.
    It looks very different from the 425 local 7 digit rule which looks for match on existing 3 digit prefixes in that area code + any 4 digits.

    ReplyDelete
    Replies
    1. Thank you for alerting me to this. You'll see a fix in the next few days.

      Ken

      Delete
  53. Hi Ken,
    I saw your video from the Lync Conference and learned that I was not setup correctly for failover simply by including trunks for different sites to my routes, round robin not top down. Thanks for that.

    I want to see what your guidance would be for our scenario.

    We have two sites, LA and San Francisco. Each site has an AudioCodes Gateway for PSTN access and a second Trunk to our Cisco CallManager node at that site for internal extensions.

    So
    LA AudioCodes for PSTN
    LA CM for internal extensions
    SF AudioCodes for PSTN
    SF CM for Internal extensions

    How should I use your tool to support the two different gateways at each site and still be able to benefit from failover between the sites. I need internal extensions that are not assigned to Lync Users to route over the internal trunks to CallManager and calls bound for the PSTN to go out via the AudioCodes Gateways.

    And then ideally have the benefit of failover between the site trunks for the two routes Internal and PSTN.

    Hopefully that makes sense.
    Thanks
    Luke

    ReplyDelete
    Replies
    1. The easiest way to go about this is to create a ruleset for both LA and SF, including the extensions bound for Call Manager. Run the resulting scripts twice each (LA, SF, LA, SF), making sure to say "Yes" to the prompt for doing least cost routing.

      Then modify the route for the internal extensions to point to the relevant Call Manager at each site, and copy the trunk translation rule that strips the E.164 number down to the extensions to the CM trunk (you may need to create the trunk config in Lync Control Panel first).

      Then copy the internal extension normalization rules between each of the dial plans, so everyone can dial extensions for each site and it will route correctly.

      That should be pretty much all you need to do to get it going. That will give you least cost/failover routing to both SF and LA, and also ensures that called extensions will go to the right place.

      Ken

      Delete
    2. Thanks Ken,
      I took your advice and everything is working great. I only have one issue at this time.

      I have a range of internal extensions 4100-4700. I added them to the list of internal extensions as +13235497155;ext=4XXX. the generated rule works perfectly, dial 4xxx and it transforms to e.164.

      But most of these extensions are still over on my CallManger. So I have updated the route and changed to the internal trunk to my CallManager. Now I am trying to get my Called Number Translation Rule on the Trunk to strip the +13235497155;ext= and just send the last 4 digits and I can't seem to get it to work.

      When I add the ; to the starting digits in the rule I get an unexpected character warning. Any idea what I am doing wrong?

      In short I am trying to strip everything but the last 4 digits when I send it over the internal trunk to my callmanager.

      Thanks,
      Luke

      Delete
    3. Ken,
      Never mind. I just figured it out. I needed to manually edit the rule vs. let the rule be built for me. I used ^\+\d{11};ext=(\d{4})$ .
      Your tool is fantastic.
      Thanks again,
      Luke

      Delete
  54. 4th Lync installation I've done using this (2 2010s and 2 2013s) and it's worked flawlessly every time. UCKen FTW!

    ReplyDelete
  55. Great article and tool, The only thing I don't understand is the UK-Non-Geographic-Service usage, what numbers are they for?

    ReplyDelete
    Replies
    1. They are supposed to represent every service number in the UK. It was provided to me by a telephony guy from the UK years ago.

      Delete
  56. This is a good tool but do you plan to update for Teams cmdlt?
    Since SfB cmdlt is going away.

    ReplyDelete
    Replies
    1. The site has supported Teams for a number of years now.

      Delete