Haiku #185

I only have eye

Lashes for you. And for you,

Outbound translations.

 

If you're like most people then each and every morning, as you climb into your car and prepare to go to work, you think, "You know, this car is pretty good: it runs well, I've never had any problems with it, and it gets awfully good gas mileage. And yet still, I don't think I'll ever be able to look past its one major flaw: my car doesn't have eyelashes."

 

You've been there before, haven't you? Well, so has the author of today's haiku, and he got so desperate that he actually decided to trade in his current car and get a new one, a new one that had eyelashes. Unfortunately, though, he couldn't find a car that had eyelashes; apparently they sell out so quickly that the dealers can't even keep them on the lot. Disappointed? That's putting it mildly.

 

At any rate, the author of today's haiku had resigned himself to never having a car with eyelashes, or at least he had resigned himself to that until he attended the recent Miner's Day Parade in Park City, UT.

 

Note. Incidentally, the name is correct: the celebration is, indeed, called Miner's Day. Apparently that's to honor one single, solitary miner, although we aren't sure which one.

 

Like most people, the author of today's haiku assumed that the highlight of the parade would be the dancing bowling pin. (Obviously.) As it turned out, however, there was something even better than the dancing bowling pin: cars with eyelashes! Even better, these weren't high-priced custom cars that only a Tom Cruise or a George Clooney could afford: these were regular old cars tricked out with carlashes, carlashes that just about anyone can afford!

 

Note. If you're wondering what in the world we're talking about, well, what else is new? However, if you're wondering what the heck a carlash actually is, well, take a gander at some of these photos. Although, to be honest, you have to see the things in person to truly appreciate what it means to put eyelashes on your car.

 

Of course, after learning that you can buy eyelashes for your car, your next question is undoubtedly going to be this: can I also buy eyelashes for my Lync Server PowerShell cmdlets? Sadly, the answer is no; in fact, you can't buy any accessories for any of the Lync Server PowerShell cmdlets. But that's OK; we like to believe that our cmdlets stand on their own, without the need for gaudy accessories.

 

Give you an example? OK; what about the CsOutboundTranslationRule cmdlets (Get-CsOutboundTranslationRule, New-CsOutboundTranslationRule, Remove-CsOutboundTranslationRule, and Set-CsOutboundTranslationRule)? You can't buy eyelashes for the CsOutboundTranslationRule cmdlets, nor can you buy handbags, scarves, earrings, or anything else that might jazz up the appearance of the CsOutboundTranslationRule cmdlets. On the other hand, you can use the CsOutboundTranslationRule cmdlets to create outbound translation rules, rules that can turn an E.164-formatted phone number used by Microsoft Lync to a phone number format used by your PBX (private branch exchange) system. And we'd like to see any car be able to do that, eyelashes or no eyelashes!

 

Well, OK, maybe Volvos. But other than that, we don't know of any cars that can create outbound translation rules.

 

So what did we say that outbound translation rules were again? Well, as you know, any time you make a phone call using Microsoft Lync Server the phone number you call gets translated to the E.164 format. For example, when you call the local Seattle phone number 555-1219, that number gets translated to this:

 

+12065551219

 

In that translated number, the first 1 represents the country code (US), the 206 represents the area code for Seattle, and the 5551219 represents the phone number itself.

 

So what's wrong with that? Nothing. Well, actually, one thing: not all PBX systems recognize the E.164 format. If your PBX system doesn't understand E.164, then you're going to have to convert that E.164 number to a phone number that the PBX system does understand. And that's the reason we need outbound translation rules.

 

Note. And why do we need eyelashes for our cars? Because – well, just because.

 

Let's show you a simple example of what we mean. First, let's show you a command that creates an outbound truncation rule:

 

New-CsOutboundTranslationRule -Parent global -Name SeattleSevenDigit -Description "Convert to seven digits" -Pattern '^\+1206(\d{7})$' -Translation '$1'

 

There are two parameters of primary importance here: Pattern and Translation. The Pattern parameter describes the pattern we want to match. In this case, we want to capture local phone numbers that are dialed without using the country code or area code; in other words, local numbers dialed like this:

 

5551219

 

As we've already seen, Lync Server (probably using voice normalization rules you created earlier) will convert that dialed number into an E.164 number:

 

+12065551219

 

Note. We won't explain the regular expression used to do this, at least not in any detail. Essentially, though, the regular expression ^\+1206(\d{7})$ takes a seven-digit number and tacks a plus sign (+), a country code (1), and an area code (206) to the front of that number.

 

Of course, the problem with that is that our PBX system doesn't understand E.164 numbers. Therefore, we need to convert that number to a number that the PBX system does understand. In this simple example, we're assuming the PBX system can handle a number like 5551219. Therefore, we simply translated the E.164 number back to the number originally dialed: 5551219. (In a regular expression, the symbol $1 essentially means, "Use the original value."

 

As long as we're on the subject, it's important that you surround the Pattern and the Translation values with single quote marks: '$1'. If you use double quote marks around the value (or no quote marks) you'll get an error message like this:

 

New-CsVoiceNormalizationRule : Cannot create item "Global/SeattleSevenDigit": "Value cannot be null.

Parameter name: value"

 

Why? Well, in a case like that (e.g., "$1"), PowerShell is trying to use the value of a variable named $1. Most likely you don't have a variable named $1, which means you're trying to assign a null value to the Translate parameter. In turn, that means you're trying to convert the E.164 phone number into nothing. And very few PBX systems know how to dial nothing.

 

By contrast, when you enclose $1 in single quotes, Windows PowerShell uses the literal value: $1. In other words, your finished rule will have these property values:

 

Identity : Global/SeattleSevenDigit

Priority : -1

Description : Convert to seven digits

Pattern : ^\+1206(\d{7})$

Translation : $1

Name : SeattleSevenDigit

 

If that doesn’t make much sense, well, for the time being at least, just use single quotes and don’t worry too much about it.

 

And what if you PBX system requires the area code, even for local numbers? That's fine: just include the 206 in your translation. In other words:

 

New-CsOutboundTranslationRule -Parent global -Name SeattleSevenDigit -Description "Convert to seven digits" -Pattern '^\+1206(\d{7})$' -Translation '206$1'

 

The Translation 206$1 simply says, "Dial 206 followed by the number the user actually dialed (that is, $1)."

 

It’s like child's play … well, assuming that you were a pretty smart child.

 

That, in a nutshell, is how outbound translation rules work, and how the New-CsOutboundTranslationRule cmdlet works. We won't spend a lot of time talking about the remaining cmdlets in the CsOutboundTranslationRule: you can probably guess what Get-CsOutboundTranslationRule, Remove-CsOutboundTranslationRule, and Set-CsOutboundTranslationRule do. One thing that we will note, however, is the Priority parameter, a parameter found on both New-CsOutboundTranslationRule and Set-CsOutboundTranslationRule. It's possible that – depending on your setup – a dialed number could meet more than one translation rule. If so, the Priority parameter lets you specify which rule gets applied first. By default, the first translation rule you create is assigned priority 0, the second rule is assigned priority 1, and so on:

 

Rule

Priority

Global/Rule1

0

Global/Rule2

1

Global/Rule3

2

 

Now, suppose you'd prefer that Rule3 have the highest priority. In that case, you can just use the Set-CsOutboundTranslationRule cmdlet to change the Priority for that rule:

 

Set-CsOutboundTranslationRule -Identity "global/Rule2" –Priority 0

 

Do that, and Rule3 will now have the highest priority, and the other rules will have their priorities adjust accordingly:

 

Rule

Priority

Global/Rule3

0

Global/Rule1

1

Global/Rule2

2

 

We doubt that even a Volvo could do that.

 

That's about all we have time for today. As you might expect, outbound translation rules have the potential to get a bit complicated, especially if you try to apply least-cost routing. If that's of interest to you, you might check out a very cool online utility that can do least-cost calculations (and create outbound translation rules) for you. It's a pretty slick little tool, although we were a little disappointed that it wouldn't write today's haiku for us. Maybe in the next version.

 

Oh, and speaking of what's coming next, here's what's coming next: lips for your car. Hey, we couldn't make up something like that even if we wanted to.

 

See you tomorrow.