Get-CsUser: The Real Story

You know how they say that you shouldn’t believe everything you read? Well, as it turns out, that’s pretty good advice … even for things you read here on this Web site.

What do we mean by that? Well, from the beginning of time generation after generation of Communications Server and Microsoft Lync Server technical writers have been saying things like this: "The Get-CsUser cmdlet returns information about all the Active Directory user accounts that have been enabled for Microsoft Lync Server." As it turns out, however, that’s not the full and complete story!

Note. Yes, we are surprised that the New York Times or the Washington Post didn’t get hold of this scandalous story before we did. Take that, lamestream media!

Now, before we go any further, we should note that we haven’t exactly been lying to you; after all, Get-CsUser does return information about all the Active Directory user accounts that have been enabled for Lync Server 2010. However, and as you’re about to see, it’s also possible for the cmdlet to return information about user accounts that haven’t been enabled for Lync Server. How is that possible? Why is that possible? Coincidentally enough, we were just about to answer those questions.

Not too long ago, we were sitting in our offices, playing Mahjong, when we got an email from someone who has been working with the beta version of Lync Server. This user claimed that he was running the Get-CsUser cmdlet and he was getting back information about all his users who had been enabled for Lync Server. At the same time, however, he was also getting back information about users that he knew had never been enabled for LyncServer. He was curious as to what was going on and, needless to say, so were we. Consequently, we immediately began our investigation.

Well, after we finished playing Mahjong, of course.

And what did that investigation uncover? This: The beta tester did have several user accounts that had never been enabled for Lync Server and information about those accounts was being returned by Get-CsUser. Why? Well, as it turns out, while those accounts had never been enabled for Lync Server they had been given SIP addresses. And, as we eventually learned, it was the SIP address that was creating all the confusion.

If you’re familiar with Lync Server or with Communications Server (any version of Communications Server) then you know that most user account information is stored in Active Directory. In fact, one of the first things you need to do in order to install Lync Server is to complete the "domain prep" phase; in this phase, your Active Directory schema is extended to, among other things, add a few new Lync Server-specific attributes to your Active Directory users accounts. To show you what we mean, do this, assuming that you’ve installed Microsoft Lync Server 2010:

1. Open Active Directory Users and Computers.

2. Click View and then click Advanced Features.

3. Right-click a user account (preferably an account that hasn’t been enabled for Communications Server) and then click Properties.

4. In the Properties dialog box, click the Attribute Editor tab.

Now, scroll down through the list of attributes. See all the attributes that begin with msRTCSIP? You know, the ones that look like these:

Those are user account attributes added by Lync Server.

So what does any of this have to do with the Get-CsUser cmdlet? Be patient; we were just about to get to that. The Properties dialog box shown above is for a user named Ken Myer. With that in mind, let's run the following command and see what we get back:

Get-CsUser | Select-Object DisplayName

In case you’re wondering, on our test machine here’s what we get back;

Jonathan Haas

Pilar Ackerman

Notice that there’s no Ken Myer, the user whose properties we looked at in Active Directory. But that shouldn’t come as any big surprise. After all, Get-CsUser is designed to return information about users who have been enabled for Lync Server. And Ken Myer hasn’t been enabled for Lync Server. We shouldn't expect Get-CsUser to return information about Ken Myer.

Just to verify that Ken has a valid Active Directory user account, let's now run this command:

Get-CsAdUser | Select-Object DisplayName

Here’s what we got back after running Get-CsAdUser:

Administrator

Internet Guest Account

Jonathan Haas

Ken Myer

Pilar Ackerman

OK, there’s Ken Myer. And, again, that’s what we would expect to get back: the whole point of Get-CsAdUser is to return information about all your Active Directory user accounts, regardless of whether or not those accounts have been enabled for Lync Server.

Still with us? OK, let’s go back to the Properties dialog box for Ken Myer's user account. In that dialog box, select the msRTCSIP-PrimaryUserAddress and then click Edit. In the String Attribute Editor dialog box, give Ken Myer the following SIP address and then click OK:

sip:kenmyer@litwareinc.com

After clicking Apply, the Properties dialog box for Ken Myer should look something like this:

In other words, we’ve assigned Ken a SIP address (via the msRTCSIP-PrimaryUserAddress attribute) but we haven’t touched any other Lync Server properties. In other words, he has a SIP address, but he hasn't been enabled for Lync Server.

Now let’s re-run our Get-CsUser command:

Get-CsUser | Select-Object DisplayName

Here’s what comes back when we run that command:

Jonathan Haas

Ken Myer

Pilar Ackerman

What the – there’s Ken Myer! And yet we know that Ken Myer hasn’t been enabled for Lync Server. What gives?

Well, what gives is this: when trying to decide who has and who has not been enabled for Lync Server, Get-CsUser relies on the msRTCSIP-PrimaryUserAddress attribute. If you have a value configured for this attribute then Get-CsUser assumes you’ve been enabled for Lync Server. If you don’t have a value configured for this attribute then Get-CsUser assumes that you haven’t been enabled for Lync Server. It's that simple.

Need more proof? Well, while we typically don’t recommend that you do this, go ahead and do this: enable Ken for Lync Server and then go in and delete just his SIP address. That should leave his Active Directory account looking something like this:

Now run Get-CsUser. You should get back something that looks like this:

Jonathan Haas

Pilar Ackerman

The moral of the story? No SIP address means no Ken Myer. At least not as far as Get-CsUser is concerned.

And that’s true even though (as you can see in the preceding graphic) the msRTCSIP-UserEnabled attribute is still set to TRUE. The msRTCSIP-UserEnabled attribute corresponds to the Enabled property used by Lync Server's user management cmdlets. Because of that you might be thinking, “Wait a second: if the Enabled property is TRUE then that must mean that the user has been enabled for Lync Server.” Surprisingly enough, however, that’s not how things work. To explain what we mean by that, let’s take a look at some attribute values for a user who has not been enabled for Lync Server. In this table, and subsequent tables, we show both the Active Directory attribute name and the corresponding Lync Server PowerShell property/parameter name:

Attribute Name

Property Name

Value

msRTCSIP-PrimaryHomeServer

HomeServer

msRTCSIP-PrimaryUserAddress

SipAddress

msRTCSIP-UserEnabled

Enabled

As you can see, no values have been configured for this user. Nor would we expect any of them to have been configured for a user who hasn't been enabled for Lync Server.

Now, here are the same attribute values for a user who has been enabled for Lync Server:

Attribute Name

Property Name

Value

msRTCSIP-PrimaryHomeServer

HomeServer

CN=Lc Services,CN=Microsoft,CN=co1:2,CN=Pools,CN=RTC Service,CN=Services,CN=Configuration,DC=Litwareinc,DC=com

msRTCSIP-PrimaryUserAddress

SipAddress

sip:kenmyer@litwareinc.com

msRTCSIP-UserEnabled

Enabled

TRUE

That should make sense: the enabled user has values configured for all these attributes. The un-enabled user doesn't have values for any of these attributes.

Ah, but this is where it gets tricky. As you may or may not know, there are two ways to disable a Lync Server user account. If you want to temporarily disable a user account, without deleting the user’s SIP address, his or her Registrar pool, any policies that have been assigned to the user, and so on, you should use the Set-CsUser cmdlet, like so:

Set-CsUser –Identity "Ken Myer" –Enabled $False

If you run this command and then take a look at Ken’s user account attributes you’ll see something that looks like this:

Attribute Name

Property Name

Value

msRTCSIP-PrimaryHomeServer

HomeServer

CN=Lc Services,CN=Microsoft,CN=co1:2,CN=Pools,CN=RTC Service,CN=Services,CN=Configuration,DC=Litwareinc,DC=com

msRTCSIP-PrimaryUserAddress

SipAddress

sip:kenmyer@litwareinc.com

msRTCSIP-UserEnabled

Enabled

FALSE

Notice that the only thing that has changed is this: the Enabled property is set to FALSE. Ken Myer is still a valid Lync Server user: he still has a SIP address, he still has a RegistrarPool, he still has all his policies and other settings. The only difference is that, because Enabled has been set to False, he can’t log on to the system. That's it. Enabled doesn't necessarily tell you whether or not you've been enabled for Lync Server; instead, it really lets you know, if you have been enabled for Lync Server, whether or not you can log on to the system.

To fully restore his user account all you have to do is run this command:

Set-CsUser –Identity "Ken Myer" –Enabled $True

See? That’s why you (or, for that matter, Get-CsUser) can’t just look at the value of the Enabled property to determine whether or not a user account has been enabled for Communications Server. Ken Myer’s Enabled property is set to FALSE, but that doesn’t mean he hasn’t been enabled for Lync Server; it just means that he’s currently unable to log on to the system.

Got all that? Good. Now, the other way to disable a user account is to run the Disable-CsUser cmdlet:

Disable-CsUser –Identity "Ken Myer"

Run that command and you'll see a much more drastic change in Active Directory:

Attribute Name

Property Name

Value

msRTCSIP-PrimaryHomeServer

HomeServer

msRTCSIP-PrimaryUserAddress

SipAddress

msRTCSIP-UserEnabled

Enabled

As you can see, when you run Disable-CsUser, all the Lync Server-related attribute values are cleared. As far as Lync Server is concerned (or at least as far as Get-CsUser is concerned), Ken Myer no longer exists. Ken won't show up when we run Get-CsUser for one reason and one reason only: because he doesn't have a SIP address. When it comes to Get-CsUser, the SIP address is the only thing that matters.

So does that mean that you can just go into Active Directory Users and Computers, assign someone a SIP address, and then magically enable that person for Lync Server? No, it does not. Admittedly, assigning someone a SIP address will cause that person to show up when you run Get-CsUser; however, it won’t give them the ability to log on to Lync Server. In theory, we suppose that, if you went in and supplied the right values for the right attributes, you probably could enable someone for Lync Server using Active Directory Users and Computer. To be honest, though, that would be way harder and way slower than enabling a user the right way: by using the Enable-CsUser cmdlet. Besides, the odds of you supplying all the right values to all the right attributes are about as good as the odds of the Seattle Mariners winning the 2010 World Series.

And, if you know anything at all about baseball, you know that those aren’t very good odds.

So what does this mean to you? Well, if you aren’t in the habit of assigning SIP addresses to users who haven’t been enabled for Lync Server then it doesn’t mean anything at all: you’ll never run into this issue. If you do assign SIP addresses to users (or contacts) who haven’t been enabled for Lync Server then you’ll just have to live with the fact that, by default, these users will show up anytime you run Get-CsUser. That's life.

But what if you’d prefer not to see these users any time you run Get-CsUser? Well, in that case, just use this syntax anytime you call Get-CsUser:

Get-CsUser –Filter {RegistrarPool –ne $Null}

What this command does is return a list of users who have a SIP address and who have been assigned to a Registrar pool. If an account has a SIP address but no Registrar pool (that is, if your Registrar pool is equal to a null value) then that account won’t be returned by this command. That will weed out users who have just a SIP address but no Registrar pool.

Incidentally, the following command does just the opposite: it returns the display name of any user who has a SIP address but is not assigned to a Registrar pool:

Get-CsUser –UnassignedUser | Select-Object DisplayName

If you aren’t sure whether or not you have users who have a SIP address but have not been enabled for Lync Server that command should help.

OK, now let’s make this really interesting. Suppose you have some users who have SIP addresses but have never been enabled for Lync Server. You’ve decided that you’d like to go ahead and enable all those users, but you’d like them to keep their existing SIP address. How in the world can you do that?

One way is to run the following script:

$x = Get-CsUser –UnassignedUser

foreach ($i in $x)

    {

        $userDN = $i.Identity

        $user = [ADSI] "LDAP://$userDN"

        $sipAddress = $user.{msRTCSIP-PrimaryUserAddress}

        Enable-CsUser –Identity $i.Identity –RegistrarPool `

            "atl-cs-001.litwareinc.com" –SipAddress $sipAddress[0]

    }

Without going into too much detail, what we’re doing here is first using Get-CsUser and the UnassignedUser parameter to return a collection of all the users who have a SIP address but have not been assigned to a Registrar pool; those user accounts get assigned to a variable named $x. We then set up a foreach loop to loop through our collection, binding to each Active Directory user account and retrieving the value of the msRTCSIP-PrimaryUserAddress attribute. That value gets stashed in a variable named $sipAddress, which we use when calling Enable-CsUser and enable the user for Lync Server.

Will that really work? Of course it will; after all, you read about it right here on our Web site, didn’t you? And you know what they say: you should always believe everything you read.