Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Powershell 4 XML node access notation puzzle

Tags:

powershell

xml

Powershell 4 windows Server 2008 R2

So recently I wrote a Powershell script to dial into the app pools of my machine web configuration file for IIS. I really don't know the name of the way this access the XML nodes, but here is how it was done the first time:

$appPoolNode = ($config['configuration']['system.applicationHost']['applicationPools']['add'] | where {$_.name -eq $AppPoolName})

Sadly this did not work with anything but the default app pool.
So if I wanted to change something for another app pool that was made, I could not get anything to return from the above line of code. I pulled in a co-worker who showed me the dot-notation of accessing XML nodes:

$appPoolNode = ($config.configuration.'system.applicationHost'.applicationPools.add | where {$_.name -eq $AppPoolName})

And somehow this code works.

My question is:
what kind of XML access is the 1st code sample code called, and why does dot-notation work for other app pools instead of just the defaultappPool like the first code sample?

like image 712
McFrank Avatar asked May 31 '26 10:05

McFrank


1 Answers

Fun with PowerShell magic :-)

Your $config variable is of some type derived from System.Xml.XmlNode. PowerShell does this when you cast some string to [xml].

This type includes among other methods a property Item, which like in C# is used to handle the accessor syntax with the brackets, so writing

$config['a']

gets resolved into a function call

$config.Item('a')

which returns a single value - the first child node matching the given name.

Now, if you use the . notation for this, you just invoke another property, but in this case one added dynamically by PowerShell when it parsed the XML file.

It adds a property for each child node name and each attribute it finds on the current node. If there is more than one child node with a given name, it makes the property return the array of these nodes and that is where it differs from the Item method, which returns only the first value.

To see this with a simple example, consider

$x = [xml]"<a> <b Id='1'/> <b Id='2'/> </a>"

Then $x | Get-Member shows the usual XmlDocument properties, including Item, plus a property a which returns a single XmlElement. So at this point

$x['a']
$x.Item('a')
$x.a

all return the same. Now do $x.a | Get-Member. You see that Item still returns a single XmlElement, but since b occurs more than once in the XML, PowerShell lets the b property return an array of generic objects (which happen to be of type XmlElement again).

Consequently

$x.a.b

gives you both Id values, while

 $x.a['b']

only returns the first one.

like image 125
TToni Avatar answered Jun 04 '26 13:06

TToni



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!