6

Suppose you are writing some PSCmdLet in C#:

/// <summary>
/// Get a stack overflow exception.
/// </summary>
[Cmdlet(VerbsCommon.Join, "StackOverflow")]
[OutputType(typeof(OverflowException))]
public class JoinStackOverflow : PSCmdlet {
  protected override void ProcessRecord() {
    throw new OverflowException("stack");
  }
}

If the module defining the above is loaded into PowerShell, the command help Join-StackOverflow will return the following:

NAME
  Join-StackOverflow

SYNTAX
  Join-StackOverflow  [<CommonParameters>]

ALIASES
  None

REMARKS
  None

How can I add a synopsis/summary for this cmdlet, e.g. the same as for Get-Process:

NAME
  Get-Process

SYNOPSIS
  Gets the processes that are running on the local computer or a remote computer.

...
Rok Strniša
  • 6,781
  • 6
  • 41
  • 53

2 Answers2

6

Cmdlet help is normally in the satellite XML file. Assuming the cmdlet is in the module MyModule.dll, the help file is normally in MyModule\en-US\MyModule.dll-help.xml

Help XML is so called MAML-format. In order to avoid composing it each time manually I created a tool (script library) Helps. It generates a template help script for a cmdlet which looks somewhat similar to help. Here is an example. Then, after filling blanks (example), another Helps command is called to convert this script into MAML XML.

P.S. There are other helper tools on the web. I tried a couple of them and decided to create my own.

Roman Kuzmin
  • 40,627
  • 11
  • 95
  • 117
1

Here is the basic structure of the MyModule.dll-Help.xml file, which can be in the same directory as the module DLL itself, or in a culture subdirectory (such as en-US):

<!-- For a complete treatment of this format for PowerShell cmdlets, 
     see https://msdn.microsoft.com/en-us/library/bb525433.aspx -->
<command:command 
  xmlns:maml="http://schemas.microsoft.com/maml/2004/10"
  xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" 
  xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10">
  <command:details>
    <command:name>Verb-Noun</command:name>
    <command:verb></command:verb>
    <command:noun></command:noun>
    <maml:description><maml:para>Synopsis</maml:para></maml:description>
  </command:details>
  <maml:description><maml:para>Description</maml:para></maml:description>
  <command:syntax>
    <command:syntaxItem>
      <maml:name>Verb-Noun</maml:name>
      <command:parameter required="true" globbing="true" pipelineInput="true (ByValue)" position="1">
        <maml:name>ParameterName1</maml:name>
        <command:parameterValue required="true">string[]</command:parameterValue>
      </command:parameter>
      <command:parameter required="true" globbing="true" pipelineInput="true (ByPropertyName)">
        <maml:name>ParameterName2</maml:name>
        <command:parameterValue required="true">int32[]</command:parameterValue>
      </command:parameter>
      <!-- Additional parameter elements for each additional parameter. -->
    </command:syntaxItem>
    <!-- Additional syntaxItem elements for each additional parameter set. -->
  </command:syntax>
  <command:parameters>
    <command:parameter required="true" globbing="true" pipelineInput="true (ByValue)" position="1">
      <maml:name>ParameterName1</maml:name>
      <command:parameterValue required="true">string[]</command:parameterValue>
      <maml:description><maml:para>Parameter description</maml:para></maml:description>
      <dev:type>string[]</dev:type>
      <dev:defaultvalue>defaultvalue</dev:defaultvalue>
      <dev:possiblevalues>
        <dev:possiblevalue>
          <dev:value>value1</dev:value>
          <maml:description><maml:para>value description</maml:para></maml:description>
        </dev:possiblevalue>
        <dev:possiblevalue>
          <dev:value>value2</dev:value>
          <maml:description><maml:para>value description</maml:para></maml:description>
        </dev:possiblevalue>
      </dev:possiblevalues>
    </command:parameter>
    <command:parameter required="true" globbing="true" pipelineInput="true (ByPropertyName)">
      <maml:name>ParameterName2</maml:name>
      <maml:description><maml:para>Parameter description</maml:para></maml:description>
      <dev:type>int32[]</dev:type>
      <dev:defaultvalue>defaultvalue</dev:defaultvalue>
    </command:parameter>
    <!-- Additional parameter elements for each additional parameter. -->
  </command:parameters>
  <command:inputTypes>
    <command:inputType>
      <dev:type>
        <maml:name>System.String</maml:name>
        <maml:uri></maml:uri>
        <maml:description><maml:para></maml:para></maml:description>
      </dev:type>
      <maml:description><maml:para>You can pipe names …</maml:para></maml:description>
    </command:inputType>
    <!-- Additional inputType elements for each additional input type. -->
  </command:inputTypes>
  <command:returnValues>
    <command:returnValue>
      <dev:type>
        <maml:name>System.Object</maml:name>
        <maml:uri></maml:uri>
        <maml:description><maml:para></maml:para></maml:description>
      </dev:type>
      <maml:description><maml:para>When you …</maml:para></maml:description>
    </command:returnValue>
  </command:returnValues>
  <maml:alertSet>
    <maml:title>Note Title</maml:title>
    <maml:alert>
      <maml:para></maml:para>
    </maml:alert>
  </maml:alertSet>
  <command:examples>
    <command:example>
      <maml:title>----------  EXAMPLE 1  ----------</maml:title>
      <!-- The documentation (and SQLPS) suggests the PS C:\&gt; should go in the intro,
           but the dll-Help.xml files that come with PowerShell all seem to add it to the dev:code line. -->
      <maml:Introduction><maml:para>PS C:\&gt;</maml:para></maml:Introduction>
      <dev:code>Verb-Noun</dev:code>
      <dev:remarks>
        <maml:para> command description </maml:para>
        <!-- Two empty para elements signify the beginning of the output. -->
        <maml:para/>
        <maml:para/>
        <maml:para>output</maml:para>
      </dev:remarks>
    </command:example>
  </command:examples>
  <maml:relatedLinks>
    <maml:navigationLink><maml:linkText>Topic-name</maml:linkText><maml:uri></maml:uri></maml:navigationLink>
    <maml:navigationLink><maml:linkText>Topic-name</maml:linkText><maml:uri></maml:uri></maml:navigationLink>
  </maml:relatedLinks>
</command:command>
jpmc26
  • 28,463
  • 14
  • 94
  • 146
brianary
  • 8,996
  • 2
  • 35
  • 29
  • 1
    "Basic" ....... That's one of the most verbose and convoluted things I've ever seen. – jpmc26 Aug 15 '17 at 00:11
  • @jpmc26 It's not an easy or approachable format. I thought a fill-in-the-blanks template or recipe would be helpful. – brianary Aug 15 '17 at 03:36
  • 1
    I know it's not you fault. It's Microsoft's. But, well... I didn't even realize it *was* a fill in the blank template. ;) It's not that your answer is bad. It's just the format is really difficult to even start wrapping your head around. "Basic" just didn't seem like a very fitting word. lol – jpmc26 Aug 15 '17 at 03:58