MDT 2013, Powershell, and XPath – ZTIGather.xml

Deployment

With XML being used so much nowadays, XPath is a useful tool to query xml documents, it can also be useful in other ways. For example looking at how the ZTIConfigure.xml file in helps MDT merge information from Customsettings.ini into an answer file. XPath is used to query the answer file for the current vlues that are present and then merge the new values into the correct nodes.

Use the ZTIGather.xml file to explore the basics of XPath and wwhat it can do. This file is great for a demo as it has a fairly basic structure with only 1 set of child nodes and 3-4 attibutes.

Root Node – properties
Child Node – property
Attributes – id,type,overwrite,description

Using the Select-Xml cmdlet we can start exploring this document using xpath via powershell. To begin, we start by getting the root node of the document.

Query: Select-Xml -Path ‘C:\ZTIGather.xml’ -XPath “/*”

We’re off to a good start. You can see that the first node is “properties” which is exactly what we saw in the initial screenshot from NotePad++. Now, we need to see what child nodes are under the root node. We do this by specifying the “properties” node as our starting point and using the ‘*’ wildcard character to return everything. The forward slash ‘/’ tells xpath to only search the very next set of child nodes as opposed to ‘//’ which would search every set of child nodes. In this case there is only one set of child nodes under “properties” so there is no need to use the double forward slash but you certainly can if you so choose.

Query: Select-Xml -Path ‘C:\ZTIGather.xml’ -XPath “/properties/*”

Ok. As you can see we have returned all of the “property” nodes that exist under “properties”. But how do we get the information we care about? You may have noticed that the Select-Xml cmdlet returns the Node.Path, and Pattern properties. In this case we need to get the Node property to unlock the valuable information that we are looking for.

Query: Select-Xml -Path ‘C:\ZTIGather.xml’ -XPath “/properties/property” | foreach-object{$_.Node}
Or
Query: Select-Xml -Path ‘C:\ZTIGather.xml’ -XPath “/properties/*” | foreach-object{$_.Node}

Now we’re cookin’. We can see the attributes of the “property” nodes but how can we filter out the information that we don’t need? For example, let’s get only the properties that have an overwrite attribute that has a value of “true”.

Query: Select-Xml -Path ‘C:\ZTIGather.xml’ -XPath “/properties/property[@overwrite=’true’]” | foreach-object{$_.Node}

The “@” character tells xpath that we are looking for an attribute and the string that we are searching for must be surrounded by single or double quotes. This entire part of the query is called a Predicate and is always contained in square brackets.

Okay so now that we have the properties that can be overwritten, how can we retrieve a single property? We simply need to add another predicate. The attribute we want to filter on is “id” and to keep it simple let’s get the property that has an id value of “Phase”.

Query: Select-Xml -Path ‘C:\ZTIGather.xml’ -XPath “/properties/property[@overwrite=’true’][@id=’Phase’]” | foreach-object{$_.Node}

Nice right? Now we can see only the property that we currently need. But notice that I executed the query twice and the first execution did not produce any output. This is because of one of the most important rules about XPath that you need to remember. It is EXTREMELY CASE-SENSITIVE!!! Take another look at all of the queries we have executed thus far. Every element that we used in the queries is lower-case. That is because they are lower-case in the original document that we are trying to explore.  This does not mean that every query you execute needs to be entirely in lower-case. You must specify each element exactly how it is displayed in the original document.

In this case, the id we were looking for has a capital letter(“P”) and I used a lower-case “p” in the first query. Once I revised the query I received the desired results.

I hope that this little demo gives you a better understanding of what you can do with XPath and Powershell. In future posts we will look at more complex documents like the answer files that are used in MDT deployments.

No Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Deployment
MDT – Joining a Computer to a Domain Using PowerShell

Using PowerShell scripts within a task sequence provides more flexibility than using the CustomSettings.ini file to join a computer to a domain. The parameters of the CustomSettings.ini file are common to any deployment you perform. That’s why creating a custom PowerShell script to join your domain will be customize to …

Deployment
Task Sequence Tasks Explained

This document explains the tasks that you will find in standard task sequence. Initialization > Gather local only – gathers deployment configuration settings from local sources that apply to the target computer [ZTIGather.wsf] Validation > Validate – verifies that the target computer meets the specified deployment requirement conditions. Such as …

Deployment
How MDT uses XML to install Applications

Have you ever thought about what actually happens when you import applications into your MDT environment? How does the task sequence know what application to install? How does it know what command-line arguments to specify during the application install process? Technically, as a user, all that is required of us …