Last time, I covered the XenApp 6 SDK PowerShell commands included in the Citrix.Common.Commands and Citrix.XenApp.Commands snap-ins. I’d like to talk about the Group Policy Provider in the Citrix.Common.GroupPolicy snap-in. But I feel I should first cover some concepts around Group Policies that administrators may or may not already be familiar with. So this blog entry will digress from strict PowerShell coverage in order to help establish a common base of understanding. I apologize if you are already an AD guru and find this information redundant!
Policies have a more complex and flexible model than settings did in previous versions of XenApp, and will require a different approach to thinking about where and how settings are configured. Allow me to explain in a bit of detail how the policy model works.
A GPO is a “Group Policy Object”. It is a container which contains policies and settings. If you are familiar with Active Directory, you already know that:
- Domain GPOs are stored on Domain Controllers and are linked to Sites, OUs, Security Groups, etc. within GPMC, which determines the scope of the computers and users that are affected by the settings within.
- Local GPOs are stored on each computer, and the settings within those affect only the local computer and the users logging into it.
Citrix adds a third type of GPO: a Farm GPO. This is implicitly “linked” to the scope of the farm, meaning that it applies to all servers in the farm, and all users logging into those servers, but no servers or users outside the farm. If your organization does not use Active Directory, you can use the Farm GPO exclusively.
The control provided by AD and the Farm GPO over the scope of settings is nice, but sometimes more control is required. Certainly, with the Farm GPO approach, you need a way to limit the scope of some settings to only a subset of servers in the farm or a subset of users connecting to the farm. But even within Domain GPOs you may wish to limit the scope of settings based on a connecting user’s subnet, or application silos, or other criteria. To get this flexibility, Citrix settings are stored within a prioritized list of policies in each GPO. Each policy can be filtered based on special criteria such as the connecting user’s group, client IP or name, the server’s worker group, etc. Using these filters you can control farm, server, and user settings in as granular a manner as you require. Each GPO also contains one special policy that is named “Unfiltered” which, like its name suggests, cannot be filtered. This policy also cannot be deleted.
Since multiple GPOs can apply to a single computer or user, and multiple policies within each GPO can apply to a single computer or user, it is important to know what happens when there is a conflict between two policies. First, the order of GPO processing is taken into consideration: the Farm GPO takes precedence over the Local GPO, and any Domain GPOs take precedence over both the Farm GPO and the Local GPO. (AD defines strict precedence rules between Domain GPOs; I won’t go into that here.) Within any GPO, there is a policy priority order which determines how conflicts are resolved there.
Sometimes, a higher priority policy may wish to prevent a lower priority policy from altering a setting. That is, it may be necessary to force the setting to revert to the default value, whatever that default value may be. For that reason, settings have a State which is set to Enabled, Disabled, or Not Configured. When a setting is Enabled, its value is explicitly set. When a setting is Disabled, its value is forced to revert to the default value. When a setting is Not Configured, other lower-priority policies are allowed to set the value.
Some policies are simple on/off switches for a feature. Those policies use the State field a bit differently. They still have three states, but the states are Allow, Prevent, and Not Configured. When these settings are set to Allow, the feature is turned on. When set to Prevent, the feature is turned off. When set to Not Configured, other lower-priority policies are allowed to set the value.
The SDK is forgiving about the use of Allow or Enabled, and Prevent or Disabled. It will accept either input for any setting state. In other words, even though a setting can only logically be set to Allow or Prevent, the SDK will allow a script to specify Enabled or Disabled for the state and will convert them to Allow or Prevent. This makes it a bit easier when scripting, since you may not have to look up the exact state settings for every setting individually. It helps with cut & paste code reuse.
In addition to the State, all settings that are not simply on/off switches for a feature also contain a Value. The Value is only used when the setting’s State is set to Enabled. An example of a Value is the name of a license server.
In some cases, the Value for a setting is very complex and would be quite difficult to script against. For example, the Health Check Agent has a very complex configuration that applies when it is Enabled. The Value for this setting is encoded as an XML string, and manipulating XML via a script would be painful. For these settings, we provide additional properties that make it much easier to read and modify the Value.
A big change from the XenApp 5-and-earlier model is the elimination of “instantaneous configuration”. Whereas in previous versions, a change to configuration was adopted immediately by all servers, Group Policies work differently. Regardless of the GPO, policy, or setting being changed, Group Policies are always replicated with a delay. A setting change may not take effect for up to 90 minutes within a domain, or much longer across domains. It is possible to force setting changes to be adopted more quickly by running “gpupdate.exe” on servers; however, that should be used sparingly. Having too many servers run gpupdate simultaneously can overload your domain controller. You should therefore plan for the delays in rolling out setting changes via policies.  ;Note that these delays also affect Farm GPOs even though they are not replicated via AD.
To summarize the terminology:
- A Setting is an individual configuration item that you can control for XenApp, such as the name of the license server.
- A setting has a State which is either Enabled/Allow, Disabled/Prevent, or Not Configured.
- Some settings also have a Value which is used when the setting’s state is Enabled.
- Some settings have additional properties to allow easier manipulation of the setting’s value.
- A Policy is a collection of one or more settings.
- Each policy can have one or more Filters that controls the scope of when the policy applies.
- A GPO contains one or more policies, in a prioritized order.
Understanding this model is important when it comes time to create policies, whether creating them through the SDK or through the UI. When you prepare to configure a setting, you must first ask yourself these questions:
- What setting do I need to configure?
- If the setting has a value, what value do I need to set? Or, do I just want to prevent the value from being set by administrators with lower authority?
- Where do I want the setting to apply?
Let’s consider a couple of examples.
Example: I wish to set the license server for all servers in my company to “ctxlicense.company.com”.
Here, the answers to the questions are:
- I need to configure the License Server setting.
- I need to set the setting to “ctxlicense.company.com”.
- I need the setting to apply to my entire organization.
Since the scope of the setting is potentially larger than a single farm, I should set this setting within a Domain GPO that is linked to a scope encompassing my entire organization. I do not wish any filtering, since I want all servers to be included in the scope, so I need to set the setting within the GPO’s “Unfiltered” policy. I need to set the setting’s State to “Enabled” so that it will apply the value. And I need to set the Value accordingly.
Note – if my organization does not use Active Directory I must set this setting within the Farm GPO of all farms, in the “Unfiltered” policy.
Example: I wish to disable client drive mapping for applications in my farm whenever clients connect from a subnet.
The answers now are:
- I need to configure the Client Drive Mapping setting.
- I need to set the setting so that it disables (prevents) the feature.
- I need to limit the scope of the setting to only clients connecting to one farm, with a client IP within a given range.
Since the scope of the setting is a single farm, I can set this setting with the Farm GPO for that farm. In addition, I need to filter the setting based on Client IP, so I cannot set the setting within the “Unfiltered” policy; I need to create another policy in the GPO. I need to set the setting’s State to “Prevent” so that the feature will be disabled.
That’s it for this time. Next time we’ll get back to a focus on PowerShell, and start putting these concepts to work through scripting!