gpt4 book ai didi

xml - 用于 XML 节点/路径寻址的 Powershell 变量

转载 作者:行者123 更新时间:2023-12-05 05:38:18 24 4
gpt4 key购买 nike

您好亲爱的 Powershell 专家,

我需要一些建议。我尝试使用 Powershell 变量(我从参数中获取)来处理 XML 路径/节点。

我的场景

下面的代码显示了我的代码的一个快捷方式。有了这个剪贴画,我将尝试尽可能详细地解释我的问题。

foreach ($Gpo in $AllGpos) {
[xml]$selected_Gpo = Get-GPOReport -ReportType Xml -Guid $Gpo.Id
$policy_object = $selected_Gpo.GPO.Computer.ExtensionData.Extension
if ($policy_object.$Policy_Identity_XMLPath_Name -eq $Policy_Identity_Name) {
if ($policy_object.$Setting_XMLPath_Name -eq $Policy_Identity_Setting_Name -and $policy_object.$Setting_XMLPath_Value -eq $Policy_Identity_Setting_Value) {
}
...

我遍历所有组策略对象(在 Active Directory 环境中),生成 GPO 的 xml 报告,然后在该 xml 文件中搜索特定的组策略设置。只要我使用硬编码的 xml 节点路径,此方法就可以正常工作。例如:我可以使用“$policy_object.$Policy_Identity_XMLPath_Name -eq $Policy_Identity_Name”,而不是使用“$policy_object.Policy.DropDownList.Name -eq”示例设置”。但我无法使用这些硬编码的 xml 节点路径,并且想使用变量来在 xml 文件中处理这些路径。

示例 XML 的快捷方式

<q1:Policy>
<q1:Name>TestName</q1:Name>
<q1:State>Enabled</q1:State>
<q1:Explain>Test Explaination </q1:Explain>
<q1:Supported>Testsupported version</q1:Supported>
<q1:Category>Test Category</q1:Category>
<q1:DropDownList>
<q1:Name>Test Name DropDownList</q1:Name>
<q1:State>Enabled</q1:State>
<q1:Value>
<q1:Name>TestName Value</q1:Name>
</q1:Value>
</q1:DropDownList>
</q1:Policy>

我的问题

问题是,我无法使用 powershell 变量处理 xml 路径。当我像上面的代码示例($policy_object.$Policy_Identity_XMLPath_Name)一样使用变量时,我返回 null,因此我的 if 语句不再起作用。

到目前为止我做了什么

当然,我做了很多尝试和错误的事情,让 powershell 使用变量解决这些 xml 节点路径。我试图将 ($policy_object.$Policy_Identity_XMLPath_Name) 放在不同类型的引号中。我也已经看到堆栈溢出帖子有一个非常相似的问题(Parsing an XML file with PowerShell with node from variable)但是这些解决方案基本上还不错,但在我的具体场景中没有用。让我解释一下:

$Policy_Identity_Setting_XMLPath_Name = 'GPO/Computer/ExtensionData/Extension/SecurityOptions/Display/DisplayFields/Field/Name'
$test = policy_object.SelectNodes($Policy_Identity_Setting_XMLPath_Name)

=> 结果为空。老实说,不知道为什么

$ExecutionContext.InvokeCommand.ExpandString("`$(`policy_object.$Policy_Identity_Setting_XMLPath_Name)")

这将导致“可接受的”结果。但在我的场景中,结果主要是多个值(GPO 设置),并将它们全部存储在一个巨大的字符串中。之后我无法访问此字符串中的特定值。所以这种方法也不理想,因为我无法进一步处理结果。

希望各位小伙伴多多指教。也许我让它变得比我的大脑逻辑所需要的更复杂。如果您需要更多信息,请告诉我。

最佳答案

如果您想使用 PowerShell 对 XML DOM 的改编,它允许使用 . 运算符对元素和属性进行类似属性的访问,您可以通过将 . 分隔的路径字符串拆分为其使用 . 的组件,迭代地 钻取 XML 文档,利用事实上,您可以使用表达式 来动态指定(单个)属性名称:

# Sample input
[xml] $xml = @'
<q1:Policy xmlns:q1="http://example.org">
<q1:Name>TestName</q1:Name>
<q1:State>Enabled</q1:State>
<q1:Explain>Test Explaination </q1:Explain>
<q1:Supported>Testsupported version</q1:Supported>
<q1:Category>Test Category</q1:Category>
<q1:DropDownList>
<q1:Name>Test Name DropDownList</q1:Name>
<q1:State>Enabled</q1:State>
<q1:Value>
<q1:Name>TestName Value</q1:Name>
</q1:Value>
</q1:DropDownList>
</q1:Policy>
'@

# Define the path as a single, dotted string; e.g.:
$dottedPath = 'Policy.DropDownList.State'

# Drill down into the XML, component by component.
$result = $xml
foreach ($prop in $dottedPath -split '\.') { $result = $result.$prop }

$result # Output the result: -> 'Enabled'

注意:PowerShell 对 XML DOM 的改编很方便——特别是不需要需要指定命名空间(见下文)——但有其局限性;见this answer .


相比之下,为了使用 XPath 查询,例如 .SelectNodes() :

  • 路径中的元素名称必须以/分隔
  • 并且,由于您的文档使用 XML namespace ,因此您必须传递一个 namespace 管理器实例作为第二个参数 namespace 限定元素路径中的名称

如果您忽略了后者,您确实会得到 $null 作为结果。

# Sample input
[xml] $xml = @'
<q1:Policy xmlns:q1="http://example.org">
<q1:Name>TestName</q1:Name>
<q1:State>Enabled</q1:State>
<q1:Explain>Test Explaination </q1:Explain>
<q1:Supported>Testsupported version</q1:Supported>
<q1:Category>Test Category</q1:Category>
<q1:DropDownList>
<q1:Name>Test Name DropDownList</q1:Name>
<q1:State>Enabled</q1:State>
<q1:Value>
<q1:Name>TestName Value</q1:Name>
</q1:Value>
</q1:DropDownList>
</q1:Policy>
'@

# Create a namespace manager and associate it with the document.
$namespaceMgr = [System.Xml.XmlNamespaceManager]::new($xml.NameTable)

# Add an entry for the 'q1' namespace prefix.
# Note:
# * The *prefix* (entry *name*) need not match the prefix in the document,
# but whatever name you choose must be used in your XPath query.
# * The namespace *URL* must match the one in the document, however.
$namespaceMgr.AddNameSpace('q1', 'http://example.org')

# Construct the XPath path, using the appropriate namespace prefixes; e.g.:
$xpath = 'q1:Policy/q1:DropDownList/q1:State'

# Now call .SelectNodes() with the query and the namespace manager.
# Note: This outputs the targeted XML element(s) as a whole,
# not their inner text, as dot notation would do.
# Append .InnerText, if needed.
$xml.SelectNodes($xpath, $namespaceMgr)

注意:或者,考虑使用 Select-Xml cmdlet,它为上面使用的 .NET API 提供了更高级别的接口(interface);见this answer举个例子。

关于xml - 用于 XML 节点/路径寻址的 Powershell 变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72962308/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com