Navigating XML Files with PowerShell (Using the Help File as an example)
In the blog post called, Reading in the Help File with Get-Content (Part 2 of 2), I started the process of roaming around the PowerShell help file.
I followed the process I'm going to talk through when I needed to build some quick scripts that checked all of our Windows Server help files to make sure we had completely filled out the required fields. But before I could write scripts to automate the file verification, I first needed to know what I was looking to verify. So, in a sense, I’m more crawling through the file, than walking.
What Am I Looking For?
I can see the skeleton of the information I want from the help file when I run, get-help get-help –full and distill the titles of the sections. (I could have used any cmdlet to see the section headers, so generalized it would be get-help <cmdlet name> -full
NAME
SYNOPSIS
SYNTAX
DESCRIPTION
PARAMETERS
INPUTS
OUTPUTS
NOTES
-------------------------- EXAMPLE 1 --------------------------
…
-------------------------- EXAMPLE 15 --------------------------
RELATED LINKS
Rereading the PowerShell Help File (recap from last blog post)
In the past blog post, I had made it down to the level where I could see an element known as command. I've repeated the two sets of commands here so we can get started together (I’ve highlighted the two lines of commands I typed in):
PS C:\> $help_xml = [xml] (Get-Content $pshome\en-us\System.Management.Automation.dll-Help.xml)
PS C:\> $help_xml.helpItems | gm -MemberType properties
TypeName: System.Xml.XmlElement
Name MemberType Definition
---- ---------- ----------
#comment Property System.Object[] #comment {get;}
command Property System.Object[] command {get;}
providerHelp Property System.Object[] providerHelp {get;}
schema Property System.String schema {get;set;}
Let’s go down one level to see what child nodes are inside the command XML node: (How did I know to look at the command node? Well, I want to see information for cmdlet help. This pretty much rules out the other three nodes based on their names.)
PS C:\> $help_xml.helpItems.command | gm -MemberType properties
TypeName: System.Xml.XmlElement#https://schemas.microsoft.com/maml/dev/command/2004/10#command
Name MemberType Definition
---- ---------- ----------
#comment Property System.Object[] #comment {get;}
alertSet Property System.Xml.XmlElement alertSet {get;}
command Property System.String command {get;set;}
description Property System.Xml.XmlElement description {get;}
details Property System.Xml.XmlElement details {get;}
dev Property System.String dev {get;set;}
examples Property System.Xml.XmlElement examples {get;}
inputTypes Property System.Xml.XmlElement inputTypes {get;}
maml Property System.String maml {get;set;}
nonTerminatingErrors Property System.String nonTerminatingErrors {get;set;}
parameters Property System.Xml.XmlElement parameters {get;}
relatedLinks Property System.Xml.XmlElement relatedLinks {get;}
returnValues Property System.Xml.XmlElement returnValues {get;}
syntax Property System.Xml.XmlElement syntax {get;}
terminatingErrors Property System.String terminatingErrors {get;set;}
So, it looks like $help_xml.helpItems.command contains the cmdlet help topics I'm interested in. Some of the element/property names correspond to the section titles I’m looking for: description, examples, syntax, parameters, relatedLinks. Others seem close: inputTypes and returnValues. I don’t see notes, but there is an element called details, which might have more information.
Instead of looking at the properties of the $help_xml.helpItems.command members, let’s look at what happens when I just type $help_xml.helpItems.command and press enter from the PowerShell command line:
PS C:\> $help_xml.helpItems.command
maml : https://schemas.microsoft.com/maml/2004/10
command : https://schemas.microsoft.com/maml/dev/command/2004/10
dev : https://schemas.microsoft.com/maml/dev/2004/10
details : details
description : description
#comment : { Cmdlet syntax section, Cmdlet parameter section , Input - Output section, Error section...
}
syntax : syntax
parameters : parameters
inputTypes : inputTypes
returnValues : returnValues
terminatingErrors :
nonTerminatingErrors :
alertSet : alertSet
examples : examples
relatedLinks : relatedLinks…
I’ve only displayed the first command that is spewed when you type $help_xml.helpItems.command. What you’ll see if you try this for yourself is a spew of listings that all appear the same – no actual information, though. Because we’re seeing multiple copies, I suspect that command is actually an array. Let’s look at the first element of command details.
PS C:\> $help_xml.helpItems.command[0].details
name :
Add-Historydescription : description
copyright : copyright
verb : Add
noun : History
version :
Woo hoo! OK, we’ve hit pay dirt here. Here is the name (Add-History) along with more elements providing verb (Add) and noun (History). And if we want to display just the name of the cmdlet we can run:
PS C:\> $help_xml.helpItems.command[0].details.name
Add-History
But maybe we want to look at a different command, maybe the 100th command in the file. If we do this here’s what we see:
PS C:\> $help_xml.helpItems.command[100].details
PS C:\>
Not very enlightening, but unless we specifically setup to trap an error, we might not see one. I’m guessing we might have put in too large an index for the array of $help_xml.helpItems.command We can find length of the array (number of cmdlets that have help specified in this file) by running:
PS C:\> $help_xml.helpItems.command.length
42
Because PowerShell arrays are zero indexed, the maximum index is length - 1. In this case, if we keep the index to ((length=42) - 1) = 41 and under, we’ll get a result. For the index 41,
PS C:\> $help_xml.helpItems.command[41].details
name :
Where-Objectdescription : description
copyright : copyright
verb : Where
noun : Object
version :
Let’s go a little further and see what’s under description:
PS C:\> $help_xml.helpItems.command[41].details.description
para
----
Creates a filter that controls which objects will be passed along a command pipeline.
Comparing to the results from Get-Help Where-Object –full, this looks like what we’ve been seeing as the synopsis. That means we can get the short description or synopsis text directly with the dotted notation with para at the end:
PS C:\> $help_xml.helpItems.command[41].details.description.para
Creates a filter that controls which objects will be passed along a command pipeline.
To Recap What We’ve Found in the PowerShell Help File So Far
Steps | Command |
Read in XML file as XML | $help_xml = [xml] (Get-Content $pshome\en-us\System.Management.Automation.dll-Help.xml) |
Find out how many cmdlets we have help for in file | $help_xml.helpItems.command.length |
Print out name of cmdlet N, where N is the index into the command array | $help_xml.helpItems.command[N].details.name |
Print out short description or synopsis of cmdlet N, where N is the index into command array | $help_xml.helpItems.command[N].details.description.para |
We’re still looking for syntax, full description, parameters with description, inputs, outputs, notes, examples, and related links. Feel free to look around for these on your own. I will be continuing to hunt down more information within the PowerShell help file in the next blog post.
And again, let me know what other XML files you think we should walk through as an exercise when we’re done with this file. Feel free to post suggestions in the comment sections of this post. Looking to hear from you soon. -- Judith
Comments
- Anonymous
July 27, 2012
Fantastic! I started trying to get at this information for a long time now.