Hello powershell fellows,
i have another issue with powershell and xml.
What i try to do: I have an XML File (more accurately, it is a xml export of a AD GPO). This XML looks very similar to this:
<?xml version="1.0" encoding="UTF-16"?>
-<GPO xmlns="http://www.microsoft.com/GroupPolicy/Settings" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
-<Identifier>
<Identifier xmlns="http://www.microsoft.com/GroupPolicy/Types"></Identifier>
<Domain xmlns="http://www.microsoft.com/GroupPolicy/Types">Testdomain.local</Domain>
</Identifier>
<Name>ExampleName</Name>
<IncludeComments>true</IncludeComments>
<CreatedTime>2022-07-26T11:12:25</CreatedTime>
<ModifiedTime>2022-07-26T11:56:44</ModifiedTime>
<ReadTime>2022-07-26T11:56:52.7975554Z</ReadTime>
-<Computer>
<VersionDirectory>1</VersionDirectory>
<VersionSysvol>1</VersionSysvol>
<Enabled>true</Enabled>
-<ExtensionData>
-<Extension xsi:type="q1:SecuritySettings" xmlns:q1="http://www.microsoft.com/GroupPolicy/Settings/Security">
-<q1:SecurityOptions>
<q1:KeyName>TestKeyName</q1:KeyName>
<q1:SettingNumber>5</q1:SettingNumber>
-<q1:Display>
<q1:Name>TestName</q1:Name>
<q1:Units/>
<q1:DisplayString>TestValue</q1:DisplayString>
</q1:Display>
</q1:SecurityOptions>
...
Now i want to address these xml nodes with Select-XML cmdlet. I need to use a absolute Xpath Path. Lets say i want to get the value of "SecurityOptions/Display/Name".
I tried something like this:
$namespace = @{ns="http://www.microsoft.com/GroupPolicy/Settings";xsi="http://www.w3.org/2001/XMLSchema-instance";xsd="http://www.w3.org/2001/XMLSchema";q1="http://www.microsoft.com/GroupPolicy/Settings/Security"}
$xpath = '/q1:SecurityOptions/q1:Display/q1:Name'
$result = (Select-Xml -Path "C:\examplepath\example.xml" -XPath $xpath -Namespace $namespace).Node.InnerText
But this gets me no value at all :/
What works:
On the other hand, when i do not use an absolute path like:
$xpath = '//q1:Name'
$result = (Select-Xml -Path "C:\examplepath\example.xml" -XPath $xpath -Namespace $namespace).Node.InnerText
It gives me some result. But i want to address the XML Nodes with an absolute path not only with a relative path.
Maybe anyone can tell me what i am doing wrong here. :)
Thank you in advance !
The answer is as simple as adding a missing /
. Not sure why you have to use an absolute path, but in your relative path, your expression //q1:Name
starts with //
which covers all descendants nodes of the root with that name. In your absolute path expression /q1:SecurityOptions...
you start with /
, which looks only for direct child elements of the root by that name. But the /q1:SecurityOptions
element is burred several layers down the tree.
So long story short, changing your xpath expression to
'//q1:SecurityOptions/q1:Display/q1:Name'
should work.