{"id":1194,"date":"2014-06-11T00:01:00","date_gmt":"2014-06-11T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2014\/06\/11\/using-powershell-to-explore-structure-of-an-xml-document\/"},"modified":"2022-06-21T14:05:17","modified_gmt":"2022-06-21T21:05:17","slug":"using-powershell-to-explore-structure-of-an-xml-document","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/using-powershell-to-explore-structure-of-an-xml-document\/","title":{"rendered":"Using PowerShell to Explore Structure of an XML Document"},"content":{"rendered":"<p><strong>Summary<\/strong>: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to explore the structure of an XML document.<\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. I don\u2019t know about you, but when I decide to script, I often do a cost\/benefit analysis. I am not talking about anything extensive or anything that is even formalized. But I do estimate how long it will take to do something manually, and then I estimate how long it will take to do the same thing with Windows PowerShell. As you may well know, quite often Windows PowerShell wins. But not always. The not always areas are often because I may not know or understand an underlying technology well enough to script it.<\/p>\n<p><strong>\u00a0 \u00a0 \u00a0Note\u00a0<\/strong> This is the third in a series of posts about XML. You might also enjoy reading:<\/p>\n<ul>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/scripting\/creating-an-xml-document-for-admins\/\" target=\"_blank\" rel=\"noopener\">Creating an XML Document for Admins<\/a><\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/scripting\/exploring-xml-document-by-using-the-xml-type-accelerator\/\" target=\"_blank\" rel=\"noopener\">Exploring XML Document by Using the [XML] Type Accelerator<\/a><\/li>\n<\/ul>\n<p>Windows PowerShell is not &#8220;magic pixie dust.&#8221; It is an automation technology. To successfully automate, I often must know and understand the underlying technology. The better the Windows PowerShell cmdlets abstract this requirement, the easier it is for a non-expert to automate.<\/p>\n<p>But at some point, I need to know what I am doing. For example, there are 27 cmdlets that contain the characters &#42;firewall&#42; in the noun. To successfully automate firewall stuff, I need to know the relationship between the firewall rules, address, application, interface, and port filters. I also need to understand the relationship between rules, filters, settings, and profiles.<\/p>\n<p>Clearly, there is going to be a bit of reading before I really mess stuff up. In general, I like to ease into things gently by using the **Get*** types of cmdlets before I get to carried away with the **Set***, **New***, **Enable***, and **Disable*** cmdlets.<\/p>\n<h2>XML document structure<\/h2>\n<p>When I read an XML document into a variable, I like to see what is available. I like to pipe the <strong>XMLDocument<\/strong> to **Format-List **and look at the values of all properties. This is shown here:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-11-14-01.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-11-14-01.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>I can see that the XML node does not contain a lot of extremely useful information. I see that <strong>Users<\/strong> says <strong>Users<\/strong>, and that the <strong>Name<\/strong> and the <strong>LocalName<\/strong> are both <strong>#Document<\/strong>. The <strong>DocumentElement<\/strong> is <strong>Users<\/strong>. Nothing I need here.<\/p>\n<p>Although this is interesting, I am trying to see the data. One area that looks promising is <strong>InnerXML<\/strong>. It definitely contains the data for all of the user nodes. It is shown here:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-11-14-02.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-11-14-02.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>I can, call the <strong>Split<\/strong> method, and split on both <strong>&lt;<\/strong> and <strong>\/><\/strong>. This command will clean up the output a bit:<\/p>\n<p style=\"margin-left:30px\">\n  $users.InnerXml.Split(&#8216;<\/>&#8216;)\n<\/p>\n<p>The output associated with the command is shown here:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-11-14-03.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-11-14-03.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>Of course, that is not really working with XML, it is simply avoiding the problem of how to work with XML. I go back to my <strong>Format-List<\/strong> output, and I can see that there are more interesting properties exposed, \u00a0such as the <strong>ChildNodes<\/strong> property that lists the child nodes, the <strong>LastChild<\/strong> property, and the <strong>HasChildNodes<\/strong> property.<\/p>\n<p>All of these could be useful from a navigation perspective. The <strong>OuterXML<\/strong> looks an awful lot like the <strong>InnerXML<\/strong>, so I do not need to mess with that. The following image shows the properties and their associated values:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-11-14-04.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-11-14-04.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>From all of this, I can see the best path for me to pursue, is to go into the <strong>Users<\/strong> node, and look at the individual <strong>User<\/strong> objects. This is shown here\u2014and it takes us back to where we left off yesterday.<\/p>\n<p style=\"margin-left:30px\">\n  PS C:\\> $users.Users.User\n<\/p>\n<p>\u00a0<\/p>\n<p style=\"margin-left:30px\">\n  ID\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 UserName\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Address\n<\/p>\n<p style=\"margin-left:30px\">\n  &#8212;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8212;&#8212;&#8211;\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8212;&#8212;-\n<\/p>\n<p style=\"margin-left:30px\">\n  0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 UserName\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Address\n<\/p>\n<p style=\"margin-left:30px\">\n  0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 UserName\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Address\n<\/p>\n<p style=\"margin-left:30px\">\n  0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 UserName\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Address\n<\/p>\n<p style=\"margin-left:30px\">\n  0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0UserName\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Address\n<\/p>\n<p style=\"margin-left:30px\">\n  0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 UserName\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Address\n<\/p>\n<p>The point to all this?<\/p>\n<p>Well, it helps to know a bit about XML to avoid doing a lot of extra work, such as manually trying to parse (by using string methods) XML data. XML data is already formatted. I only need to know what it looks like, and I can easily use Windows PowerShell to retrieve the data I need or want.<\/p>\n<p>That is all there is to using Windows PowerShell to work with XML. XML Week will continue tomorrow when I will talk about more cool Windows PowerShell stuff.<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\" rel=\"noopener\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\" rel=\"noopener\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\" rel=\"noopener\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\" rel=\"noopener\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><strong>Ed Wilson, Microsoft Scripting Guy<\/strong>\u00a0<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to explore the structure of an XML document. Microsoft Scripting Guy, Ed Wilson, is here. I don\u2019t know about you, but when I decide to script, I often do a cost\/benefit analysis. I am not talking about anything extensive or anything that is even [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[3,4,45,165],"class_list":["post-1194","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell","tag-xml"],"acf":[],"blog_post_summary":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to explore the structure of an XML document. Microsoft Scripting Guy, Ed Wilson, is here. I don\u2019t know about you, but when I decide to script, I often do a cost\/benefit analysis. I am not talking about anything extensive or anything that is even [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/1194","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=1194"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/1194\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=1194"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=1194"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=1194"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}