PowershellCentral Script Repository

This is a highly modified pastebin, designed to support long term storage, as well as browsing and search. It is hosted by PowerShellCentral, and is the main community repository for PowerShell scripts.

This site is developed to XHTML and CSS2 W3C standards. If you see this paragraph, your browser does not support those standards and you need to upgrade. Visit WaSP for a variety of options.

Compile-Help (modification of post by Jeff Hillman view diff)
diff | download | new post

This script uses the text and XML PowerShell help files to generate HTML help for all PowerShell Cmdlets, PSProviders, and "about" topics. the help topics are compiled into a .chm file using HTML Help Workshop.
  1. # Compile-Help.ps1
  2. # by Jeff Hillman
  3. #
  4. # this script uses the text and XML PowerShell help files to generate HTML help
  5. # for all PowerShell Cmdlets, PSProviders, and "about" topics.  the help topics
  6. # are compiled into a .chm file using HTML Help Workshop.
  7. #
  8. # Minor tweak by John Robbins to work on x64 when looking for HHC.EXE.
  9.  
  10. param( [string] $outDirectory = ".\PSHelp", [switch] $GroupByPSSnapIn )
  11.  
  12. function Html-Encode( [string] $value )
  13. {
  14.     # System.Web.HttpUtility.HtmlEncode() doesn't quite get everything, and
  15.     # I don't want to load the System.Web assembly just for this.  I'm sure
  16.     # I missed something here, but these are the characters I saw that needed
  17.     # to be encoded most often
  18.     $value = $value -replace "&(?![\w#]+;)", "&"
  19.     $value = $value -replace "<(?!!--)", "&lt;"
  20.     $value = $value -replace "(?<!--)>", "&gt;"
  21.     $value = $value -replace "’", "&#39;"
  22.     $value = $value -replace '["“”]', "&quot;"
  23.    
  24.     $value = $value -replace "\n", "<br />"
  25.  
  26.     $value
  27. }
  28.  
  29. function Capitalize-Words( [string] $value )
  30. {
  31.     $capitalizedString = ""
  32.  
  33.     # convert the string to lower case and split it into individual words. for each one,
  34.     # capitalize the first character, and append it to the converted string
  35.     [regex]::Split( $value.ToLower(), "\s" ) | ForEach-Object {
  36.         $capitalizedString += ( [string]$_.Chars( 0 ) ).ToUpper() + $_.SubString( 1 ) + " "
  37.     }
  38.  
  39.     $capitalizedString.Trim()
  40. }
  41.  
  42. function Get-ParagraphedHtml( [string] $xmlText )
  43. {
  44.     $value = ""
  45.    
  46.     if ( $xmlText -match "<(\w+:)?para" )
  47.     {
  48.         $value = ""
  49.         $options = [System.Text.RegularExpressions.RegexOptions]::Singleline
  50.  
  51.         foreach ( $match in [regex]::Matches( $xmlText,
  52.             "<(?:\w+:)?para[^>]*>(?<Text>.*?)</(?:\w+:)?para>", $options ) )
  53.         {
  54.             $value += "<p>$( Html-Encode $match.Groups[ 'Text' ].Value )</p>"   
  55.         }
  56.     }
  57.     else
  58.     {
  59.         $value = Html-Encode $xmlText
  60.     }
  61.    
  62.     $value
  63. }
  64.  
  65. function Get-SyntaxHtml( [xml] $syntaxXml )
  66. {
  67.     $syntaxHtml = ""
  68.  
  69.     # generate the HTML for each form of the Cmdlet syntax
  70.     foreach ( $syntaxItem in $syntaxXml.syntax.syntaxItem )
  71.     {
  72.         if ( $syntaxHtml -ne "" )
  73.         {
  74.             $syntaxHtml += "<br /><br />`n"
  75.         }
  76.  
  77.         $syntaxHtml += "        $( $syntaxItem.name.get_InnerText().Trim() ) "
  78.  
  79.         if ( $syntaxItem.parameter )
  80.         {
  81.             foreach ( $parameter in $syntaxItem.parameter )
  82.             {
  83.                 $required = [bool]::Parse( $parameter.required )
  84.  
  85.                 $syntaxHtml += "<nobr>[-$( $parameter.name.get_InnerText().Trim() )"
  86.  
  87.                 if ( $required )
  88.                 {
  89.                     $syntaxHtml += "]"
  90.                 }
  91.  
  92.                 if ( $parameter.parameterValue )
  93.                 {
  94.                     $syntaxHtml +=
  95.                         " &lt;$( $parameter.parameterValue.get_InnerText().Trim() )&gt;"
  96.                 }
  97.  
  98.                 if ( !$required )
  99.                 {
  100.                     $syntaxHtml += "]"
  101.                 }
  102.  
  103.                 $syntaxHtml += "</nobr> "
  104.             }
  105.         }
  106.  
  107.         $syntaxHtml += " <nobr>[&lt;CommonParameters&gt;]</nobr>"
  108.     }
  109.  
  110.     $syntaxHtml.Trim()
  111. }
  112.  
  113. function Get-ParameterHtml( [xml] $parameterXml )
  114. {
  115.     $parameterHtml = ""
  116.  
  117.     # generate HTML for each parameter
  118.     foreach ( $parameter in $parameterXml.parameters.parameter )
  119.     {
  120.         if ( $parameterHtml -ne "" )
  121.         {
  122.             $parameterHtml += "        <br /><br />`n"
  123.         }
  124.  
  125.         $parameterHtml +=
  126.             "        <nobr><span class=`"boldtext`">-$( $parameter.name.get_InnerText().Trim() )"
  127.  
  128.         if ( $parameter.parameterValue )
  129.         {
  130.             $parameterHtml += " &lt;$( $parameter.parameterValue.get_InnerText().Trim() )&gt;"
  131.         }
  132.  
  133.         $parameterHtml += "</span></nobr>`n"
  134.  
  135.         $parameterHtml += @"
  136.         <br />
  137.         <div id="contenttext">
  138.           $( Get-ParagraphedHtml $parameter.description.get_InnerXml().Trim() )
  139. "@
  140.         if ( $parameter.possibleValues )
  141.         {
  142.             foreach ( $possibleValue in $parameter.possibleValues.possibleValue )
  143.             {
  144.                 $parameterHtml += @"
  145.           $( $possibleValue.value.Trim() )<br />
  146. "@
  147.                 if ( $possibleValue.description.get_InnerText().Trim() -ne "" )
  148.                 {
  149.                     $parameterHtml += @"
  150.           <div id="contenttext">
  151.             $( Get-ParagraphedHtml $possibleValue.description.get_InnerXml().Trim() )
  152.           </div>
  153. "@
  154.                 }
  155.             }
  156.         }
  157.        
  158.         $parameterHtml += @"
  159.         <br />
  160.         </div>
  161.         <table class="parametertable">
  162.           <tr>
  163.             <td>Required</td>
  164.             <td>$( $parameter.required )</td>
  165.           </tr>
  166.           <tr>
  167.             <td>Position</td>
  168.             <td>$( $parameter.position )</td>
  169.           </tr>
  170.           <tr>
  171.             <td>Accepts pipeline input</td>
  172.             <td>$( $parameter.pipelineInput )</td>
  173.           </tr>
  174.           <tr>
  175.             <td>Accepts wildcard characters</td>
  176.             <td>$( $parameter.globbing )</td>
  177.           </tr>
  178. "@
  179.  
  180.         if ( $parameter.defaultValue )
  181.         {
  182.             if( $parameter.defaultValue.get_InnerText().Trim() -ne "" )
  183.             {
  184.                 $parameterHtml += @"
  185.           <tr>
  186.             <td>Default Value</td>
  187.             <td>$( $parameter.defaultValue.get_InnerText().Trim() )</td>
  188.           </tr>
  189. "@
  190.             }
  191.         }
  192.  
  193.         $parameterHtml += @"
  194.         </table>
  195. "@
  196.     }
  197.  
  198.     if ( $parameterHtml -ne "" )
  199.     {
  200.         $parameterHtml += "        <br /><br />`n"
  201.     }
  202.  
  203.     $parameterHtml += @"
  204.         <nobr><span class="boldtext">&lt;CommonParameters&gt;</span></nobr>
  205.         <br />
  206.         <div id="contenttext">
  207.           <p>
  208.             For more information about common parameters, type "Get-Help about_commonparameters".
  209.           </p>
  210.         </div>
  211. "@
  212.  
  213.     $parameterHtml.Trim()
  214. }
  215.  
  216. function Get-InputHtml( [xml] $inputXml )
  217. {
  218.     $inputHtml = ""
  219.     $inputCount = 0
  220.  
  221.     # generate HTML for each input type
  222.     foreach ( $inputType in $inputXml.inputTypes.inputType )
  223.     {
  224.         if ( $inputHtml -ne "" )
  225.         {
  226.             $inputHtml += "        <br /><br />`n"
  227.         }
  228.  
  229.         if ( $inputType.type.name.get_InnerText().Trim() -ne "" -or
  230.             $inputType.type.description.get_InnerText().Trim() -ne "" )
  231.         {
  232.             $inputHtml += "      $( $inputType.type.name.get_InnerText().Trim() )`n"
  233.             $inputHtml += @"
  234.       <div id="contenttext">
  235.         $( Get-ParagraphedHtml $inputType.type.description.get_InnerXml().Trim() )
  236.       </div>
  237. "@
  238.             $inputCount++
  239.         }
  240.     }
  241.  
  242.     $inputHtml.Trim()
  243.     $inputCount
  244. }
  245.  
  246. function Get-ReturnHtml( [xml] $returnXml )
  247. {
  248.     $returnHtml = ""
  249.     $returnCount = 0
  250.  
  251.     # generate HTML for each return value
  252.     foreach ( $returnValue in $returnXml.returnValues.returnValue )
  253.     {
  254.         if ( $returnHtml -ne "" )
  255.         {
  256.             $returnHtml += "        <br /><br />`n"
  257.         }
  258.  
  259.         if ( $returnValue.type.name.get_InnerText().Trim() -ne "" -or
  260.             $returnValue.type.description.get_InnerText().Trim() -ne "" )
  261.         {
  262.             $returnHtml += "      $( $returnValue.type.name.get_InnerText().Trim() )`n"
  263.             $returnHtml += @"
  264.       <div id="contenttext">
  265.         $( Get-ParagraphedHtml $returnValue.type.description.get_InnerXml().Trim() )
  266.       </div>
  267. "@
  268.             $returnCount++
  269.         }
  270.     }
  271.  
  272.     $returnHtml.Trim()
  273.     $returnCount
  274. }
  275.  
  276. function Get-ExampleHtml( [xml] $exampleXml )
  277. {
  278.     $exampleHtml = ""
  279.     $exampleTotalCount = 0
  280.     $exampleCount = 0
  281.  
  282.     foreach ( $example in $exampleXml.examples.example )
  283.     {
  284.         $exampleTotalCount++
  285.     }
  286.  
  287.     # generate HTML for each example
  288.     foreach ( $example in $exampleXml.examples.example )
  289.     {
  290.         if ( $example.code -and $example.code.get_InnerText().Trim() -ne "" )
  291.         {
  292.             if ( $exampleHtml -ne "" )
  293.             {
  294.                 $exampleHtml += "        <br />`n"
  295.             }
  296.    
  297.             if ( $exampleTotalCount -gt 1 )
  298.             {
  299.                 $exampleHtml +=
  300.                     "        <nobr><span class=`"boldtext`">Example $( $exampleCount + 1 )</span></nobr>`n"
  301.             }
  302.    
  303.             $exampleCodeHtml = "$( Html-Encode $example.introduction.get_InnerText().Trim() )" +
  304.                 "$( Html-Encode $example.code.get_InnerText().Trim() )"
  305.            
  306.             $exampleHtml += "        <div class=`"syntaxregion`">$exampleCodeHtml</div>`n"
  307.  
  308.             $foundFirstPara = $false
  309.    
  310.             foreach ( $para in $example.remarks.para )
  311.             {
  312.                 if ( $para.get_InnerText().Trim() -ne "" )
  313.                 {
  314.                     # the first para is generally the description of the example.
  315.                     # other para tags usually contain sample output
  316.                     if ( !$foundFirstPara )
  317.                     {
  318.                         $exampleHtml += @"
  319.         <div id="contenttext">
  320.           <p>
  321.             $( Html-Encode $para.get_InnerText().Trim() )
  322.           </p>
  323.         </div>
  324. "@
  325.                         $foundFirstPara = $true
  326.                     }
  327.                     else
  328.                     {
  329.                         $exampleHtml += @"
  330.         <pre class="syntaxregion">$( $( ( Html-Encode $para.get_InnerText().Trim() )  -replace "&lt;br /&gt;", "`n" ) )</pre>
  331. "@
  332.                     }
  333.                 }
  334.             }
  335.    
  336.             $exampleCount++
  337.         }
  338.     }
  339.  
  340.     $exampleHtml.Trim()
  341.     $exampleCount
  342. }
  343.  
  344. function Get-TaskExampleHtml( [xml] $exampleXml )
  345. {
  346.     $exampleHtml = ""
  347.     $exampleCount = 0
  348.     $exampleTotalCount = 0
  349.  
  350.     foreach ( $example in $exampleXml.examples.example )
  351.     {
  352.         $exampleTotalCount++
  353.     }
  354.  
  355.     # generate HTML for each example
  356.     foreach ( $example in $exampleXml.examples.example )
  357.     {
  358.         if ( $exampleHtml -ne "" )
  359.         {
  360.             $exampleHtml += "        <br />`n"
  361.         }
  362.  
  363.         if ( $exampleTotalCount -gt 1 )
  364.         {
  365.             $exampleHtml += "        <nobr><span class=`"boldtext`">Example $( $exampleCount + 1 )</span></nobr>`n"
  366.         }
  367.  
  368.         $exampleHtml += "        <div>$( Get-ParagraphedHtml $example.introduction.get_InnerXml().Trim() )</div>`n"
  369.        
  370.         $exampleCodeHtml = ( Html-Encode $example.code.Trim() ) -replace "<br />", "`n"
  371.  
  372.         $exampleHtml += "        <pre class=`"syntaxregion`">$exampleCodeHtml</pre>"
  373.  
  374.         $exampleHtml += "        <div>$( Get-ParagraphedHtml $example.remarks.get_InnerXml().Trim() )</div>`n"
  375.  
  376.         $exampleCount++
  377.     }
  378.  
  379.     $exampleHtml.Trim()
  380. }
  381.  
  382. function Get-LinkHtml( [xml] $linkXml )
  383. {
  384.     $linkHtml = ""
  385.     $linkCount = 0
  386.  
  387.     # generate HTML for each related link
  388.     foreach ( $navigationLink in $linkXml.relatedLinks.navigationLink )
  389.     {
  390.         if ( $navigationLink.linkText -and `
  391.             ( $helpHash.Keys | Foreach-Object { $_.ToUpper() } ) -contains $navigationLink.linkText.Trim().ToUpper() )
  392.         {
  393.             $linkHtml += "        $( $navigationLink.linkText.Trim() )<br />`n"
  394.             $linkCount++
  395.         }
  396.     }
  397.  
  398.     $linkHtml.Trim()
  399.     $linkCount
  400. }
  401.  
  402. function Get-TaskHtml( [xml] $taskXml )
  403. {
  404.     $taskHtml = ""
  405.     $taskCount = 0
  406.  
  407.     foreach ( $task in $taskXml.tasks.task )
  408.     {
  409.         if ( $taskHtml -ne "" )
  410.         {
  411.             $taskHtml += "        <br />`n"
  412.         }
  413.  
  414.         $taskHtml += "        <nobr><span class=`"boldtext`">Task:</span> $( $task.title.Trim() )</nobr>`n"
  415.        
  416.         $taskDescriptionHtml = ( Get-ParagraphedHtml $task.description.get_InnerXml().Trim() )
  417.        
  418.         $taskHtml += "        <div id=`"contenttext`">$taskDescriptionHtml</div>`n"
  419.  
  420.         # add the example sections
  421.         if ( $task.examples )
  422.         {
  423.             $taskHtml += @"
  424.         <div id="contenttext">
  425.           <p>
  426.             $( Get-TaskExampleHtml ( [xml]$task.examples.get_OuterXml() ) )
  427.           </p>
  428.         </div>
  429.    
  430. "@
  431.         }
  432.  
  433.         $taskCount++
  434.     }
  435.    
  436.     $taskHtml.Trim()
  437.     $taskCount
  438. }
  439.  
  440. function Get-DynamicParameterHtml( [xml] $dynamicParameterXml )
  441. {
  442.     $dynamicParameterHtml = ""
  443.    
  444.     # generate HTML for each dynamic parameter
  445.     foreach ( $dynamicParameter in $dynamicParameterXml.dynamicparameters.dynamicparameter )
  446.     {
  447.         $dynamicParameterHtml += "        <nobr><span class=`"boldtext`">-$( $dynamicParameter.name.Trim() )"
  448.  
  449.         if ( $dynamicParameter.type )
  450.         {
  451.             $dynamicParameterHtml += " &lt;$( $dynamicParameter.type.name.Trim() )&gt;"
  452.         }
  453.  
  454.         $dynamicParameterHtml += "</span></nobr>`n"
  455.  
  456.         $dynamicParameterHtml += @"
  457.         <br />
  458.         <div id="contenttext">
  459.           <p>
  460.             $( Html-Encode $dynamicParameter.description.Trim() )
  461.           </p>
  462. "@
  463.         if ( $dynamicParameter.possiblevalues )
  464.         {
  465.             foreach ( $possibleValue in $dynamicParameter.possiblevalues.possiblevalue )
  466.             {
  467.                 $dynamicParameterHtml += @"
  468.           <div id="contenttext">
  469.             <span class=`"boldtext`">$( $possibleValue.value )</span>
  470.             <div id="contenttext">
  471.               $( Get-ParagraphedHtml $possibleValue.description.get_InnerXml().Trim() )
  472.             </div>
  473.           </div>
  474. "@
  475.             }
  476.         }
  477.  
  478.         $dynamicParameterHtml += @"
  479.           <br />
  480.           <span class=`"boldtext`">Cmdlets Supported</span>
  481.           <div id="contenttext">
  482.             <p>
  483.               $( Html-Encode $dynamicParameter.cmdletsupported.Trim() )
  484.             </p>
  485.           </div>
  486.         </div>
  487.         <br />
  488. "@
  489.     }
  490.  
  491.     $dynamicParameterHtml.Trim()
  492. }
  493.  
  494. function Write-AboutTopic( [string] $topicName, [string] $topicPath )
  495. {
  496.     # just dump the contents of the about topic exactly as it is.  the only changes needed
  497.     # are to encode the special HTML characters and add topic links
  498.     $topicHtml = @"
  499. <html>
  500.   <head>
  501.     <link rel="stylesheet" type="text/css" href="powershell.css" />
  502.     <title>About $( Capitalize-Words ( $topicName -replace "(about)?_", " " ).Trim() )</title>
  503.   </head>
  504.   <body>
  505.     <div id="topicheading">
  506.       <div id="topictitle">PowerShell Help</div>
  507.       About $( Capitalize-Words ( $topicName -replace "(about)?_", " " ).Trim() )
  508.     </div>
  509.     <pre>
  510. $( ( Html-Encode ( [string]::Join( [Environment]::NewLine, ( Get-Content -Path $topicPath ) ) ) ) -replace "&lt;br /&gt;" )
  511.     </pre>
  512.   </body>
  513. </html>
  514. "@
  515.  
  516.     $topicHtml = Add-Links $topicName $topicHtml
  517.  
  518.     Out-File -FilePath "$outDirectory\Topics\$topicName.html" -Encoding Ascii -Input $topicHtml
  519. }
  520.  
  521. function Write-ProviderTopic( [string] $providerFullName, [xml] $providerXml )
  522. {
  523.     $providerName = $providerXml.providerhelp.Name.Trim()
  524.    
  525.     $topicHtml = @"
  526. <html>
  527.   <head>
  528.     <link rel="stylesheet" type="text/css" href="powershell.css" />
  529.     <title>$providerName Help</title>
  530.   </head>
  531.   <body>
  532.     <div id="topicheading">
  533.       <div id="topictitle">PowerShell Help</div>
  534.       $providerName Provider
  535.       <div style="text-align: right; padding-right: 3px;">
  536.          $( $providerFullName -replace "^\w+\." )
  537.       </div>
  538.     </div>
  539.     <div class="categorytitle">Drives</div>
  540.     <div id="contenttext">
  541.       $( Get-ParagraphedHtml $providerXml.providerhelp.drives.get_InnerXml().Trim() )
  542.     </div>
  543.     <div class="categorytitle">Synopsis</div>
  544.     <div id="contenttext">
  545.       <p>$( Html-Encode $providerXml.providerhelp.synopsis.Trim() )</p>
  546.     </div>
  547. "@
  548.    
  549.     $topicHtml += @"
  550.     <div class="categorytitle">Description</div>
  551.     <div id="contenttext">
  552.       $( Get-ParagraphedHtml $providerXml.providerhelp.detaileddescription.get_InnerXml().Trim() )
  553.     </div>
  554. "@
  555.  
  556.     if ( $providerXml.providerhelp.capabilities.get_InnerText().Trim() -ne "" )
  557.     {
  558.         $topicHtml += @"
  559.     <div class="categorytitle">Capabilities</div>
  560.     <div id="contenttext">
  561.       $( Get-ParagraphedHtml $providerXml.providerhelp.capabilities.get_InnerXml().Trim() )
  562.     </div>
  563. "@
  564.     }
  565.  
  566.     $taskHtml, $taskCount = Get-TaskHtml( $providerXml.providerhelp.tasks.get_OuterXml() )
  567.    
  568.     if ( $taskCount -gt 0 )
  569.     {
  570.         $topicHtml += @"
  571.     <div class="categorytitle">Task$( if ( $taskCount -gt 1 ) { "s" } )</div>
  572.     <div id="contenttext">
  573.       $taskHtml
  574.     </div>
  575. "@
  576.     }
  577.  
  578.     if ( $providerXml.providerhelp.dynamicparameters )
  579.     {
  580.         $topicHtml += @"
  581.     <div class="categorytitle">Dynamic Parameters</div>
  582.     <div id="contenttext">
  583.       $( Get-DynamicParameterHtml( $providerXml.providerhelp.dynamicparameters.get_OuterXml() ) )
  584.     </div>
  585. "@
  586.     }
  587.  
  588.     if ( $providerXml.providerhelp.notes.Trim() -ne "" )
  589.     {
  590.         $topicHtml += @"
  591.     <div class="categorytitle">Notes</div>
  592.     <div id="contenttext">
  593.       <p>$( Html-Encode $providerXml.providerhelp.notes.Trim() )</p>
  594.     </div>
  595. "@
  596.     }
  597.  
  598.     $topicHtml += @"
  599.     <div class="categorytitle">Related Links</div>
  600.     <div id="contenttext">
  601.       <p>$( Html-Encode $providerXml.providerhelp.relatedlinks.Trim() )</p>
  602.     </div>
  603.     <br />
  604.   </body>
  605. </html>   
  606. "@   
  607.  
  608.     $topicHtml = Add-Links $providerName $topicHtml
  609.  
  610.     Out-File -FilePath "$outDirectory\Topics\$providerFullName.html" -Encoding Ascii -Input $topicHtml
  611. }
  612.  
  613. function Write-CmdletTopic( [string] $cmdletFullName, [xml] $cmdletXml )
  614. {
  615.     $cmdletName = $cmdletXml.command.details.name.Trim()
  616.    
  617.     # add the heading, syntax section, and description
  618.     $topicHtml = @"
  619. <html>
  620.   <head>
  621.     <link rel="stylesheet" type="text/css" href="powershell.css" />
  622.     <title>$cmdletName Help</title>
  623.   </head>
  624.   <body>
  625.     <div id="topicheading">
  626.       <div id="topictitle">PowerShell Help</div>
  627.       $cmdletName Cmdlet
  628.       <div style="text-align: right; padding-right: 3px;">
  629.          $( $cmdletFullName -replace "^\w+-\w+\." )
  630.       </div>
  631.     </div>
  632.     <div class="categorytitle">Synopsis</div>
  633.     <div id="contenttext">
  634.       $( Get-ParagraphedHtml $cmdletXml.command.details.description.get_InnerXml().Trim() )
  635.     </div>
  636.     <div class="categorytitle">Syntax</div>
  637.     <div id="contenttext">
  638.       <div class="syntaxregion">$( Get-SyntaxHtml ( [xml]$cmdletXml.command.syntax.get_OuterXml() ) )</div>
  639.     </div>
  640.     <div class="categorytitle">Description</div>
  641.     <div id="contenttext">
  642.       $( Get-ParagraphedHtml $cmdletXml.command.description.get_InnerXml().Trim() )
  643.     </div>
  644. "@
  645.  
  646.     # add the parameters section
  647.     if ( $cmdletXml.command.parameters )
  648.     {
  649.         $topicHtml += @"
  650.     <div class="categorytitle">Parameters</div>
  651.     <div id="contenttext">
  652.       <p>
  653.         $( Get-ParameterHtml ( [xml]$cmdletXml.command.parameters.get_OuterXml() ) )
  654.       </p>
  655.     </div>
  656. "@
  657.     }
  658.     else
  659.     {
  660.         $topicHtml += @"
  661.     <div class="categorytitle">Parameters</div>
  662.     <div id="contenttext">
  663.       <p>
  664.        <nobr><span class="boldtext">&lt;CommonParameters&gt;</span></nobr><br />
  665.        <div id="contenttext">
  666.          <p>
  667.             For more information about common parameters, type "Get-Help about_commonparameters".
  668.          </p>
  669.         </div>
  670.       </p>
  671.     </div>
  672. "@
  673.     }
  674.  
  675.     # add the input types section
  676.     if ( $cmdletXml.command.inputTypes )
  677.     {
  678.         $inputHtml, $inputCount = Get-InputHtml ( [xml]$cmdletXml.command.inputTypes.get_OuterXml() )
  679.    
  680.         if ( $inputCount -gt 0 )
  681.         {
  682.             $topicHtml += @"
  683.     <div class="categorytitle">Input Type$( if ( $inputCount -gt 1 ) { "s" } )</div>
  684.     <div id="contenttext">
  685.       $inputHtml
  686.     </div>
  687. "@
  688.         }
  689.     }
  690.  
  691.     # add the return values section
  692.     if ( $cmdletXml.command.returnValue )
  693.     {
  694.         $returnHtml, $returnCount = Get-ReturnHtml ( [xml]$cmdletXml.command.returnValues.get_OuterXml() )
  695.    
  696.         if ( $returnCount -gt 0 )
  697.         {
  698.             $topicHtml += @"
  699.     <div class="categorytitle">Return Value$( if ( $returnCount -gt 1 ) { "s" } )</div>
  700.     <div id="contenttext">
  701.       $returnHtml
  702.     </div>
  703. "@
  704.         }
  705.     }
  706.  
  707.     # add the notes section
  708.     if ( $cmdletXml.command.alertSet )
  709.     {
  710.         if ( $cmdletXml.command.alertSet.get_InnerText().Trim() -ne "" )
  711.         {
  712.             $topicHtml += @"
  713.     <div class="categorytitle">Notes</div>
  714.     <div id="contenttext">
  715.       $( Get-ParagraphedHtml $cmdletXml.command.alertSet.get_InnerXml().Trim() )
  716.     </div>
  717. "@
  718.         }
  719.     }
  720.  
  721.     # add the example section
  722.     if ( $cmdletXml.command.examples )
  723.     {
  724.         $exampleHtml, $exampleCount = Get-ExampleHtml ( [xml]$cmdletXml.command.examples.get_OuterXml() )
  725.  
  726.         if ( $exampleCount -gt 0 )
  727.         {
  728.             $topicHtml += @"
  729.     <div class="categorytitle">Example$( if ( $exampleCount -gt 1 ) { "s" } )</div>
  730.     <div id="contenttext">
  731.       <p>
  732.         $exampleHtml
  733.       </p>
  734.     </div>
  735. "@
  736.         }
  737.     }
  738.  
  739.     # add the related links section
  740.     if ( $cmdletXml.command.relatedLinks )
  741.     {
  742.         $linkHtml, $linkCount = Get-LinkHtml ( [xml]$cmdletXml.command.relatedLinks.get_OuterXml() )
  743.  
  744.         if ( $linkCount -gt 0 )
  745.         {
  746.             $topicHtml += @"
  747.     <div class="categorytitle">Related Link$( if ( $linkCount -gt 1 ) { "s" } )</div>
  748.     <div id="contenttext">
  749.       <p>
  750.         $linkHtml
  751.       </p>
  752.     </div>
  753.     <br />
  754. "@
  755.         }
  756.         else
  757.         {
  758.             $topicHtml +=  "        <br />`n"
  759.         }
  760.     }
  761.     else
  762.     {
  763.         $topicHtml +=  "        <br />`n"
  764.     }
  765.  
  766.     $topicHtml += @"
  767.   </body>
  768. </html>
  769. "@
  770.  
  771.     $topicHtml = Add-Links $cmdletName $topicHtml
  772.  
  773.     Out-File -FilePath "$outDirectory\Topics\$cmdletFullName.html" -Encoding Ascii -Input $topicHtml
  774. }
  775.  
  776. function Add-Links( [string] $topicName, [string] $topicHtml )
  777. {
  778.     # we only want to add links for Cmdlets and about topics
  779.     $helpHash.Keys | Where-Object { $_ -match "(^\w+-\w+|^about_)" } | Foreach-Object {
  780.         $searchText = $_
  781.    
  782.         # keys representing Cmdlets are formatted like this:
  783.         # <Cmdlet Name>.<PSProvider name>
  784.         if ( $_ -match "^\w+-\w+" )
  785.         {
  786.             # we only want to search for the Cmdlet name
  787.             $searchText = $matches[ 0 ]
  788.         }
  789.  
  790.         # if the search text isn't the topic being processed
  791.         if ( $searchText -ne $topicName )
  792.         {
  793.             $topicHtml = $topicHtml -replace "\b($searchText)\b", "<a href=`"Topics\$_.html`"><nobr>`$1</nobr></a>"
  794.         }
  795.     }
  796.  
  797.     $topicHtml
  798. }
  799.  
  800. # file dumping functions
  801.  
  802. function Write-Hhp
  803. {
  804.     # write the contents of the Html Help Project file
  805.     Out-File -FilePath "$outDirectory\powershell.hhp" -Encoding Ascii -Input @"
  806. [OPTIONS]
  807. Binary TOC=Yes
  808. Compatibility=1.1 or later
  809. Compiled file=PowerShell.chm
  810. Contents file=powershell.hhc
  811. Default topic=Topics/default.html
  812. Full-text search=Yes
  813. Language=0x409 English (United States)
  814. Title=PowerShell Help
  815. [INFOTYPES]
  816. "@
  817. }
  818.  
  819. function Write-DefaultPage
  820. {