Get-CsUser and Get-CsAdUser: When to Use Where-Object vs. Filter or LdapFilter

With Get-CsUser and Get-CsAdUser, doesn’t the Where-Object cmdlet do the same thing as the Filter and LdapFilter parameters?

That's an easy one. The answer to your question is this: yes.

Well, except that the answer to your question is also this: no.

Hmmm …. Maybe it's not quite as easy as we thought.

Here's the deal. Oftentimes, the net result of using the Where-Object cmdlet is the same as using the Filter or LdapFilter parameter. For example, this command returns all the users who have been assigned the client policy RedmondClientPolicy:

Get-CsUser –Filter {ClientPolicy –eq "RedmondClientPolicy}

So does this command:

Get-CsUser | Where-Object {$_.ClientPolicy –eq "RedmondClientPolicy}

Slightly different syntax, but the exact same result.

So does it really matter whether you use the Filter parameter (or the LdapFilter parameter) or whether you pipe data to Where-Object? Well, believe it or not, it can make a big difference, at least if you’re running these commands on your workstation rather than on the server. When you use the Filter (or LdapFilter) parameter, all your filtering takes place on the server. You connect to the server, you retrieve all the user accounts, the Filter parameter weeds out everyone who hasn’t been assigned the client policy RedmondClientPolicy, then that subset of user data is shipped across the network to your workstation. Suppose you have 10,000 users and 88 of them have been assigned RedmondClientPolicy. That means user account data for just those 88 users is all that gets sent across the network.

So does Where-Object do the same thing? Nope, not even close. With Where-Object, you connect to server, grab all of your user accounts (in this case, all 10,000 of them), then all that user information gets ferried across the network. It's only after all information about all 10,000 accounts has been delivered to your workstation that Where-Object goes about picking out those 88 accounts that have been assigned RedmondClientPolicy. In other words:

· With the Filter or LdapFilter parameters, minimal (depending on your query) information is sent across the network, and processing takes place on the server.

· With Where-Object, maximum information is sent across the network, and processing takes place on your workstation.

If that doesn't make total sense, well, don't worry about: we have an article that explains the process in much more detail.

That article also talks about the second difference between the two filtering parameters and the Where-Object cmdlet: the fact that Where-Object can only filter on properties that belong to the object being returned. For example, suppose you would like to get some information about all your Lync-enabled users who work in the IT department. With that in mind, you try running the following command:

Get-CsUser | Where-Object {$_.Department –eq "IT"} | Select-Object DisplayName, Enabled, EnterpriseVoiceEnabled

Is that command going to work? No, it's going to fail. Why? Because Department is not an attribute that gets returned by the Get-CsUser cmdlet. (If you don't believe us, try running Get-CsUser and see for yourself.) Because the user object returned by Get-CsUser doesn't have a Department property there's no way that Where-Object can filter on that property.

And yes we know: life can be so unfair at times, can't it?

Now consider this command:

Get-CsUser –LdapFilter "Department=IT" | Select-Object DisplayName, Enabled, EnterpriseVoiceEnabled

Is that command going to work? You bet it is. That's because the LdapFilter parameter can filter on any "generic" Active Directory user account attribute (like, say, Department), just like the Filter parameter can filter on any Lync Server-specific attribute (like, say, EnterpriseVoiceEnabled). In other words, there are going to be times when you can't use Where-Object. In those cases, only the Filter or the LdapFilter parameter will do.