Haiku #159
We can rebuild it.
We have the technology.
Policy entries.
Well, it's Monday, and we're back after another typical Pacific Northwest weekend. What's a typical Pacific Northwest weekend, you ask? Well, a typical Pacific Northwest weekend somehow manages to combine the really good with the really bad. For example, this past weekend the author of today's haiku and his wife went down to Portland to visit his brother-in-law and his brother-in-law's girlfriend. The really good part of that? Well, they got to watch the brother-in-law's girlfriend perform in the play Boeing, Boeing, and absolutely steal the show as Gretchen, the … assertive … German "air hostess." And, with the sun shining and the temperature near 90 degrees (!), they also got to hike the Angel's Rest trail, 2.6 miles long, 1,500 feet in elevation gain. And absolutely killer views once you reach the top.
And the really bad? How about this: it took nearly 6 hours to make the 180-mile trip home. During one memorable hour-long, traffic-filled stretch, the family traveled almost 12 miles. That's practically 12 miles an hour!
Which as anyone who has traveled the freeways around here knows, really isn't all that bad.
And now we're back at work, which also somehow manages to combine the really good with the really bad. The really bad? Well, perhaps you didn't catch it the first time around, but we are back at work. And the really good? Today we're going to talk about the New-CsClientPolicyEntry cmdlet.
Note. Oh, and after having to deal with temperatures in the high 80s yesterday, today the current temperature is 59 degrees, it's overcast, and the author of today's haiku keeps hearing thunder off in the distance. Thank goodness we no longer have to deal with that nice weather!
So what about the New-CsClientPolicyEntry cmdlet? Well, the New-CsClientPolicyEntry cmdlet provides a way for you to extend your client policies, to add management capabilities that aren't included among the default properties of a client policy. Now, before you get too excited about this – wow, does this mean I can add anything to a client policy?!? – we need to qualify this a little: this doesn't mean that you can add anything to a client policy. Instead, you'll need to wait for Microsoft to tell you what you actually can and cannot add to a client policy.
You say you need an example of that? Well, at the moment we only know of one example: the ability to add an entry to your client policies that enables or disables the collecting of Microsoft Lync diagnostic logs. We won't bother to explain what it means to enable or disable the collecting of diagnostic logs; that's something we've already covered in a previous article. What we will do, however, is show you how you can add this entry to a client policy. And speaking of which, here's how you can add this entry to a client policy:
$x = New-CsClientPolicyEntry -Name EnableDiagnosticsLogsCollection -Value 1
Set-CsClientPolicy –Identity global –PolicyEntry @{Add=$x}
As you can see, there's nothing too terribly complicated about this. In our first command, we call the New-CsClientPolicyEntry cmdlet along with two parameters: Name and Value (which are the only two parameters available for this cmdlet). The Name parameter is simply the name of the property being added (EnableDiagnosticsLogsCollection) and the Value parameter is, well, the value assigned to that property. In this case the value 1 enables diagnostic log collecting and the value 0 disables diagnostic log collecting.
Note. So where did we get this name and value from in the first place? You got it: that information was released by the Microsoft Lync Server product team. You can put any name and any value you want into a client policy, but those names and values won't actually do anything. The name EnableDiagnosticsLogsCollection and the value 1 let you manage log collections because Microsoft Lync and Microsoft Lync Server have been architected to know what to do when those items show up in a client policy.
At any rate, our new client policy entry is stored in a variable named $x, then is added to the PolicyEntry property using this command:
Set-CsClientPolicy –Identity global –PolicyEntry @{Add=$x}
And what does our global client policy look like now? It looks something like this:
Identity : Global
PolicyEntry : {Name=EnableDiagnosticsLogsCollection;Value=1}
Description :
AddressBookAvailability : WebSearchAndFileDownload
AttendantSafeTransfer :
AutoDiscoveryRetryInterval :
And you're right: if we'd only thought to bring the New-CsClientPolicyEntry cmdlet with us those six hours in the car would have seemed like six minutes. Next time we'll pack a little smarter.
Ah, good question: what if you did have a second client policy entry you wanted to add (one that we've stashed in a variable named $y)? That's no problem; you can add multiple entries in a single command:
Set-CsClientPolicy –Identity global –PolicyEntry @{Add=$x,$y}
In other words, suppose we did this:
$x = New-CsClientPolicyEntry -Name Test1 -Value 1
$y = New-CsClientPolicyEntry -Name Test2 -Value 2
Set-CsClientPolicy -PolicyEntry @{Add=$x,$y}
That will give us a client policy that looks something like this:
Identity : Global
PolicyEntry : {Name=Test1;Value=1, Name=Test2;Value=2}
Description :
AddressBookAvailability : WebSearchAndFileDownload
AttendantSafeTransfer :
What's that? You say you don't actually want policy entries $x and $y? You say that what you really wanted to do was replace $x with $y? That's fine; just use the Replace method, like so:
Set-CsClientPolicy -PolicyEntry @{Replace=$y}
Or how about this: you currently have a policy that includes a pair of entries (Test1 and Test2) and you'd like to remove just Test1, leaving Test2 as-is. Can you do that?
Of course you can. It's just, alas, a tiny bit clunky.
What do we mean by that? Well, you can't remove a policy entry just by specifying the name; for example, by using a command similar to this one:
Set-CsClientPolicy -PolicyEntry @{Remove="Test1"}
The Remove method is the correct method to use, but the PolicyEntry parameter can only work with instances of the Microsoft.Rtc.Management.WritableConfig.Policy.Client.PolicyEntryType class. A plain old string value (like Test1) is just going to result in an error message:
Set-CsClientPolicy : Unable to cast object of type 'System.String' to type 'Microsoft.Rtc.Management.WritableConfig.Policy.Client.PolicyEntryType'.
So how do you get around that problem? There are two possibilities. For one, you can create a new policy entry object identical to the entry to be removed; you can then use that variable as the value passed to the Remove method. In other words:
$x = New-CsClientPolicyEntry -Name Test1 -Value 1
Set-CsClientPolicy -PolicyEntry @{Remove= $x}
It's kind of any odd thing to do – to remove something, first create a second instance of that something – but it works.
The other way is to go down this path:
$z = Get-CsClientPolicy -Identity global
$z.PolicyEntry.RemoveAt(0)
Set-CsClientPolicy -Instance $z
What's going on here? Well, the PolicyEntry property stores individual policy entries in an array. Items in an array are always given an index number: the first item in the array is item 0, the second item in the array is item 1, and so on. What we're doing here is first using the Get-CsClientPolicy cmdlet to create an object reference to the global client policy. We then use the RemoveAt method to remove the array item with the index number 0:
$z.PolicyEntry.RemoveAt(0)
And then, finally, we use the Set-CsClientPolicy cmdlet and the Instance parameter to write the changes back to Lync Server:
Set-CsClientPolicy -Instance $z
Like we said, it's a little clunky. But it also works.
And there you have it: the New-CsClientPolicyEntry cmdlet. That's the really good news for today. The really bad news? You know, come to think of it, it's Monday, the sun isn't shining anymore, and we're back at work. Looks like there isn't any really bad news today after all!
See you tomorrow.