How to Undo That Thing You Now Wish You Had Never Done in the First Place


Although we can't guarantee this, we can pretty much guarantee this: once you've switched to Microsoft Lync Server 2010 you'll never have nightmares again. Or, at the very least, you'll never have nightmares about Microsoft Lync Server again. Ever.

 

Note. A strong statement? Perhaps. On the other hand, Sigmund Freud is universally acknowledged as history's foremost authority on dream studies and dream interpretation. Before writing this article, we carefully read everything Freud ever wrote. Do you know how many references to Lync Server nightmares we found in the collected works of Sigmund Freud? That's right: zero.

 

Of course, even as you're sitting back reading this article you can probably think of at least one or two potential Lync Server nightmare scenarios. For example, consider this. Your organization has 105 users who have been enabled for Lync Server. In turn, those users have been assigned one of 3 different client policies; the breakdown of client policy assignments looks something like this:

 

Policy

No. of Users Assigned This Policy

ClientPolicy1

21

ClientPolicy2

13

ClientPolicy3

71

 

Note. What's that? You say you'd like to able to generate a table similar to this? No problem:

 

Get-CsUser | Group-Object ClientPolicy | Select-Object Name Count | Format-Table -Autosize

 

But we digress. We also need to note that there's a reason why a user has been assigned a particular policy. Actually, there could be a lot of reasons why a user has been assigned a particular policy. Maybe he or she belongs to a specified security group, maybe he or she has a specific job title, maybe her or she works in a specified department and in a specific city. For our purposes, it doesn't really matter why a user has been assigned a specific policy. What does matter is that the whole thing is complicated, and you can't simply assume that all the users in a given department have the same client policy. It just doesn't work that way.

 

With us so far? OK, let's now assume that there's been a change in management, and your new manager has decided that it's silly to have all these different client policies: he wants one policy to be assigned to all users.

 

Note. Yes, typically we would say "he or she wants …." For some reason, though, any time a crazy decision like this gets made we assume it must be a he and not a she.

 

So is the nightmare scenario the fact that you have to assign the same client policy to all your Lync Server-enabled users? Nope; that's not a nightmare scenario, not by a long shot. In fact, all that takes is one little PowerShell command:

 

Get-CsUser | Grant-CsClientPolicy –PolicyName "LitwareincClientPolicy"

 

Instead, here's the nightmare scenario: no sooner do you make this change then your help desk is deluged with complaints. As it turns out, one policy doesn't work in your organization: different users need different capabilities, and now, by taking those capabilities away, you're preventing people from being able to do their jobs. At that point, your manager turns to you and says, "Well, there's only one thing we can do now: you'll just have to put things back the way they used to be. You need to reassign each person the client policy they had before we assigned them all the LitwareincClientPolicy policy."

 

So is that going to be a problem? No; that's going to be a nightmare. For better or worse, Lync Server doesn't have any sort of undo feature when it comes to most administrative tasks; for example, there's no way to undo the bulk assignment of policies. Furthermore, Lync Server doesn't keep a history of any kind: you can' just thumb through a list of all the client policies that have ever been assigned to a user and then restore one of those policies. Granted, if you've backed up Active Directory (which is where user data is stored) you could theoretically restore the overwritten data; however, in that case all the other changes made to Active Directory since the time you assigned the LitwareincClientPolicy policy would be lost.

 

Uh-oh.

 

So doesn't this mean that you should start having nightmares about Microsoft Lync Server 2010? Believe it or not, the answer is no. Admittedly, Lync Server doesn't have a built-in undo function for administrative tasks. However, if you're willing to write a couple of simple Windows PowerShell scripts, you can create your own undo function, at least for many of the things you'll do in Lync Server.

 

Like, say, bulk assignment of client policies. In the scenario we just described, the problem isn't that we did bulk assignment of client policies; instead, the problem is that, if anything went wrong with that bulk assignment there was no easy way to put things back the way they used to be. Why is there no easy way to put things back the way they used to be? You got it: because there's no easy way of knowing how things used to be. That's why we decided to assign client policies using the following script:

 

$backupData = (Get-CsUser | Select-Object Identity,ClientPolicy)

$backupData | Export-Csv –Path "C:BackupClientPolicies.csv" –NoTypeInformation

 

foreach ($user in $backupData)

    {Grant-CsClientPolicy –Identity $user.Identity –PolicyName "LitwareincClientPolicy"

    }

 

Nice, huh? Except for one thing: what does this script actually do? Well, in the first line, we use the Get-CsUser cmdlet to retrieve information about all the users who have been enabled for Lync Server. We then pipe that data to the Select-Object cmdlet, which grabs the values for just the Identity and the ClientPolicy properties. (Why just those two property values? Because those are the only two property values we care about.) That filtered data – Identity and ClientPolicy – is then stored in a variable named $backupData.

 

In the second line, we then take the variable $backupData and pipe it to the Export-Csv cmdlet, which creates a comma-separated values file at C:BackupClientPolicies.csv. That file is going to look something like this:

 

"Identity","ClientPolicy"

"CN=adelaney,OU=Redmond,DC=litwareinc,DC=com","ClientPolicy1"

"CN=aglagdkikh,OU=Redmond,DC=litwareinc,DC=com","ClientPolicy3"

"CN=aolecka,OU=Redmond,DC=litwareinc,DC=com","ClientPolicy2"

 

Etc., etc. In other words, it's the Identity of each of our Lync Enabled-users along with the name of the client policy that's currently assigned to them.

 

Note. Good question: what is the NoTypeInformation parameter for? Well, without it, Export-Csv would give us a text file that looked like this:

 

#TYPE System.Management.Automation.PSCustomObject

"Identity","ClientPolicy"

"CN=adelaney,OU=Redmond,DC=litwareinc,DC=com","ClientPolicy1"

"CN=aglagdkikh,OU=Redmond,DC=litwareinc,DC=com","ClientPolicy3"

"CN=aolecka,OU=Redmond,DC=litwareinc,DC=com","ClientPolicy2"

 

We don't have any use for that first line of type-related data, so we tacked on the NoTypeInformation parameter to prevent Export-Csv from saving that line of data in the first place.

 

When Export-Csv finishes running, we'll have a text file that contains the names of all our users and the name of the client policy (if any) that was assigned to each one: that is, a snapshot of our client policy picture before we did the bulk update. And speaking of the bulk update, that's what we do in the final block of code:

 

foreach ($user in $backupData)

    {Grant-CsClientPolicy –Identity $user.Identity –PolicyName "LitwareincClientPolicy"

    }

 

Nothing fancy there: we've just set up a foreach loop to loop through each user account stored in $backupData and assign the client policy LitwareincClientPolicy to each account. As soon as we're done with that our client policy breakdown will look like this:

 

Policy

No. of Users Assigned This Policy

LitwareincClientPolicy

Skip to main content