Scopes and Filters
Suppose you’re a typical English-speaking American and you get the opportunity to live and work in Rome for a year. Could you survive without learning to speak Italian? Maybe. Would you be better off if you took a little time to sit down and learn some Italian? Definitely. When in Rome, do as the Romans do.
Oh: and talk like the Romans talk.
As it turns out, Microsoft Lync Server 2010 introduces a whole new language and a whole new vocabulary all its own. Can you survive without learning this new vocabulary? Maybe. Would you be better off if you took a little time to sit down and learn this new vocabulary? Well, you know what they say: when in Rome ….
With that in mind, let’s take a minute and talk about three important new terms being introduced along with the new Lync Server implementation of Windows PowerShell: identities, scopes, and filters.
At the risk of tooting our own horns, we went to great lengths to explain identities in our Identities article, which means that we’re not going to do it again here. Instead, let’s move on to Scopes.
Man, if all the sections turn out like this one this article will be a cinch to write.
To explain what a scope let’s start by listing the available scopes:
• Global. The global scope is for configuration settings or policies you want enforced throughout your entire Microsoft Lync Server infrastructure. For example, when you configure a policy at the global scope that policy will be applied to every user in the organization. (Well, unless you have configured a policy “downstream.” But more on that in a minute.)
• Site. The site scope is for, well, sites. In Lync Server 2010, sites are typically based on geographic locations: a Redmond site, a Dublin site, etc.
• Service. The service scope represents a service. For example, the Registrar service is one Microsoft Lync Server service; user services is another. In the new Lync Server architecture, a given service might be carried out by a single computer or by all the computers in a pool.
• Tenant. The Tenant scope deals with Lync Server as a service (the so-called “in-the-cloud” scenario). At this point in time the Microsoft Lync Server cmdlets cannot be used “in the cloud.” In turn, that means that it is irrelevant to our needs, and thus won’t be discussed in this article. We mention this only because – as you’ll see in the next section – you might stumble upon a reference to the Tenant scope when trying to determine the allowed scopes for an object.
• Per-User. To be honest, “per-user” isn’t really the name of the scope, it’s more a description of the scope. (We have yet to come up with a good name for this scope.) The basic concept behind the per-user scope is pretty straightforward. The per-user scope (which applies only to policies, and not to configurations) is reserved for policies that can be directly applied to a user or a group of users. This makes the per-user (or, more simply, “user”) scope very different from the global, site, and service scopes, all of which are tied to your Microsoft Lync Server infrastructure. For example, if you don’t have a site named Redmond then you can’t create a policy at the site:Redmond scope; a site-scoped policy must be tied to an actual site. The Identity of a site-scoped policy or a service-scoped policy is simply the Identity of the site or service – period.
Oh, and each site is limited to one voice policy, one client policy, and so on: you can’t have two site-scoped voice policies at the Redmond site.
By comparison, you can create a per-user policy and give it pretty much any Identity. That’s because these policies do not have to be anchored to real objects such as sites or services. In turn, that means you can create as many per-user voice policies as you want, even if you don’t ever actually use those policies.
Scopes are primarily used for policy (and configuration) resolution. For example, if a user wants to make a phone call Lync Server needs to check to see such things as which voice policy is used to determine how (or even if) the user makes a call. Microsoft Lync Server applies policies and configurations in this order:
1. First, the system checks to see if something has been applied at the user scope. If so, then that policy (configurations can’t be applied at the user scope) is used.
2. If nothing can be found at the user scope then the system checks to see if something has been applied at the service scope. If so, then that policy or configuration is applied.
3. If nothing can found at the service scope then the system checks to see if something has been applied at the site scope. If so, then that policy or configuration is applied
4. If nothing can be found at the site scope then the system checks to see if something has been applied at the global scope. If so, then that policy or configuration is applied.
Note that there will always be a global policy or a global configuration setting. Global policies and configuration settings are automatically created for you when you install Microsoft Lync Server 2010, and these global objects can never be removed.
Got all that? Good, because now we can talk about how you specify an identity and, equally important, when you specify an identity.
As we explained in the Identities section of this manual, identities are specified at the time you create a new object; the identity you give that object will depend on both the type of object and on the scope of the object. For example, suppose you want to create a new conferencing policy for use at the site level; what identity will you give that policy? That’s an easy one: a site policy always has an Identity that consists of the string value site: followed by the name of the site. For example, if this conferencing policy is to be assigned to the Redmond site then you would use the following code to create the new policy:
New-CsConferencingPolicy –Identity site:Redmond
OK, then what about a policy that’s supposed to be assigned to a service? That’s another easy one: the Identity is simply the string value service: followed by the service name (i.e., Registrar) followed by the fully qualified domain name of the pool where that service is located. You know, like this:
New-CsClientVersionPolicy –Identity service:Registrar:atl-cs-001.litwareinc.com
As you can see, when you are working at the site scope or the service scope there is no need to assign (or grant) a policy; instead, the policy is automatically assigned based on the Identity you give it. Give a policy the Identity site:Redmond and it will automatically be assigned to the Redmond site.
That leaves us with one last identity/scope to deal with: per-user. Per-user policies (and, again, only policies can be applied at the per-user scope) represent the one time (for the most part) you get to be a little creative: with per-user policies, you get to pick out the Identity. (Hurray!) That’s because per-user policies aren’t automatically assigned to a portion of the Microsoft Lync Server infrastructure; in fact, per-user policies aren’t automatically assigned to anyone or anything. Upon creation they simply exist; they do nothing more than wait for you to explicitly assign them to a user or group of users.
So what does all that look like? It looks a little something like this:
New-CsConferencingPolicy –Identity RedmondConferencingPolicy
In this case, the Identity consists of a string value that is the policy “name”: RedmondConferencingPolicy. You can give your user policy any name you wish.
Is there a way to determine the allowed scopes for an object?
Yes: scope information is included in the Help topic for each cmdlet where this information is relevant. You can determine the allowed scopes simply by perusing the help file for a given cmdlet. That’s the recommended way to determine the allowed scopes for an object.
Suppose you type the command Get-Help New-CsConferencingPolicy –full | more. Do that and then scroll down until you find the section labeled Parameters. In that section you should find the following information:
Unique identifier for the conferencing policy to be created.
Conferencing policies can be created at the site or per-use
Notice that the global scope isn’t mentioned. That’s because a global conferencing policy always exists, you can’t create a new one. If you look at the description of the Identity parameter in the help for Set-CsConferencingPolicy, you’ll see this:
Unique identifier for the conferencing policy to be modified.
Conferencing policies can be configured at the global, site,
or per-user scopes.
Suppose you have a dial plan with the Identity site:Redmond. As it turns out, this dial plan is the only dial plan that has an Identity that starts with the string value site:R. Consequently, you might find yourself thinking, “I bet I could use a wildcard character to identify this dial plan.” With that in mind, you try to retrieve the dial plan using a command like this:
Get-CsDialPlan –Identity site:R*
We hate to be the ones to rain on your parade, but this isn’t going to work; if you try running the preceding command all you’ll get back is the following error message:
Get-CsDialPlan : Cannot get “DialPLan” “Site:R*” because it does not exist.
At line:1 char:15
+ Get-CsDialPlan <<<< -Identity site:R*
+ CategoryInfo : ResourceUnavailable: (Site:*:XdsIdentity) [Get-C
+ FullyQualifiedErrorId : MissingItem,Microsoft.Rtc.Management.Internal.Ge
So why didn’t this work? One reason and one reason only: you can’t use wildcards when specifying an object’s Identity. If you gave your dial plan the Identity site:Redmond then you’re going to have to type that entire string each time you need to retrieve that plan. And that’s all there is to it; there’s no way to work around this issue, none whatsoever.
Well, unless you use the –Filter parameter, of course.
The -What parameter? The -Filter parameter. For example, the following command will return the dial plan site:Redmond; in fact, it will return any dial plan that has an Identity that begins with the string value site:R:
Get-CsDialPlan –Filter site:R*
In other words, if you’ve been wondering what the –Filter parameter is for, well, now you know: -Filter enables you to use wildcards when specifying the policies or configurations that you want to retrieve. For example, suppose you have the following dial plans in your organization:
To return all the dial plans you can just call Get-CsDialPlan without any additional parameters:
Now, what if you wanted all the dial plans that were configured at the site scope? This command will do the trick:
Get-CsDialPlan –Filter Site:*
See how that works? We used the wildcard Site:* to find all the dial plans that begin with the string value Site: (which, by definition, makes them site policies). It’s just that easy.
OK, so now what if you want to find all the dial plans configured at the per-user scope? Remember that, when we created an object at the per-user scope, we simply gave the identity a unique name, we didn’t have to include a scope. For example, to create the per-user dial plan NorthAmericaHeadquartersDialPlan, we use a command like this:
New-CsDialPlan –Identity NorthAmericaHeadquartersDialPlan
And we can use -Filter to retrieve that particular dial plan:
Get-CsDialPlan –Filter *North*
Of course, the preceding command will retrieve all the dial plans (regardless of scope) that contain the string North. For example, suppose we also had a dial plan defined for a site named NorthRedmond (Identity site:NorthRedmond). The preceding command would retrieve the dial plan with the identity NorthAmericaHeadquartersDialPlan and the dial plan site:NorthRedmond.
So how do you retrieve only the per-user (tag) dial plans? Well, even though we didn’t include the scope when creating an Identity for our per-user dial plan, we can still use tag: to retrieve these dial plans. In other words, we can run a command like this:
Get-CsDialPlan –Filter tag:*
By including the tag: prefix in our Filter value, we can retrieve all the dial plans that were defined using just a name; in other words, all the dial plans that must be explicitly granted to users in order to take effect (the ones configured at the per-user, or tag scope). The reason we can do this is because even though we defined the identity with just a name, the tag: prefix is added in the background. And it’s added for just this reason – so we can continue to filter on these values.
The moral of the story is this: if you want to retrieve policies or settings by using wildcard values then you will need to use –Filter rather than –Identity.
-- The End –