Haiku #168
Published May 20 2019 03:53 PM 173 Views
Occasional Visitor
First published on TECHNET on Aug 05, 2011

What? There's a haiku

Hiatus?!? Good thing there are

Voicemail policies.

We apologize for this, but we need to begin today's haiku with a little bad news: this is probably going to be the last daily Lync Server PowerShell haiku until Wednesday, August 10 th .

Note . Wow: that's the first standing ovation we've ever received.

As it turns out, beginning bright and early Monday morning (or at least early Monday morning; seeing as how this is the Seattle area we can't promise it will be very bright) the authors of today's haiku will clamber into the car and begin their long and perilous journey to the mountains on Utah, the Beehive State.

Note . So-called because bees represent the "… pioneer virtues of thrift and perseverance." That's not the greatest state nickname, but it's also not the worst. For that we'd have to vote for Louisiana, the Pelican State. Early settlers were impressed by the brown pelicans found all along the coast of Louisiana, so impressed that, by 1960, pesticides had killed off all the pelicans and the state had to import a new batch of brown pelicans from Florida (the Sunshine State).

At any rate, the author of today's haiku will be in Utah for a month or so, but have no fear: as this is part vacation and part just working from a remote location, there will definitely be a new haiku on Wednesday, and on most days thereafter. Needless to say, we take our responsibilities as haiku writers extremely seriously.

That's an interesting question: seeing as how the Beehive State is swarming with mountain bike trails, hiking trails, and canoeing/kayaking venues, what are the odds that the author of today's haiku really will do some work while he's gone? Well, to be honest, the odds are that – you know what? This is supposed to be the daily Lync Server PowerShell haiku, which means we shouldn't be talking about personal matters. Instead, we should be talking about the CsHostedVoicemailPolicy cmdlets: Get-CsHostedVoicemailPolicy , Grant-CsHostedVoicemailPolicy , New-CsHostedVoicemailPolicy , Remove-CsHostedVoicemailPolicy , and Set-CsHostedVoicemailPolicy .

To begin with, we should probably note that it's entirely possible that you will never need to use the CsHostedVoicemailPolicy cmdlets. Why not? Well, these cmdlets are only used if you have to integrate Lync Server with a hosted (i.e., "in the cloud") version of Microsoft Exchange. If you run your own on-premises version of Exchange, well, then you don't need to worry about the CsHostedVoicemailPolicy cmdlets.

Ah, but what if you do have users with accounts on a hosted version of Exchange? Well, in that case, the CsHostedVoicemailPolicy cmdlets enable you to specify how voicemails are to be routed to that hosted version of Exchange unified messaging. And how do you do that? It's actually pretty easy: you simply need to specify the full qualified domain name of the hosted service (the Destination property) as well as a list of all the tenant FQDNs used to host your user mailboxes (the Organization property).

For example, suppose you've contracted with ExUM.contoso.com to host your Exchange users, and that service provider has assigned you the tenant ID mail1.litwareinc.com. Here's how you would configure your global hosted voicemail policy:

Set-CsHostedVoicemailPolicy -Identity global -Destination "ExUM.contoso.com" –Organization "mail1.litwareinc.com"

See? That's pretty easy. You say you've actually been assigned two tenant IDs? That's fine. The Organization parameter can accept multiple IDs; you just need to pass those multiple IDs in the form of a comma-separated list:

Set-CsHostedVoicemailPolicy -Identity global -Destination "ExUM.contoso.com" –Organization "mail1.litwareinc.com,mail2.litwareinc.com"

Note . This, by the way, explains why the author of today's haiku probably can get some work done while in Utah: Lync Server PowerShell makes "work" like this incredibly easy.

Suppose you need to later add a third tenant ID? Well, because the Organization property is just a single string value (as opposed to an array of values) adding (or removing) a single value can be a little quirky. But here are commands that add a new tenant ID:

$x = (Get-CsHostedVoicemailPolicy -Identity global).Organization

$x += ",mail3.litwareinc.com"

Set-CsHostedVoicemailPolicy -Identity global -Organization $x

What we've done here is use the Get-CsHostedVoicemailPolicy cmdlet to retrieve the global policy; we've put that command in parentheses because we want to retrieve the policy and then take just the value of the Organization property and store it in a variable named $x. At the moment, that means $x is equal to this:


In the second command, we use PowerShell's += operator to add the string value ",mail3.litwareinc.com" to the tail end of $x. (Note the comma in front of the tenant ID. We need that because this has to be a comma-separated list.) At this point, $x will be equal to this:


And then, finally, the third command uses the Set-CsHostedVoiceMailPolicy cmdlet to set the value of the Organization property to $x:

Set-CsHostedVoicemailPolicy -Identity global -Organization $x

It's a little cumbersome, but it works.

And what if you want to remove a tenant ID? We were afraid someone would ask that. Well, although there are probably a zillion better solutions out there, this approach will do the trick:

$x = (Get-CsHostedVoicemailPolicy -Identity global).Organization

$x = $x –replace("mail2.litwareinc.com","")

$x = $x –replace(",,",",")

$x = $x –replace("^,|,$","")

Set-CsHostedVoicemailPolicy -Identity global -Organization $x

Pretty straightforward and intuitive, eh? But don't worry: we'll try to explain what's going on here. As you can see, we started out by grabbing the value of the Organization property and then storing it in a variable named $x. That means $x is equal to this:


So far so good. Next, we use PowerShell's –replace operator to replace the string value mail2.litwareinc.com with, well, nothing (""). After we run that second command, $x will be equal to this:


As you can see, we got rid of mail2.litwareinc.com . However, we still have a problem: we have dual commas in the middle of our string:

mail1.litwareinc.com ,, mail3.litwareinc.com

In order to replace those two commas with a single comma we use this command:

$x = $x –replace(",,",",")

You know, that is pretty weird-looking. But it does make $x equal to this:



Well, at least in this case. However, depending on which tenant ID we deleted, and depending on the number of tenant IDs we have, we could also be left with a string value that looks like either one of the following:



As you can see, in one case we have an extraneous comma at the beginning of the string, and in the other case we have an extraneous comma at the end of the string. What the heck do we do about that ?

Well, calling upon our own sense of thrift and perseverance, and calling upon PowerShell's ability to handle regular expressions, we run this command:

$x = $x –replace("^,|,$","")

This command looks for two things. It looks for a comma at the very beginning of a string; that's what the ^, syntax is for. Alternatively, it looks for a comma at the end of a string; that's what the ,$ syntax represents. If it finds either of those extraneous commas then the command deletes them (or, more properly, replaces them with nothing).

Note . What's the | in the middle of the string for? That's a regular expression operator that simply means "or." In other words, find a comma at the beginning of the string (^,) or (|) find one at the end of the string (,$).

And then, as usual, we use Set-CsHostedVoicemailPolicy to write those changes back to the global policy.


That's really the heart and soul of the CsHostedVoicemailPolicy cmdlets. As you might expect, you can use Get-CsHostedVoicemailPolicy to return information about your hosted voicemail policies, and Remove-CsHostedVoicemailPolicy to remove any of those policies. And, of course, you can also use New-CsHostedVoicemailPolicy to create new policies at the site or the per-user scope. However, that's another cmdlet that you might never find yourself using, even if you do use hosted Exchange. Why not? Well, most places that use hosted Exchange have all their accounts hosted by the same provider, which means that all those accounts have the same Destination. You only need to create additional voicemail policies if you have multiple providers or it, for some reason, your provider has given you multiple Destinations.

Oh, and let's not forget poor, neglected Grant-CsHostedVoicemailPolicy. As usual, if you create a new policy at the per-user scope you'll need to specifically assign that policy to users. That's where Grant-CsHostedVoicemailPolicy comes in:

Grant-CsHostedVoicemailPolicy -Identity "Ken Myer" -PolicyName ExRedmond

Etc., etc.

That's all we have for today; we'll be back with a new haiku on Wednesday. Is it humanly possible for anyone to go that long without reading a Lync Server PowerShell haiku? To tell you the truth, we don't think so. But don't worry: you can always go through the archive and re-read all your old favorites. That should keep you busy until Wednesday.

Version history
Last update:
‎May 20 2019 03:53 PM
Updated by: