Friday, October 22, 2010

Music on Hold for Lync Clients

Yet another nice new feature in Lync is the ability for Enterprise Voice enabled users to choose their own music that's played when they put someone on hold.

From the Lync client, click on the Options "gear" icon and go to Ringtones and Sounds.  If the logged on user is enabled for Enterprise Voice, the last option should be Play music on hold.  Users not enabled for Enterprise Voice won't see the option to use music on hold.  For enabled users, you'll notice that it's greyed out by default.

To enable this setting, you need to edit your Lync Client Policy to allow music on hold. Client policies replace the Group Policy Objects that were used in Communicator 2007 R2 to enable/disable features in the client. These policies can be global, or they can be limited to groups or even individual users.

You manage client policies via Lync Powershell.  Assuming you haven't created any client policies, there will be a single one called Global.  To see the current settings of the Global client policy, type:
Get-CSClientPolicy Global
The setting we're interested in is EnableClientMusicOnHold.  By default, this is set to FALSE.  Set it to TRUE by typing:
Set-CSClientPolicy Global -EnableClientMusicOnHold:$TRUE
Log off and back onto the Lync client and the Play music on hold dialog box should be enabled.  Interestingly, there doesn't seem to be a way to allow the user to check or uncheck this option. It's either enabled or disabled by the policy, and can't be modified by the user.

If you've previously installed beta versions of Lync (pre-RC), you'll notice the path to the music file is probably C:\Program Files (x86)\Microsoft Office Communicator\Media\DefaultHold.wma.  If you browse to this location, you'll find it doesn't exist.  The actual path to the default hold music file is C:\Program Files (x86)\Microsoft Lync\Media\DefaultHold.wma

Now, when you put someone on hold, they will get a nice soothing melody while they anxiously await your return. Note that this setting is computer-specific, meaning that if you have Lync running on multiple machines, you'll have to make sure the path is set correctly on all computers, and the media file exists in that location.

If you don't want to use the default hold music, you're free to use any piece of music that suits your taste. The caveat here is that the selected music file must be in WMA format.  Bitrate-wise, I've tested a few different files, and it hasn't had any trouble with them - variable or constant bit rate, stereo and up to 192 kbps.  Your mileage may vary.  If you're looking for a tool to convert MP3 to WMA, I suggest Audacity.

If you don't trust your users to select appropriate hold music, you can assign an audio file using the MusicOnHoldAudioFile parameter in Set-CSClientPolicy.
Set-CSClientPolicy -EnableClientMusicOnHold:$TRUE -MusicOnHoldAudioFile pathtoaudiofile.wma
If you assign this setting, users won't be able to change the hold music. To allow users to change the audio file, you have to clear the setting by assigning the $NULL value or "" to the MusicOnHoldAudioFile parameter.

Friday, October 15, 2010

Least Cost Routing in Lync

NOTE (June 2011):  While the general idea around least cost routing hasn't changed, the process required to use the Dialing Rule Optimizer has been greatly simplified and enhanced since I originally created this post.  See this post for the most up-to-date information on how to best use the Dialing Rule Optimizer.  I do encourage you to read on for general background information on how least-cost routing works.

Companies that have a number of offices spread across a wide geographical area often wish to leverage something called Least Cost Routing to reduce their telephony costs.  Least Cost Routing is the process of selecting the cheapest telephony route for a given call.  If you're a company with offices spread over a wide area, it makes sense to route your calls so that you avoid long-distance changes whenever possible.

Say you are in a company with offices in Toronto, Vancouver, Dallas and Miami. If you're in the Toronto office and you need to call someone in the Miami area, it can be much cheaper to route your call over the WAN to your Miami office and then out to the PSTN. What would have been a long-distance call is now a local one.

Traditionally, it's been extremely tedious to implement Least Cost Routing effectively. You need to obtain lists of all the local calling areas for all your offices, massage the data into something your telephony system understands, and then import that data.  Keeping track of changes can be challenging at best, and near impossible at worst. Publicly available lists such as those from make obtaining the raw data relatively easy, but manually working that data into something manageable is extremely difficult.

For instance, look at the local calling area for Dallas, TX.  The results include 1737 individual lines of data!  Sure, the data is setup for easy import into a spreadsheet, but turning this into something usable will take a very long time. What happens when there are changes? How do you keep track of new additions or corrections?  What if you have to do this for a company with offices across the continent?  How many rules will your device accept before it reaches its limit?

Some people might take a simpler approach and route all calls for a given area code through that office. For Dallas, they might look at the 1737 rules and decide to route all calls to the 214, 469 and 972 area codes through the Dallas office. Sure this works in some cases (like New York City), but most telephone numbers cannot make local calls to every number in that area code.  So, you would be routing some calls over your WAN (which incurs data costs) to your Dallas office and have to pay long-distance anyways.

How can someone easily setup Least Cost Routing without giving themselves an administrative aneurysm when faced with a challenge like this? Well, guess what?  I've got a solution.

Using the data from and the ease-of-administration inherent in Lync's Powershell command structure, I've created a web-based tool called the Dialing Rule Optimizer that does almost everything you need to implement Least Cost Routing in your Lync deployment.

First, you need to make sure your Lync deployment is complete. Specifically, make sure you've defined and published the PSTN gateways for all your offices using Topology Builder.  Make sure the PSTN gateways are associated with the appropriate mediation server.  Also, make sure that all your normalization rules normalize numbers to the E.164 standard ie. +15195551111.

Once published, you need to add the PSTN gateways as Pool Trunks in Lync Control Panel.  Go to Voice Routing - Trunk Configuration.  Click New - Pool Trunk for each PSTN gateway.  Make sure the name of the pool trunk is the same as the PSTN Gateway.  Once complete, you should have something similar to this:

Now, go to the Dialing Rule Optimizer at  I originally created this tool to help create optimized local dialing rules for AudioCodes and Dialogic gateways.  I've recently added Lync functionality.  You will be presented with the following screen:

Enter the area code (NPA) and exchange (NXX) for each of your sites. Leave the gateway type as Lync 2010.  If your PSTN gateway requires a 9 or other number to be dialed before the actual phone number, enter it at External Access #.  Enter the PSTN gateway name in the same format as you created in Topology Builder. In our example, we'll use miami.root.loc. Enter your email address so you will be notified when dialing rule changes are detected.

If your local dialling area allows 7-digit dialling and the 7-digit dialing area spans more than one area code, select the 7-Digit Normalization option.  The program will create 7-digit normalization rules that correspond to your local dialing area.  For example, Kansas City, MO allows 7-digit dialling across the 816 and 913 area codes. With 7-digit normalization selected, the Dialing Rule Optimizer will ensure that user-dialled 7-digit numbers are normalized to E.164 format for the correct area code.  For example: if a user dials 2915555, Lync will normalize the number to +18162915555.  If they dial 2195555, Lync will normalize it to +19132195555.

ONLY USE THE 7-DIGIT NORMALIZATION OPTION IF 7-DIGIT DIALLING IS ALLOWED IN YOUR AREA. If you generate 7-digit normalization rules for an area that does not allow 7-digit dialling, you will likely see inconsistent results.

Once done, press Generate Rules.  After a short while, you will see a link to a text file that contains all the Powershell commands required to setup Least Cost Routing for that particular site.  Copy the contents of the text file into the Lync Powershell dialog box.  The rest should be taken care of! 

Here's a sample of what the Powershell commands look like for 305-836 (Miami) with a PSTN gateway name of miami.root.loc:
Set-CsPSTNUsage –Identity global –Usage @{Add='NA-FL-Miami-Local'}

New-CSVoiceRoute -Name 'NA-FL-Miami-1' -Description 'Least cost routing for Miami, FL' -PSTNUsages 'NA-FL-Miami-Local' -PSTNGatewayList 'miami.root.loc' -NumberPattern '(\+1561((21[0238])|(2(06|08|37|39|41|45|87|88|89))|(36[1278])|(39[12345])|(3(00|02|05|72|78))|(44[2357])|(45[1678])|(4(16|17|70|77|79))|(5(04|05|44|49))|(67[24])|(75[06])|(86[2469])|(8(83|86|92|93))|(98[1289])|(99[145789])|(9(10|12|22|23|29|53|55|61|62))|((226|297|314|322|338|347|353|400|435|520|558|613|620|636|705|773|807|826|852|939|948))|(48)))|(\+1754(([234578])))|(\+1954(([23456789])))|(\+1786(([23456789])))|(\+1305(([23456789])))'

New-CSOutboundTranslationRule -Parent 'PstnGateway:miami.root.loc' -Name 'NA-FL-Miami-1-Local' -Description 'Removes +1 for local calls to Miami, FL' -Pattern '\+1((561((21[0238])|(2(06|08|37|39|41|45|87|88|89))|(36[1278])|(39[12345])|(3(00|02|05|72|78))|(44[2357])|(45[1678])|(4(16|17|70|77|79))|(5(04|05|44|49))|(67[24])|(75[06])|(86[2469])|(8(83|86|92|93))|(98[1289])|(99[145789])|(9(10|12|22|23|29|53|55|61|62))|((226|297|314|322|338|347|353|400|435|520|558|613|620|636|705|773|807|826|852|939|948))|(48)))|(754(([234578])))|(954(([23456789])))|(786(([23456789])))|(305(([23456789]))))' -Translation '$1'

Repeat for each gateway in your environment.  To check the results, use Lync Control Panel. Under Voice Routing - Route, you should see something like the following:

Auto-created routes are formatted like this NA-state-city-#.  For example, NA-TX-Dallas-1. If the route length is longer than 1024 characters (like Dallas), it has to be split into multiple routes, hence NA-TX-Dallas-2.

PSTN Usages should contain a PSTN Usage for each site, named like NA-state-city-Local
.  For example, NA-TX-Dallas-Local.  The PSTN Usage will contain all the routes for that particular city.

Finally, each PSTN gateway defined in Trunk Configuration should have at least one trunk normalization rule.  This rule will strip the +1 from the phone number before sending it to the PSTN gateway.

Drilling down into one of the trunks shows the translation rules for that particular trunk.

If you've selected the option to create 7-digit normalization rules, these rules will be placed in the Global dial plan in the format NA-state-city- Local Calls.  You should copy the rules to the appropriate dial plan.

One final step that's required to pull it all together is to assign the auto-created PSTN Usages to the appropriate Voice Policy.  Edit the voice policy/policies you want the Least Cost Routing to apply to, and add the PSTN Usages to those policies.  Commit the changes and you're done!

Now, when your users dial any number that is local to a defined city, the call will be routed out the appropriate PSTN gateway.  As long as you entered your email address, incorporating changes is as simple as re-applying the updated rules that are emailed to you to your Lync deployment. 

This post shows you how easy it is to configure Lync Server 2010 for Least Cost Routing.  Comments are always appreciated!

For more background on the Dialing Rule Optimizer, see this post.

Wednesday, October 13, 2010

Cross-Firewall File Transfer in Lync

In my "lab" environment, I'm running Lync Server 2010 RC in an existing OCS 2007 R2 corporate environment.  Since I didn't want to do anything that would impact the existing user population, I didn't make any unnecessary changes to the existing edge server environment.  So, I'm using our existing OCS 2007 R2 edge server to communicate with my Lync 2010 front-end. 

Since its not a full Lync 2010 environment from end to end, I expected certain Lync 2010 features would simply not work.  One of those long awaited features is the ability to transfer files between users who are on different firewalled networks.

In OCS 2007 R2 and older versions, people were often frustrated by the inability for Communicator to transfer files between users who were not on the same network.  File transfers worked peer-to-peer, and if the clients couldn't reach each other directly via their local IP address, then the file transfer would fail with a message like this:
You cannot receive the file ChuckNorrisFacts.doc from Chuck Norris.  This may be due to firewall restrictions or network problems. If you need further assistance, please contact your system administrator.
In Lync 2010, file transfers between users on disparate networks will work, because Lync 2010 is a lot smarter about finding a routable network path to the other party.  Lync will use ICE (Interactive Connectivity Establishment) and SDP (Session Description Protocol) to find a media path to send file data in much the same way that Communicator used ICE/SDP for voice/video traffic.  For an excellent description on how Communicator uses ICE/SDP, read this post by the Communications Server team.

I had assumed you would need to use the Lync client in conjunction with a Lync edge server for file transfer to work properly.  To my surprise, I found that a Lync edge server is NOT a required component.  The Lync client does all the ICE/SDP work to find a routable media path.  When either party is behind a firewall and can't be reached directly from the other user, Lync will use the existing OCS/Lync edge server to act as a proxy. 

I confirmed this by reviewing the Lync client logs on my machine.  By the way, its very handy to turn on logging in Lync.  It can be very useful when troubleshooting, or in this case, just trying to figure out how things are working.  Digging through the Communicator-uccaip-0.uccapilog file in my Tracing folder (they still haven't updated the names of the log files for Lync), I could see the following IP candidates offered by the other client just prior to the transfer:
a=candidate:1 1 TCP-PASS 2120613887 29884 typ host
a=candidate:1 2 TCP-PASS 2120613374 29884 typ host
a=candidate:2 1 TCP-ACT 2121006591 19511 typ host
a=candidate:2 2 TCP-ACT 2121006078 19511 typ host
a=candidate:3 1 TCP-PASS 6556159 57733 typ relay raddr rport 22533
a=candidate:3 2 TCP-PASS 6556158 57733 typ relay raddr rport 22533
a=candidate:4 1 TCP-ACT 7076607 57733 typ relay raddr rport 22533
a=candidate:4 2 TCP-ACT 7076094 57733 typ relay raddr rport 22533
I won't go into the details of each of these candidate lines because the Communications Server Team does such a great job explaining it, but the address is the internal address of the other user, while the address is the external AV edge IP address of my OCS 2007 R2 edge server.  You can see that several of the candidates are offering to use the AV edge IP address to relay the file transfer data from the other user's internal IP address.

So, to make a long story short, it appears that you won't have to wait to have a fully deployed Lync Server 2010 infrastructure to start taking advantage of the vastly improved file-transfer abilities in the Lync client.

Tuesday, October 5, 2010

Who says Microsoft doesn't have a sense of humour?

You know the default silhouette placeholder that Outlook 2010 and Lync 2010 shows you by default when there isn't a user picture?  You won't believe the story behind that...

Monday, October 4, 2010

Dialing Rule Optimizer and your Email Address

If you've used the Dialing Rule Optimizer to create localized dialing rules for your Audiocodes/Dialogic gateway or OCS/Lync, you may have noticed the option to enter your email address. The ONLY reason I use your email address is to automatically notify you when there have been changes in the dialing rules.  I will never sell or give your email address to anyone. 

As of right now, I do a monthly check for all those people who have entered their email address on the first of the month, and the program automatically sends them the updated rules.  For instance, this month I sent out updated rulesets to almost half of all the users who entered their email address.

Surprisingly, the local calling area for a given telephone exchange is updated on a pretty frequent basis, which means that your dialing rules could be out of date.  Your users might not be able to complete calls to newly added telephone exchanges. 

Allowing me to contact you via email is also handy for when I make changes in the logic to improve the rule generation process or to fix an error that may result in an incomplete ruleset.

On another note, if you ever find an error or inconsistency in the ruleset, PLEASE let me know so I can investigate.  Based on the lack of feedback so far, I can either assume that the program is working perfectly (which I'd like to think is the case), people are not validating the results, or they are simply tossing it out and not using it at all.

So, check out and use the Dialing Rule Optimizer, and enter your email address so you can stay up-to-date, and send me a note to give me some feedback  :)


Friday, October 1, 2010

Check your Exchange 2010 UM Dial Plans Before Upgrading to SP1

I thought I'd pass along my experience with some undocumented UM changes in Exchange 2010 SP1 that recently caused a client some grief. 

This particular client has made extensive use of UM dial plans and auto attendants, with it all tied in to a Cisco Call Manager telephony environment.  The way they configured their AAs wasn't done in a manner recommended by Microsoft.  Specifically, they didn't consistently assign Dialing Rule Groups to their AAs. 

If you're not familiar with Dialing Rule Groups, they are essentially groupings of dialing rules used to determine the types of calls that users can make when they make outgoing calls via Exchange UM.  For instance, you might have a dialing rule group that contains a set of rules that only allows local calls.  According to MS Best Practices, every dial plan and auto attendant should have at least one dialing rule group assigned to handle every possible combination of numbers it is expected to see.

The UM Dial Plans used by this client were almost exclusively set to 4 digits.  Many of the AAs had key mappings (ie Press 1 to reach Sales) that routed to 7-digit extensions.  There were no dialing rule groups in place on the AAs.  In Exchange 2007 and Exchange 2010 RTM, this didn't seem to matter.  The auto attendants always routed the calls properly.

However, once we put in SP1, all the auto attendants that routed calls to extensions with more than 4 digits failed.  Users would get to the main menu, press the button corresponding to the key mapping and get a message saying the call could not be completed, and the caller was returned to the main menu. 

After much sweating, hand-wringing and a call to MS Premier Support, we determined that we required a dialing rule group on each of the auto attendants that routed to 7-digit extensions.  Once done, calls were routed as before.

The Microsoft support rep said that the AAs should never have worked using the configuration this client had in place.  However, this client had successfully used this method in both Exchange 2007 and Exchange 2010 RTM.  It was only Exchange 2010 SP1 where this became an issue.  One way you could look at it is that Exchange 2010 SP1 corrected an logical oversight in previous versions.

So, in essense, make sure your dial plans and auto attendants are configured according to Microsoft's Best Practices BEFORE upgrading to Exchange 2010 SP1.