提问人:OldManWithTime 提问时间:11/2/2023 最后编辑:mklement0OldManWithTime 更新时间:11/3/2023 访问量:61
使用 Excel VBS 分析 PowerShell PSCustomObject XML
Parsing a PowerShell PSCustomObject XML with Excel VBS
问:
我花了几个小时试图找到自己的解决方案,但失败了:( 我想做的就是读取 XML 并创建一个 Muti-Layered-Array 或 ArrayList。
这是 Powershell 的输出示例。
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<Obj RefId="0">
<TN RefId="0">
<T>Selected.System.String</T>
<T>System.Management.Automation.PSCustomObject</T>
<T>System.Object</T>
</TN>
<MS>
<I32 N="RefNum">1</I32>
<S N="Name">MyVMName</S>
<S N="Type">VM</S>
<!-- Additional properties -->
</MS>
</Obj>
<!-- Additional objects -->
</Objs>
这是众多尝试之一,但请随意将其拆开。
Set xmlDoc = CreateObject("MSXML2.DOMDocument.6.0")
xmlDoc.Async = False
' Load the PowerShell XML content
xmlDoc.Load "your_powershell_xml_file.xml"
If xmlDoc.ParseError = 0 Then
' Use the namespace in XPath queries
xmlDoc.setProperty "SelectionNamespaces", "xmlns:ps='http://schemas.microsoft.com/powershell/2004/04'"
' Select all PSCustomObject elements
Set customObjects = xmlDoc.SelectNodes("//ps:Obj[TN/T='System.Management.Automation.PSCustomObject']")
' Iterate through PSCustomObject elements
For Each customObject In customObjects
' Access properties within the PSCustomObject
RefNum = customObject.SelectSingleNode("MS/I32[@N='RefNum']").Text
Name = customObject.SelectSingleNode("MS/S[@N='Name']").Text
Type = customObject.SelectSingleNode("MS/S[@N='Type']").Text
' Display the parsed properties
WScript.Echo "RefNum: " & RefNum
WScript.Echo "Name: " & Name
WScript.Echo "Type: " & Type
Next
Else
' Handle XML parsing error
WScript.Echo "Error loading PowerShell XML: " & xmlDoc.ParseError.Reason
End If
在 XML 中使用 VBS 读取的任何帮助 由 Powershell 制作并填充多层数组或 ArrayList。 在“xmlDoc.SelectNodes(”//ps:Obj[TN/T='System.Management.Automation.PSCustomObject']“)处失败
答:
2赞
mklement0
11/3/2023
#1
XPath 查询中的每个命名元素都必须使用相应的命名空间前缀。
因此,例如,将:
Set customObjects = xmlDoc.SelectNodes("//ps:Obj[TN/T='System.Management.Automation.PSCustomObject']")
with(注意所有元素名称中的前缀):ps:
Set customObjects = xmlDoc.SelectNodes("//ps:Obj[ps:TN/ps:T='System.Management.Automation.PSCustomObject']")
这同样适用于后续调用。.SelectSingleNode()
总而言之:
Set xmlDoc = CreateObject("MSXML2.DOMDocument.6.0")
xmlDoc.Async = False
' Load the PowerShell XML content
xmlDoc.Load "C:\path\to\your\file.xml"
If xmlDoc.ParseError = 0 Then
' Use the namespace in XPath queries
xmlDoc.SetProperty "SelectionNamespaces", "xmlns:ps='http://schemas.microsoft.com/powershell/2004/04'"
' Select all PSCustomObject elements
Set customObjects = xmlDoc.SelectNodes("//ps:Obj[ps:TN/ps:T='System.Management.Automation.PSCustomObject']")
' Iterate through PSCustomObject elements
For Each customObject In customObjects
' Access properties within the PSCustomObject
refNumAttr = customObject.SelectSingleNode("ps:MS/ps:I32[@N='RefNum']").Text
nameAttr = customObject.SelectSingleNode("ps:MS/ps:S[@N='Name']").Text
typeAttr = customObject.SelectSingleNode("ps:MS/ps:S[@N='Type']").Text
' Display the parsed properties
Wscript.Echo ("RefNum: " & refNumAttr)
Wscript.Echo ("Name: " & nameAttr)
Wscript.Echo ("Type: " & typeAttr)
Next
Else
' Handle XML parsing error
Wscript.Echo ("Error loading PowerShell XML: " & xmlDoc.ParseError.Reason)
End If
注意:
- 若要在 Excel 的 Visual Basic for Application (VBA) 代码编辑器中运行代码,并将诊断输出到“即时窗口”,请替换为 。
Wscript.Echo
Debug.Print
评论
0赞
OldManWithTime
11/3/2023
那奏效了,非常感谢。我确实有一个 Id-10_t 问题。你怎么知道使用 ps:。我没有看到是否在 XML 路径中。
0赞
OldManWithTime
11/3/2023
是因为我在这里使用了它“xmlns:ps=”,所以我继续使用它吗?
0赞
mklement0
11/3/2023
@OldManWithTime:是的,这是因为你使用了 in,所以你必须在 XPath 查询中使用前缀。此前缀是自行选择的,不必与输入文档中的相同 - 只有 URI 必须相同。:ps
xmlDoc.setProperty "SelectionNamespaces", "xmlns:ps=..."
ps:
0赞
OldManWithTime
11/3/2023
看起来XML没有遵循相同的格式。我试图粘贴它,但它看起来很糟糕,而且我超过了字符计数。第一个对象有'<TN RefId=“0”>',其余对象有'<TNRef RefId=“0”/>'我不确定你如何导航。
1赞
OldManWithTime
11/3/2023
哦,好吧,是时候进行 b 计划了。 哈哈,谢谢
评论