Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Documenting Powershell modules and scripts

With Powershell 5 introducing OOP Classes support, the traditional comment-based Powershell documentation methods for functions, scripts and modules are no longer a good fit. Get-Help is not presenting any help for classes, methods or properties and it looks like it will be staying that way. Other than that, Get-Help is not much of help when trying to find information on a specific function without actually having the module or powershell script in question.

As classes are especially useful for more complex Powershell projects, the need for an up-to-date documentation is more pressing than ever. Projects like Doxygen and the Sandcastle Help File Builder do support help generation for a number of OO-languages, but do not seem to be able to handle Powershell code. A quick look at the PoshBuild project reveals that it is targeted at .NET language projects, too and needs to be integrated into the Visual Studio build process, which pure-Powershell code does not have.

There is also PSDoc capable of generating documentation for modules in HTML or markdown formats based on Get-Help output, which would have been pretty much what I want if it supported classes.

So how do I auto-generate sensible documentation if I have

  1. .ps1 scripts
  2. .psm1 modules
  3. classes in my Powershell code

using the comment-based help documentation syntax?

like image 518
syneticon-dj Avatar asked Feb 07 '18 10:02

syneticon-dj


People also ask

What is a PowerShell script module?

A script module is any valid PowerShell script saved in a . psm1 extension. This extension allows the PowerShell engine to use rules and module cmdlets on your file. Most of these capabilities are there to help you install your code on other systems, as well as manage scoping.

Where do I put PowerShell modules?

The AllUsers location is $env:PROGRAMFILES\PowerShell\Modules on Windows. On Linux or Mac the modules are stored at /usr/local/share/powershell/Modules .

Can you write scripts in PowerShell?

You can create PowerShell script files using virtually any text editor or the legacy ISE console. However, the preferred option (thanks, @JotaKa, for the tip) to write scripts is using the Visual Studio Code editor with the PowerShell extension.


1 Answers

@trebleCode still deserves the answer, I'm just posting this for anyone interested.

I started trying to answer this question a while ago but got distracted and never finished. If I recall correctly, there was some discussion I found on Github where they said they didn't plan on supporting comment annotated classes, which is sad because I like Powershell Comments.

My thought here was that by calling the builtin help methods you could create a helper function that would detect these non-standard comments above the class keyword and convert them to comment objects without invoking get-help. These comments could also be stored in external files.

Below I found the code for parsing comments into objects and creating comment objects in code.

# References: 
# https://learn-powershell.net/2015/08/07/invoking-private-static-methods-using-powershell/
# https://stackoverflow.com/questions/1259222/how-to-access-internal-class-using-reflection
# https://stackoverflow.com/questions/15652656/get-return-value-after-invoking-a-method-from-dll-using-reflection
# https://github.com/PowerShell/PowerShell/blob/a8627b83e5cea71c3576871eacad7f2b19826d53/src/System.Management.Automation/help/HelpCommentsParser.cs

$ExampleComment = @"
<#
.SYNOPSIS
    This was a triumph
#>
"@

$CommentLines = [Collections.Generic.List`1[String]]::new()
$InvokeArgs = @($ExampleComment, $CommentLines)

# GetMethod Filter
$BindingFlags = 'static','nonpublic','instance'

# GetMethod Filter: We need to specify overloaded methods by their parameters
$ParamTypes  = [Type]::GetTypeArray($InvokeArgs)
$ParamCount  = [System.Reflection.ParameterModifier]::new(2)

$HelpParser  = [psobject].Assembly.GetType('System.Management.Automation.HelpCommentsParser')
$CollectCommentText = $HelpParser.GetMethod('CollectCommentText', $BindingFlags, $null, $ParamTypes, $ParamCount)

# Extension methods aren't part of the class so null gets called first.
# TODO: Figure out return value
$CollectCommentText.Invoke($Null,$InvokeArgs)
$InvokeArgs

# Comment object but properties are read only.
$CommentHelp = [System.Management.Automation.Language.CommentHelpInfo]::new()
$CommentHelp.Synopsis
$CommentHelp.Description
$CommentHelp.Examples
$CommentHelp
like image 69
RiverHeart Avatar answered Oct 21 '22 12:10

RiverHeart