Haiku #182

All play and no work

Makes our blog quite successful.

Routing collections.

 

Here's an interesting piece of trivia for you. In August, 2011, the Lync Server PowerShell blog recorded a page view increase of slightly more than 20 percent. Why is that so interesting? Well, in July, 2011, the authors of the Lync Server PowerShell blogged worked every single day of the month; in August, 2011, the authors took off 10 days between the two of them. Not only that, but in August, 2011 there were actually 5 days in which there was no Lync Server PowerShell haiku of the day. And yet, page views increased dramatically during the month of August. Obviously the less we do, the more people like us.

 

And no, to be honest, that really didn't come as that big of a surprise.

 

At any rate, we're hoping to convince our managers to let us take 20 days off in the month of September. If page views go up again, we'll then try to convince them to let us take the entire month of October off. And if we can manage to take all of 2012 off, well, who knows what could happen: the Lync Server PowerShell blog might end up attracting more visitors than Facebook, YouTube, or I Can Has Cheezburger!

 

Well, OK. But more than Facebook or YouTube.

 

Incidentally, for those of you who compete in a fantasy Microsoft blogging league, in August, 2011 the Lync Server PowerShell blog was the 34th most-popular blog on TechNet (out of some 2,200 TechNet blogs). If you throw in the blogs found on MSDN, the Lync Server PowerShell blog ranked 84th out of 7,921 Microsoft blogs.

 

Note. You know, we wondered the same thing: there are thousands of blogs that rack up fewer page views than a blog whose primary selling point is a daily haiku about Lync Server PowerShell. How could that happen? Initially we assumed this success was due to all our hard work and dedication, but we eventually reached the same conclusion you did: it probably is just a mistake.

 

Mistake or not, however, August was a very successful month for us, and now that September is upon us our first thought was to kick the month off by giving everyone what they really want. However, our managers wouldn't let us take today off, so we decided to do the next best thing: we decided to talk about the CsStaticRoutingConfiguration cmdlets (Get-CsStaticRoutingConfiguration, New-CsStaticRoutingConfiguration, Remove-CsStaticRoutingConfiguration, and Set-CsStaticRoutingConfiguration).

 

Please hold your applause until the end of today's haiku. Thank you.

 

As the name kind of implies, static routing configurations are nothing more than a collection of static routes. And what are static routes? Well, when you send a SIP message that message will often have to travel across multiple subnets and networks before it can be delivered; the path traveled by the message is known as a route. In the wild and wonderful world of networking, there are two basic kinds of routes: dynamic routes and static routes. With dynamic routing, servers use algorithms to determine the next location (i.e., the next hop) where a message should be forwarded. With static routing, message paths are predetermined by system administrators. In the latter case, whenever a message is received by a server, the server checks the message address and then forwards the message to the next hop server that has been preconfigured by an administrator.

 

Admittedly, dynamic routes are easier to work with: after all, the server does all the work for you. On the other hand, and assuming that they have been configured correctly, static routes help ensure timely, and accurate, delivery of messages, and with minimal overheard placed on servers.

 

Note. The primary downside to static routes? Messages are not dynamically rerouted in the event of a network failure.

 

But, hey, who ever heard of a network failing, right?

 

At any rate, when you install Microsoft Lync Server a global static routing collection is created for you; however, that collection is empty. (In other words, it doesn't contain any routes.) If you want to actually add a route (or two or three or …) to that global collection (or to a custom collection you create yourself), you will need to do two things:

 

1. Create the route using the New-CsStaticRoute cmdlet.

2. Use the Set-CsStaticRoutingConfiguration cmdlet to add that route to a static routing collection.

 

We won't talk about the New-CsStaticRoute cmdlet today; for more information, see our haiku on that very topic. Suffice to say that you use a command similar to this to create a new static route, and store that route in a variable (in this example, a variable named $x):

 

$x = New-CsStaticRoute -TCPRoute -Destination "192.168.0.100" -Port 8025 -MatchUri "litwareinc.com"

 

So what exactly do we do with this static route? Well, let's assume we want to add this to our global collection. How do we do that? By running a command like this one:

 

Set-CsStaticRoutingConfiguration –Identity global -Route @{Add=$x}

 

All we've done here is call Set-CsStaticRoutingConfiguration and ask the cmdlet to add the new route to the global collection. To do that, we use the Route parameter and the following syntax:

 

@{Add=$x}

 

OK, so maybe that is odd-looking syntax. But odd or not, that's standard PowerShell syntax for adding an object to a property (Route) that can contain multiple properties. The key here is to use the Add method, which tells PowerShell to add the new route to any existing routes in the collection. For example, suppose our collection currently contains one route:

 

Identity : Global

Route : {MatchUri=contoso.com;MatchOnlyPhoneUri=False;Enabled=True;  

           ReplaceHostInRequestUri=False}

 

After we run the Set-CsStaticRoutingConfiguration cmdlet this same collection will now have two routes:

 

Identity : Global

Route : {MatchUri=contoso.com;MatchOnlyPhoneUri=False;Enabled=True;  

           ReplaceHostInRequestUri=False, MatchUri=litwareinc.com;

           MatchOnlyPhoneUri=False;Enabled=True;

           ReplaceHostInRequestUri=False}

 

Why do we have two routes? You got it: because we had 1 route in the collection and now we've added 1 more route to that collection. And 1 + 1 is – well, we'll let you do the math on that one.

 

Ah, good question: suppose our original route is no longer valid, and we need to replace it with the new route. Can we do that? Sure; all we have to do is use the Replace method:

 

Set-CsStaticRoutingConfiguration –Identity global -Route @{Replace=$x}

 

That will remove every single route in the collection (even if that collection has a million routes in it) and replace it with the route stored in $x. In other words, now our collection will look like this:

 

Identity : Global

Route : {MatchUri=litwareinc.com; MatchOnlyPhoneUri=False; Enabled=True;

           ReplaceHostInRequestUri=False}

 

That was easy, wasn't it?

 

Note. Sure, you can add multiple routes in a single command; all you have to do is have multiple variables, each containing a unique route. If you do, then you can add multiple routes by running a command like this:

 

Set-CsStaticRoutingConfiguration –Identity global -Route @{Add=$x,$y,$z}

 

What isn't so easy (or at least isn't very intuitive) is how you remove a route from a collection. Suppose we have a two-route collection once again:

 

Identity : Global

Route : {MatchUri=contoso.com;MatchOnlyPhoneUri=False;Enabled=True;  

           ReplaceHostInRequestUri=False, MatchUri=litwareinc.com;

           MatchOnlyPhoneUri=False;Enabled=True;

           ReplaceHostInRequestUri=False}

 

How do we remove just the contoso.com route? Well, it's a tiny bit kludgy, but what you need to do is create an object reference to the contoso.com route and then use that object reference when deleting the route. How do you create an object reference to a route? The easiest way is to use the Get-CsStaticRoutingConfiguration cmdlet, like so:

 

$x = Get-CsStaticRoutingConfiguration -Identity global | Select-Object -ExpandProperty Route | Where-Object {$_.MatchUri -eq "contoso.com"}

 

What we've done here is use Get-CsStaticRoutingConfiguration to retrieve our global collection of static routes. We then pipe that collection to the Select-Object cmdlet, and use the ExpandProperty parameter to enable us to access the individual routes stored in that collection. We then use the Where-Object cmdlet to return the route that has a MatchUri equal to contoso.com. That route then gets stored in the variable $x.

 

That's a bit of a hassle, but once we actually have that route we can then use the Remove method to remove that route from the collection:

 

Set-CsStaticRoutingConfiguration –Identity global -Route @{Remove=$x}

 

It's weird, but it works.

 

Note. And what if you want to remove all the routes from a collection? That's actually pretty easy: just set the Route property to a null value:

 

Set-CsStaticRoutingConfiguration –Identity global -Route $Null

 

As for the other members of the CsStaticRoutingConfiguration family, well, New-CsStaticRoutingConfiguration lets you create a new collection of static routes, albeit only at the service scope (and only for the Registrar service). For example:

 

New-CsStaticRoutingConfiguration -Identity "service:Registrar:atl-cs-001.litwareinc.com"

 

And if you later want to remove that collection? Ladies and gentlemen, may we introduce the Remove-CsStaticRoutingConfiguration cmdlet:

 

Remove-CsStaticRoutingConfiguration -Identity "service:Registrar:atl-cs-001.litwareinc.com"

 

Finally, the Get-CsStaticRoutingConfiguration cmdlet enables you to return information about your existing static route collections. And, while we're on the subject, we have a confession to make: in order to help you visualize what the CsStaticRoutingConfiguration cmdlets actually do, we took the liberty of prettying up the data returned by Get-CsStaticRoutingConfiguration. For example, we showed you output that looked like this:

 

Identity : Global

Route : {MatchUri=contoso.com;MatchOnlyPhoneUri=False;Enabled=True;  

           ReplaceHostInRequestUri=False, MatchUri=litwareinc.com;

           MatchOnlyPhoneUri=False;Enabled=True;

           ReplaceHostInRequestUri=False}

 

In reality, however, the output looks more like this:

 

Identity : Global

Route : {MatchUri=contoso.com;MatchOnlyPhoneUri=False;Enabled=True;Repla

           ceHostInRequestUri=False, MatchUri=litwareinc.com;MatchOnlyPhoneU

           ri=False;Enabled=True;ReplaceHostInRequestUri=False}

 

That's a bit harder to read.

 

Note. No, you can't sue us for prettying up the output of Get-CsStaticRoutingConfiguration.

 

At least not as far as we know.

 

But fear not: here's a way to get much, much more readable output from Get-CsStaticRoutingConfiguration:

 

Get-CsStaticRoutingConfiguration –Identity global | Select-Object –ExpandProperty Route

 

And what kind of output will that command get you? This kind of output:

 

Transport : TransportChoice=IPAddress=192.168.0.100;Port=8025

MatchUri : litwareinc.com

MatchOnlyPhoneUri : False

Enabled : True

ReplaceHostInRequestUri : False

 

Transport : TransportChoice=IPAddress=172.168.0.100;Port=8025

MatchUri : contoso.com

MatchOnlyPhoneUri : False

Enabled : True

ReplaceHostInRequestUri : False

 

That's about all we have for today. See you tomorrow!

 

Note. We know, we know. But how do you think we feel about that?