Invoke-CreateModuleHelpFile/Invoke-CreateModuleHelpFile.ps1
#https://github.com/gravejester/Invoke-CreateModuleHelpFile function Invoke-CreateModuleHelpFile { <# .SYNOPSIS Create a HTML help file for a PowerShell module. .DESCRIPTION This function will generate a full HTML help file for all commands in a PowerShell module. .EXAMPLE Invoke-CreateModuleHelpFile -ModuleName 'MyModule' -Path 'c:\temp\MyModuleHelp.html' This will generate a help file for 'MyModule' and save it as 'c:\temp\MyModuleHelp.html' .NOTES This function is dependent on jquery, the bootstrap framework and the jasny bootstrap add-on. Author: Øyvind Kallstad @okallstad Version: 1.1 #> [CmdletBinding()] param( # Name of module. Note! The module must be imported before running this function. [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $ModuleName, # Skip dependency check. [Parameter()] [switch] $SkipDependencyCheck = $false ) function Get-ScriptDirectory { Split-Path -Parent $PSCommandPath } $currentPath = Get-ScriptDirectory # jquery filename - remember to update if you update jquery to a newer version $jqueryFileName = 'jquery-1.11.1.min.js' # define dependencies $dependencies = @('bootstrap.min.css','jasny-bootstrap.min.css','navmenu.css',$jqueryFileName,'bootstrap.min.js','jasny-bootstrap.min.js') try { # check dependencies if (-not($SkipDependencyCheck)) { $missingDependency = $false foreach($dependency in $dependencies) { if(-not(Test-Path -Path (Join-Path (Get-ScriptDirectory) $dependency))) { Write-Warning "Missing: $($dependency)" $missingDependency = $true } } if($missingDependency) { break } Write-Verbose 'Dependency check OK' } # add System.Web - used for html encoding Add-Type -AssemblyName System.Web # try to get module info from imported modules first $moduleData = Get-Module -Name $ModuleName # abort if no module data returned if(-not ($moduleData)) { Write-Warning "The module '$($ModuleName)' was not found. Make sure that the module is imported before running this function." break } # abort if return type is wrong if(($moduleData.GetType()).Name -ne 'PSModuleInfo') { Write-Warning "The module '$($ModuleName)' did not return an object of type PSModuleInfo." break } # get module commands $moduleCommands = $moduleData.ExportedCommands | Select-Object -ExpandProperty 'Keys' Write-Verbose 'Got Module Commands OK' # start building html $html = @" <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="description" content=""> <meta name="author" content=""> <title>$($ModuleName)</title> <link href="bootstrap.min.css" rel="stylesheet"> <link href="jasny-bootstrap.min.css" rel="stylesheet"> <link href="navmenu.css" rel="stylesheet"> <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script> <![endif]--> </head> <body> <div class="navmenu navmenu-default navmenu-fixed-left offcanvas-sm hidden-print"> <nav class="sidebar-nav" role="complementary"> <a class="navmenu-brand visible-md visible-lg" href="#" data-toggle="tooltip" title="$($ModuleName)">$($ModuleName)</a> <ul class="nav navmenu-nav"> <li><a href="#About">About</a></li> "@ # loop through the commands to build the menu structure $count = 0 foreach($command in $moduleCommands) { $count++ Write-Progress -Activity "Creating HTML for $($command)" -PercentComplete ($count/$moduleCommands.count*100) $html += @" <!-- $($command) Menu --> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">$($command) <b class="caret"></b></a> <ul class="dropdown-menu navmenu-nav"> <li><a href="#$($command)-Synopsis">Synopsis</a></li> <li><a href="#$($command)-Syntax">Syntax</a></li> <li><a href="#$($command)-Description">Description</a></li> <li><a href="#$($command)-Parameters">Parameters</a></li> <li><a href="#$($command)-Inputs">Inputs</a></li> <li><a href="#$($command)-Outputs">Outputs</a></li> <li><a href="#$($command)-Examples">Examples</a></li> <li><a href="#$($command)-RelatedLinks">RelatedLinks</a></li> <li><a href="#$($command)-Notes">Notes</a></li> </ul> </li> <!-- End $($command) Menu --> "@ } # finishing up the menu and starting on the main content $html += @" <li><a class="back-to-top" href="#top"><small>Back to top</small></a></li> </ul> </nav> </div> <div class="navbar navbar-default navbar-fixed-top hidden-md hidden-lg hidden-print"> <button type="button" class="navbar-toggle" data-toggle="offcanvas" data-target=".navmenu"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">$($ModuleName)</a> </div> <div class="container"> <div class="page-content"> <!-- About $($ModuleName) --> <h1 id="About" class="page-header">About $($ModuleName)</h1> <div class="row"> <div class="col-md-4 col-xs-4"> Description<br> DotNetFrameworkVersion<br> ModuleVersion<br> Author<br> ProjectUri<br> Copyright </div> <div class="col-md-6 col-xs-6"> $([System.Web.HttpUtility]::HtmlEncode($moduleData.Description))<br> $([System.Web.HttpUtility]::HtmlEncode($moduleData.DotNetFrameworkVersion))<br> $([System.Web.HttpUtility]::HtmlEncode($moduleData.Version))<br> $([System.Web.HttpUtility]::HtmlEncode($moduleData.Author))<br> <a href="$($moduleData.ProjectUri.AbsoluteUri)" target="_blank">$([System.Web.HttpUtility]::HtmlEncode($moduleData.ProjectUri.AbsoluteUri))</a><br> $([System.Web.HttpUtility]::HtmlEncode($moduleData.Copyright)) </div> </div> <br> <!-- End About --> "@ # loop through the commands again to build the main content foreach($command in $moduleCommands) { $commandHelp = Get-Help $command $html += @" <!-- $($command) --> <div class="panel panel-default"> <div class="panel-heading"> <h2 id="$($command)-Header">$($command)</h1> </div> <div class="panel-body"> <h3 id="$($command)-Synopsis">Synopsis</h3> <p>$([System.Web.HttpUtility]::HtmlEncode($commandHelp.Synopsis))</p> <h3 id="$($command)-Syntax">Syntax</h3> "@ # get and format the command syntax $syntaxString = '' foreach($syntax in ($commandHelp.syntax.syntaxItem)) { $syntaxString += "$($syntax.name)" foreach ($syntaxParameter in ($syntax.parameter)) { $syntaxString += ' ' # parameter is required if(($syntaxParameter.required) -eq 'true') { $syntaxString += "-$($syntaxParameter.name)" if($syntaxParameter.parameterValue) { $syntaxString += " <$($syntaxParameter.parameterValue)>" } } # parameter is not required else { $syntaxString += "[-$($syntaxParameter.name)" if($syntaxParameter.parameterValue) { $syntaxString += " <$($syntaxParameter.parameterValue)>]" } elseif($syntaxParameter.parameterValueGroup) { $syntaxString += " {$($syntaxParameter.parameterValueGroup.parameterValue -join ' | ')}]" } else { $syntaxString += ']' } } } $html += @" <pre>$([System.Web.HttpUtility]::HtmlEncode($syntaxString))</pre> "@ Remove-Variable -Name 'syntaxString' } $html += @" <h3 id="$($command)-Description">Description</h3> <p>$([System.Web.HttpUtility]::HtmlEncode($commandHelp.Description.Text -join [System.Environment]::NewLine) -replace([System.Environment]::NewLine, '<br>'))</p> <h3 id="$($command)-Parameters">Parameters</h3> <dl class="dl-horizontal"> "@ # get all parameter data foreach($parameter in ($commandHelp.parameters.parameter)) { $parameterValueText = "<$($parameter.parameterValue)>" $html += @" <dt data-toggle="tooltip" title="$($parameter.name)">-$($parameter.name)</dt> <dd>$([System.Web.HttpUtility]::HtmlEncode($parameterValueText))<br> $($parameter.description.Text)<br><br> <div class="row"> <div class="col-md-4 col-xs-4"> Required?<br> Position?<br> Default value<br> Accept pipeline input?<br> Accept wildchard characters? </div> <div class="col-md-6 col-xs-6"> $([System.Web.HttpUtility]::HtmlEncode($parameter.required))<br> $([System.Web.HttpUtility]::HtmlEncode($parameter.position))<br> $([System.Web.HttpUtility]::HtmlEncode($parameter.defaultValue))<br> $([System.Web.HttpUtility]::HtmlEncode($parameter.pipelineInput))<br> $([System.Web.HttpUtility]::HtmlEncode($parameter.globbing)) </div> </div> <br> </dd> "@ } $html += @" </dl> <h3 id="$($command)-Inputs">Inputs</h3> <p>$([System.Web.HttpUtility]::HtmlEncode($commandHelp.inputTypes.inputType.type.name))</p> <h3 id="$($command)-Outputs">Outputs</h3> <p>$([System.Web.HttpUtility]::HtmlEncode($commandHelp.returnTypes.returnType.type.name))</p> <h3 id="$($command)-Examples">Examples</h3> "@ # get all examples $exampleCount = 0 foreach($commandExample in ($commandHelp.examples.example)) { $exampleCount++ $html += @" <b>Example $($exampleCount.ToString())</b> <pre>$([System.Web.HttpUtility]::HtmlEncode($commandExample.code))</pre> <p>Output<pre>$($commandExample.remarks.text)</pre></p> <br> "@ } $html += @" <h3 id="$($command)-RelatedLinks">RelatedLinks</h3> <p><a href="$([System.Web.HttpUtility]::HtmlEncode($commandHelp.relatedLinks.navigationLink.uri -join ''))">$([System.Web.HttpUtility]::HtmlEncode($commandHelp.relatedLinks.navigationLink.uri -join ''))</a></p> <h3 id="$($command)-Notes">Notes</h3> <p>$([System.Web.HttpUtility]::HtmlEncode($commandHelp.alertSet.alert.text -join [System.Environment]::NewLine) -replace([System.Environment]::NewLine, '<br>'))</p> <br> </div> </div> <!-- End ConvertFrom-HexIP --> "@ } # finishing up the html $html += @" </div> </div><!-- /.container --> <script src="$($jqueryFileName)"></script> "@ $html += @' <script src="bootstrap.min.js"></script> <script src="jasny-bootstrap.min.js"></script> <script>$('body').scrollspy({ target: '.sidebar-nav' })</script> <script> $('[data-spy="scroll"]').on("load", function () { var $spy = $(this).scrollspy('refresh') }) </script> </body> </html> '@ Write-Verbose 'Generated HTML OK' $helpPath = Join-Path (Split-Path -Path $currentPath -Parent) docs if (-not (Test-Path -Path $helpPath)) { New-Item -Path $helpPath -ItemType Directory | Out-Null } $dependencies | % { Copy-Item -Path (Join-Path $currentPath $_) -Destination $helpPath -Force } # write html file $html | Out-File -FilePath (Join-Path $helpPath index.html) -Force -Encoding 'UTF8' Write-Verbose "$($helpPath) written OK" } catch { Write-Warning $_.Exception.Message } } Invoke-CreateModuleHelpFile -ModuleName psWeblogic |