Take the guess work out of XPath with the Lithnet FIM Service PowerShell Module
Summary
The FIM Service allows you to query for resources using a subset of the XPath 2.0 dialect. It provides a quite powerful mechanism for searching for resources, but has more than a few curiosities when it comes to constructing queries for different attribute types.
The Lithnet FIM Service PowerShell module includes three cmdlets to help take the guess work out of constructing your XPath queries.
New-XPathQuery
The New-XPathQuery cmdlet creates a predicate that forms part of an XPath expression. The query is the Attribute = ‘value’ component of the expression
New-XPathGroup
An XPath query group contains multiple XPath query objects, or other query groups, that are combined together with an ‘and’ or ‘or’ operator.
New-XPathExpression
The XPath expression wraps the query or query group with the appropriate syntax defining the object type (eg /Person[query])
Working with different attribute types
The cmdlets generate the correct syntax for each attribute type, without you have having to remember all the different ways the query needs to be expressed.
For example, lets have a look at the way we have to test for presence for each different attribute type
Type | Check |
String | /Person[(starts-with(AccountName, '%'))] |
Integer | /Person[(unixGid <= 999999999999999)] |
DateTime | /Person[(ExpiryDate <= '9999-12-31T23:59:59.997')] |
Boolean | /Person[((AccountDisabled = true) or (AccountDisabled = false))] |
Reference | /Person[(Manager = /*)] |
The New-XPathQuery cmdlet has a simple syntax, that is independent of the type of attribute.
$query`` ``=`` `` New-XPathQuery`` ``-AttributeName`` `` AccountName`` ``-Operator`` `` IsPresent
The cmdlet will automatically generate the syntax that is appropriate for the attribute specified . It’s not just the IsPresent operator that is made simpler. The cmdlets support all the attribute types and operators that are supported by FIM. The underlying Lithnet RMC library used by the cmdlets has over 100 associated unit tests to ensure all combinations of operators and attributes generate the correct XPath syntax.
How do i use it?
Simple query
The following example shows a simple query that checks for an AccountName of ‘ryan’
$query = New-XPathQuery -AttributeName "AccountName" -Operator Equals -Value "ryan" $expression = New-XPathExpression -ObjectType "Person" -QueryObject $query
$expression``.`` ToString()
Resulting expression
/Person[(AccountName = 'ryan')]
Combining queries into a group
You can combine multiple queries together in a group using the New-XPathQueryGroup cmdlet. This allows you to join queries created by New-XPathQuery together with an And or Or operator. Searching for an AccountName of ‘bob’ or ‘ryan’ is shown in the example below.
$query1 = New-XPathQuery -AttributeName "AccountName" -Operator Equals -Value "ryan"
$query2 = New-XPathQuery -AttributeName "AccountName" -Operator Equals -Value "bob"
$queryGroup = New-XPathQueryGroup -Operator Or -Queries ($query1, $query2)
$expression = New-XPathExpression -ObjectType "Person" -QueryObject $queryGroup
$expression. ToString()
Resulting expression
/Person[ ((AccountName = 'ryan' ) or (AccountName = 'bob'))]
Nested query groups
Query groups can contain child query groups as well. You can build complex nested expressions using multiple groups. The following example looks for all users who have a display name starting with ‘ryan’ or ‘bob’ that also have an email address
# Create the child queries
$query1 = New-XPathQuery -AttributeName "DisplayName" -Operator StartsWith -Value "ryan"
$query2 = New-XPathQuery -AttributeName "DisplayName" -Operator Equals -Value "bob"
# Create the child group
$queryGroup1 = New-XPathQueryGroup -Operator Or -Queries @($query1, $query2)
$query3 = New-XPathQuery -AttributeName "Email" -Operator IsPresent
# Create the parent group using the child group and another query
$queryGroup2 = New-XPathQueryGroup -Operator And -Queries @($query3, $queryGroup1)
$expression = New-XPathExpression -ObjectType "Person" -QueryObject $queryGroup2
$expression. ToString()
Resulting expression
/Person[ ((starts-with(Email, '%' )) and ((starts-with(DisplayName, 'ryan' )) or (DisplayName = 'bob')))]
Nested expressions
When querying a reference attribute, you can use another expression as a query parameter. This allows you to build dereferencing expressions with ease. The following example searches for all people who have a manager with the AccountName ‘ryan’
# Build an expression to find a user by its account name
$query = New-XpathQuery -AttributeName "AccountName" -Operator Equals -Value "ryan"
$expression = New-XpathExpression -ObjectType "Person" -Query $query
# Build a query to find all users with a manager who has the account name 'ryan'
$derefQuery = New-XpathQuery -AttributeName "Manager" -Operator Equals -Value $expression
$derefExpression = New-XpathExpression Person $derefQuery
$derefExpression. ToString()
Resulting expression
/Person[ (Manager = /Person[(AccountName = 'ryan')])]
Dereferencing expressions
Creating a dereferencing expression is easy with the DereferenceAttribute parameter on the New-XPathExpression cmdlet. The following example gets the manager of the person with the AccountName ‘ryan’
# Creates an expression that returns the manager of a user who has the account name 'ryan'
$query = New-XPathQuery -AttributeName "AccountName" -Operator Equals -Value "ryan"
$expression = New-XPathExpression -ObjectType "Person" -QueryObject $query -DereferenceAttribute "Manager"
$expression. ToString()
Resulting expression
/Person[(AccountName = 'ryan')]/Manager
Using the expression object
Passing the expression to Search-Resources
Expression objects can be passed to other cmdlets such as Search-Resources . Rather than providing an XPath string to Search-Resources, you can simply pass the expression object.
# Creates an expression that searches for users with the account name 'ryan'
$query = New-XPathQuery -AttributeName "AccountName" -Operator Equals -Value "ryan"
$expression = New-XPathExpression -ObjectType "Person" -QueryObject $query
Search-Resources $expression
Filter syntax
You can also use the builder to create the Filter attribute used is sets and groups. The –WrapFilterXml parameter ensures that the <Filter> XML element is wrapped around your expression
$query`` `` =`` ``New-XPathQuery`` `` -AttributeName`` ``"AccountName"`` `` -Operator`` ``Equals`` `` -Value`` ``"ryan"``
$expression = New-XPathExpression -ObjectType "Person" -QueryObject $query -WrapFilterXml
$expression. ToString()
Resulting expression
<Filter xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
Dialect="http://schemas.microsoft.com/2006/11/XPathFilterDialect"
xmlns="http://schemas.xmlsoap.org/ws/2004/09/enumeration" >
/Person[(AccountName = 'ryan')]
</ Filter>
** **
Setting Filter attributes directly
The library supports setting the value of a Filter attribute to an expression object directly. Ensure you set the –WrapFilterXml parameter on your expression.
# Get the set
$set = Get-Resource -ObjectType Set -AttributeName DisplayName -AttributeValue "Users called ryan"
# Construct the filter expression
$query = New-XPathQuery -AttributeName "DisplayName" -Operator StartsWith -Value "ryan"
$expression = New-XPathExpression -ObjectType "Person" -QueryObject $query -WrapFilterXml
# Set the filter attribute to newly created expression
$set .Filter = $expression
# Save the resource
Save-Resource $set
Further Reading
- The cmdlet reference documents the full set of features available in the PowerShell module.
- The XPath Expression Examples page shows all the possible resulting XPath expressions for each attribute type
Feedback
If you have feedback please leave it as comment below.