Monday, January 24, 2011

Lync External Web Services without Reverse Proxy

PLEASE NOTE:  While the procedures below has worked in a Lync 2010 environment, it may not work in Lync 2013 or Skype for Business.  It is HIGHLY recommended to employ a reverse-proxy solution.  Opening up an internal domain-joined computer to the Internet can be a recipe for disaster. I myself, have only done this procedure once, and have since made a reverse-proxy mandatory for customers looking for help from me. Not only that, but I've heard from some that the mobility features do not work using the alternate IP method.  If you find yourself in that situation, please be aware that Microsoft (and any consulting company worth their salt) WILL NOT support this method.  Also, this is not a substitute for deploying an edge server.  If you want external connectivity to work, you MUST deploy an edge server.  There is no other way, supported or not.  Caveat emptor.

And now on with the show....

While working on a Lync deployment for a small customer, it came up during the planning stages that they didn't have a reverse proxy server (like ISA/TMG) to publish the Meet/Dialin simple URLs and web components URL, nor were they planning to. In the past, I had tried to make OCS work without a reverse proxy, but some things just didn't work right. After advising them about the risks involved with opening up an internal domain-joined computer to the Internet, I told them I would try to make Lync work without a reverse proxy, but cautioned that it may not work.

Friday, January 21, 2011

Lync Enterprise Voice Best Practices - Usages and Routes

Over the past while, I've typed some lengthy posts about the importance of E.164 phone number formatting and my take on normalization best practices. Now to pull it all together for the final act, I'll be talking about Lync PSTN usages and routes.

When you look at the Voice Routing section of the Lync Control Panel, you'll see the following "tabs": Dial Plan, Voice Policy, Route, PSTN Usage, Trunk Configuration and Test Voice Routing:

From this section, you can manage most aspects of your Enterprise Voice deployment.

Dial Plans were briefly discussed in my previous post.  A dial plan is a collection of normalization rules that are assigned to sites, pools or users.  Dial plans are designed to allow users to dial phone numbers as they are accustomed to, but still outputs properly formatted E.164 phone numbers, no matter what they type. When you create a dial plan at the site or pool level, all users within that site or pool whose Dial Plan Policy is set to Automatic will be assigned that policy.  There can only be one Dial Plan per site/pool.  If one dial plan is assigned to a site and another one to a pool, the pool-level policy will take precedence.  If you want more granular control, you can create user-level dial plans.  You have to assign users to the user-level Dial Plan policy either through the control panel or via Powershell.

Voice Policies define the capabilities of the users assigned to it. Capabilities can include call transfer and call forward, among others. Capabilities also include the types of calls (local, long distance, international etc) members are allowed to make via PSTN Usages.  Voice policies are assigned to users or sites. Site policies will automatically be named the same as the site, while user policies can be given whatever name suits you.

When you create a voice policy, you have the option to associate PSTN Usages to the policy. If you're just starting out, this list will be blank.

PSTN Usages
PSTN usages are the link between a voice policy and a route. The combination of the three determines the calls a user can make and what route the calls will take.  PSTN usages can contain multiple routes, and can be assigned to multiple voice policies.

You can only create PSTN usages through the Voice Policy interface. When you create PSTN usages within a specific voice policy, it will automatically link to that policy.  You can also create routes from within the PSTN Usage creation dialog box, which makes the whole creation process efficient.

PSTN usage names should relate to calls of the same type: like Local, Long Distance/National, or International. If you've got more than one site where PSTN calls will be made and has a defined PSTN gateway, its best to qualify the usages with site information (you'll see why later). I prefer (and this is the same format used for the Dialing Rule Optimizer):  country-state/prov-city-callclass or country-city-callclass.

Some examples:

I tend to use NA (North America) instead of US and CA, because both countries share the same country code (1). Again, if you have a better scheme, go ahead and use it.  There is no right or wrong way to do this.

Once the PSTN usages are created, I then create routes. If you've followed best practices and ensured that every phone number that enters the system is formatted for E.164, this is where your diligence pays off. A route defines the actual path a call takes on its way out to the PSTN via a defined PSTN gateway. When a user makes a call, a route is selected based on two things: a matching rule (ie. 11-digit numbers starting with +1) and whether that route is part of a PSTN usage assigned to the user.

Don't make the mistake of assigning multiple gateways from different sites in the hopes of achieving failover routing. Lync doesn't use any sort of ordering when determining which gateway to use within a given route.  Its very likely that calls will route equally between the two, which would make for a nasty surprise when the bills come in. For example, don't put gateways from your Toronto and Rome deployments in the same route.  Some calls will route through Toronto, and others will route through Rome.  To properly achieve failover routing, use PSTN usage ordering, as discussed later.

Create routes according to the calls you want to send out that particular gateway.  You can be as generic or as specific as you want.  For instance, you could create a single route called All Calls, and have a matching pattern of ^\+\d+$ (which means accept any call starting with + and at least one digit.).

I prefer to get more granular, even if I won't be imposing limits on the calls users can make. Increased granularity allows you to impose great control over call paths. For instance, you can easily setup least cost routing and backup routes by using properly formatted routes.

I like to setup at least 5 different routes for each gateway: Local, National (long distance), International, Toll-Free, and Service Codes.  As with usages and normalization rules, I like to follow the same naming convention: country-state/prov-city-routeclass or country-city-routeclass.  I assign the routes to the respective PSTN usage.  National and International routes go into the National and International PSTN usages respectively.  Local, Toll-Free and Service Codes all go into the Local PSTN usage.

Each site should look something like this, using Ottawa as an example:
PSTN UsageRouteRule
Trunk Translation
With your voice policy/PSTN usages/routes all setup, calls should be routed to the proper gateway for sending out to the PSTN. However, the local PSTN provider likely has their own formatting rules for calls that may not be compatible with E.164.

To accomodate these requirements, you create trunk translation rules to add or remove digits from your E.164 formatted phone numbers before sending the call out to the PSTN.  For instance, a Toronto gateway to the PSTN might need to strip the +1 from local calls, strip the + from long distance calls and add 011 to international calls.  Again, the Dialing Rule Optimizer can help create the local ruleset for your deployment.  An example for Toronto would look something like this:
Trunk Translation Rule NamePatternTranslationSent to GW Example

If your calls have to route through a PBX before going to the PSTN, you can add the necessary external access prefix here as well. For example (using 9 as the external access prefix):
Trunk Translation Rule NamePatternTranslationSent to GW Example

PSTN Usages Ordering
When you have all your usages and routes defined, it is very important to put your PSTN usages in the correct order in your Voice Policies.  When searching for a route, Lync will start at the top of the PSTN usage list and work its way down until it finds a functional route that matches the dialed number.  If the selected route is not available because the gateway is down or can't accept any more calls, then Lync will keep searching for a matching, working route.  Order your PSTN usages so that calls will use the cheapest toll options and also provide failover capabilities. 

Imagine you have a 3 site deployment, with offices in Vancouver, Toronto and Budapest, Hungary.  You've setup your usages and routes according to my guide.  Your PSTN usage for the Vancouver site Voice Policy would look something like this:



In this manner, calls will use the least-cost route for any given call, and should the preferred route not be available, the call will use the next cheapest available option.  The most used usages are positioned at the top to reduce call connection time.  Because every phone number is normalized to E.164, it can be easily routed to any gateway, which will then add any necessary routing codes (like 011) before sending it out.  This may take a fair bit of work to setup, especially with a large deployment with several sites, but I think the benefits outweigh the time involved in setting it up.

Of course, with the flexibility provided by Lync, this is just one method of setting up your Enterprise Voice deployment.  If you've got other ideas or methods, I'd love to hear them.

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 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:
7xxx Extensions^(7\d{3})+1416222$1
5xxx Extensions^(5\d{3})+14162221111;ext=$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.