Or, what you can and can’t do [in criteria-based membership filters].
Forefront Identity Manager 2010 has an XPath dialect that has been intentionally limited in several areas. The XPath dialect used in FIM is documented here. The XPath dialect supports expressions against Boolean, DateTime, indexed string, number and reference data types. The XPath dialect does not support expressions on unindexed string and binary attributes.
If you want to query an unindexed string, for example, you need to pull the target resources locally and then use a local search technique against the attribute values present on the collection of resources in memory. Craig has documented this technique using PowerShell here.
Without going into any more detail on the XPath dialect let’s get to the point of this post. The dialect documented applies to enumeration (search) requests by the FIM Service in the form of Search Scope resources or the EnumerateResourcesActivity within a custom WF activity; and from any other form of client via the web services, e.g. the PowerShell cmdlets or a WCF client. The Criteria attribute of a Group or Set resource type, however, is different. The criteria-membership logic is implemented within the FIM Service and doesn’t utilise the public enumeration interfaces and, due to the fundamental nature of the criteria-based membership (it essentially drives the FIM Service in that it plays one of the largest parts in the request processing pipeline and therefore the functioning of the product), is limited in what XPath can be used and supported within the Filter attribute of a Group or Set resource.
The limitations of sets are defined in the Designing Business Policy Rules TechNet document. I’m going to reiterate them here, starting with the point I articulate quite often on our internal alias and the public forums.
Multiple location steps are not supported, except when referencing the membership of a set
Stated another way, you can only dereference the ComputedMember and ExplicitMember attributes of a Set with a predicate of ObjectID = <GUID> in Set criteria; and, in Group criteria, you can only dereference the ComputedMember and ExplicitMember attributes of a Set or Group with a predicate of ObjectID = <GUID>. This means that only the following queries, that dereference a multivalued attribute value, are permitted within the Criteria attribute of a set:
For Sets, two types of dereferencing of multivalued attributes are permitted:
/<ResType>[<reference-attr> = /Set[ObjectID = <GUID>]/ComputedMember] /<ResType>[<reference-attr> = /Set[ObjectID = <GUID>]/ExplicitMember]
For Groups, four types of dereferencing are permitted:
/<ResType>[<reference-attr> = /Set[ObjectID = <GUID>]/ComputedMember] /<ResType>[<reference-attr> = /Set[ObjectID = <GUID>]/ExplicitMember] /<ResType>[<reference-attr> = /Group[ObjectID = <GUID>]/ComputedMember] /<ResType>[<reference-attr> = /Group[ObjectID = <GUID>]/ExplicitMember]
The above reinforces this point too: Sets cannot reference the membership of Group resources (but groups can reference the membership of Set resources).
The understanding set limitations section of the Designing Business Policy Rules TechNet document also goes on to list the following unsupported filter definitions (excluding the two mentioned above) -this information is copied from the aforementioned document:
- Double negation in set filters is unsupported. If a filter contains any condition of the form not(Attribute != Value) (for example, /Person[not(DisplayName != ‘value’)], an exception is returned notifying the client that the server cannot process the filter as requested, and that the use of double negation is unsupported.
- Multiple conditions nested inside a not() statement in set filters is unsupported. If a filter contains multiple conditions inside a not() statement, the filter will be rejected. For example: /Person[not(JobTitle = ‘Developer’ or JobTitle = ‘Tester’)]
- The creation of filters that reference the membership of a temporal set is not supported. If a set/group filter is created with a filter that dynamically nests a temporal set, the request is rejected with the following error message: “A temporal set cannot be dynamically nested in other sets.”
- The creation of filters in temporal sets that reference the membership of other sets is not supported. If a set/group filter is created with a Datetime-based filter condition, the set’s filter is not permitted to reference the membership of other sets.
- The creation of filters that include relational conditions based on multivalued Datetime or multivalued Integer attributes is not supported. If a set/group filter is created with a filter that contains a relational condition on a multivalued Datetime or integer, the request is rejected with the following error message: “Relational conditions cannot be defined on multivalued DateTime and multivalued Integer attributes in a set filter.” The unsupported operators consist of: >, >=, <, <=
- The creation of filters that include the != operator with a multivalued attributes is not supported. Such a condition is not supported by the FIM 2010 XPath filter dialect.
- The contains() XPath function is not supported in set filters.
Filters such as these are not permitted in criteria-based membership filters (the lattermost example is rather contrived but illustrates the flexibility of XPath).
/Group[Owner != /Person] /Person[Manager = /Person[EmployeeType = 'Contractor']] /Person/Manager[EmploymentStatus != 'Active'] /ManagementPolicyRule[GrantRight = False and ResourceFinalSet = /Set[ComputedMember = /Person[AccountName = 'elizc']]]
…and the best source of information on this subject (repeated here):
- FIM XPath Filter Dialect: http://msdn.microsoft.com/en-us/library/windows/desktop/ee652287.aspx
- Designing Business Policy Rules: http://technet.microsoft.com/en-us/library/ff356871(WS.10).aspx. Pay particular attention to the section “understanding set limitations”.