Simultaneously Assigning a Policy to Multiple Users

Trying to pick your favorite feature in Microsoft Lync Server 2010 PowerShell is like trying to pick your favorite episode of The Simpsons: there are so many good ones to choose from that it simply can't be done.


Note. Actually, it can be done: Simpsoncalifragilisticexpiala(Annoyed Grunt)cious. The problem is getting everyone in the family to agree that this is the best episode ever. For example, one family member continues to hold out for Homer at the Bat (admittedly a great episode). Meanwhile, and for reasons known only to himself, Uncle Chuck still votes for Lisa Get an A, the Pinchy the Lobster episode.


Hey, you try talking to Uncle Chuck. We've given up on that.


We have to admit that, when it comes to Lync Server PowerShell, one of our favorite features is this: the fact that it's so easy to assign policies to a specific set of users. (And no, we haven't asked Uncle Chuck what his favorite feature of Lync Server PowerShell is. We don't want to open another can of worms.) For example, suppose you want to assign the same client policy (ITClientPolicy) to all the users in the IT department. That's fine; this command will do the trick:


Get-CsUser –LdapFilter "Department=IT" | Grant-CsClientPolicy –PolicyName "ITClientPolicy"


Or maybe you'd like to assign the same client policy to all the users who have been enabled for Enterprise Voice. To quote Ned Flanders, okely-dokely:


Get-CsUser –Filter {EnterpriseVoiceEnabled –eq $True} | Grant-CsClientPolicy –PolicyName "EnterpriseVoiceClientPolicy"


We could go on and on like this (and we have; see the article Retrieving Active Directory and Microsoft Lync Server 2010 User Accounts for more information) but you get the idea: if users have something in common (a job title, a department, a Registrar pool, whatever) it's very easy to write a command that can retrieve all those users and assign them a policy.


As well it should be.


But what happens if you have a bunch of users who don't have anything in common? For example, suppose you're doing some sort of pilot testing and you need to assign the same policy to 15 users chosen at random. These users don't necessarily have anything in common: they don't belong to the same department, they don't all use the same dial plan, they haven't all been enabled for Enterprise Voice. And even if they did have something in common, you might not want to run a command like this one anyway:


Get-CsUser –LdapFilter "Department=IT" | Grant-CsClientPolicy –PolicyName "TestClientPolicy"


Why not? You got it: because that command will assign TestClientPolicy to all the users in the IT department, not just the 15 users who were chosen at random.


That's right: bummer.



Before you ask, no, a command like this one (which tries to assign the same policy to two users) isn't going to work:


Grant-CsClientPolicy –Identity "Ken Myer","Pilar Ackerman" –PolicyName "TestClientPolicy"


Instead, you're just going to get an error message like this:


Grant-CsClientPolicy : Cannot convert 'System.Object[]' to the type 'Microsoft.Rtc.Management.AD.UserIdParameter' required by the parameter 'Identity". Specified method is not supported.


Which simply means this: we tried the pass an array of user IDs to the Identity parameter (in PowerShell, the symbol [] means we're dealing with an array) and the Identity parameter can handle only one user ID at a time. Therefore, the command failed.


That's right: bummer. Again.


So does that mean you're going to have to write 15 individual commands, one for each user, in order to get these policies assigned? That is, 15 commands like these:


Grant-CsClientPolicy –Identity "Ken Myer" –PolicyName "TestClientPolicy"

Grant-CsClientPolicy –Identity "Pilar Ackerman" –PolicyName "TestClientPolicy"


Well, that will definitely work, and if you use a little copying and pasting it won't be too terribly tedious. However, there is another way:


"Ken Myer","Pilar Ackerman" | Grant-CsClientPolicy –PolicyName "TestClientPolicy"


As it turns out, you can pipe multiple user Identities to the Grant-Cs cmdlets: all you have to do is provide a comma-separated list of Identities. Our example only pipes a pair of user IDs, but we can pipe a whole passel of IDs if we want to:


"Ken Myer","Pilar Ackerman","Mike Nash","Sheela Word","Terry Adams","Ye Xu","Dag Rovik" | Grant-CsClientPolicy –PolicyName "TestClientPolicy"


Etc., etc.


Oh, and if you have these user Identities in a text file, well, then things get even easier. For example, suppose we have a text file (C:Users.txt) similar to this one:


Ken Myer

Pilar Ackerman

Mike Nash

Sheela Word


Ye Xu

Dag Rovik


How do we assign all these people the same client policy? Like this:


Get-Content –Path C:Users.txt | Grant-CsClientPolicy –PolicyName "TestClientPolicy"


In this command, we first use the Get-Content cmdlet to read all the user IDs from the text file. Get-Content will not only read the file, but it will also automatically place all those IDs in an array. We can then pipe that array to the Grant-CsClientPolicy cmdlet, which will assign TestClientPolicy to each user.


Definitely not a bummer. If you have a random assortment of users who should all be assigned the same client policy, then just pipe all those Identities to the Grant-CsClientPolicy cmdlet and you're done.


Ah, that's a good question: how do you know if a cmdlet will accept pipelined input like this? (That's a good question because not all cmdlets do accept pipelined input.) Well, trial and error is one way to find out. A better way, though, is to check the help topic for a cmdlet:


Get-Help Grant-CsClientPolicy –Full | more


What you want to do here is check for two things. First, see what's listed under the INPUTS section. For Grant-CsClientPolicy, you'll see this:


String value or Microsoft.Rtc.Management.ADConnect.Schema.ADUser object. Grant-CsClientPolicy accepts pipelined input of string values representing the Identity of a user account. The cmdlet also accepts pipelined input of user objects.


Although that's written in our standard technical writing gobbledygook, this does tell you that you can pipe string values (like "Ken Myer") that represent user Identities to the Grant-CsClientPolicy cmdlet. You can also look at the individual cmdlet parameters to see if they support pipelined input. Here's what's listed for the Identity parameter:


Required?                     True

Position?                     1

Default value

Accept pipeline input?        True

Accept wildcard characters? False


If the Identity parameter accepts pipelined input that means that, well, you can pipeline input to that parameter. Which is what we just did.


Admittedly, being able to pipe a bunch of "random" user Identities to a cmdlet might not be as good as the classic Cape Feare episode. But it's awfully close.


Awfully close.


Comments (2)
  1. bkwins says:

    My vote for best Simpsons episode will have to go to Trilogy of Error.

    "This plot made no sense! Tell the people!"

    Best episode ever.

    No opinion yet on best Lync feature, btw.

  2. Greg Stemp says:

    My conscience won't allow me to call Triology of Error the best episode error. But I AM a big fan of this part of the episode:

    "Linguo? Dead?"

    "Linguo IS dead."

Comments are closed.

Skip to main content