Initial Commit

This commit is contained in:
DrIOS
2024-03-25 08:34:43 -05:00
commit 0226b293b5
137 changed files with 9448 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
---
Module Name: ADAuditTasks
Module Guid: '7ddb359a-e07f-4be0-b63a-a81f44c61fff'
Download Help Link: https://audittaskshelpfiles.blob.core.windows.net/helpfiles/
Help Version: 1.0.0.5
Locale: en-US
---
# ADAuditTasks Module
## Description
{{ Fill in the Description }}
## ADAuditTasks Cmdlets
### [Convert-NmapXMLToCSV](Convert-NmapXMLToCSV)
Converts an Nmap XML scan output file to a CSV file.
### [Get-ADActiveUserAudit](Get-ADActiveUserAudit)
Gets active but stale AD User accounts that haven't logged in within the last 90 days by default.
### [Get-ADHostAudit](Get-ADHostAudit)
Active Directory Server and Workstation Audit with Report export option (Can also be piped to CSV if Report isn't specified).
### [Get-ADUserLogonAudit](Get-ADUserLogonAudit)
Retrieves the most recent LastLogon timestamp for a specified Active Directory user
account from all domain controllers and outputs it as a DateTime object.
### [Get-ADUserPrivilegeAudit](Get-ADUserPrivilegeAudit)
Produces three object outputs: PrivilegedGroups, AdExtendedRights, and possible service accounts.
### [Get-ADUserWildCardAudit](Get-ADUserWildCardAudit)
Takes a search string to find commonly named accounts.
### [Get-HostTag](Get-HostTag)
Creates a host name or tag based on predetermined criteria for as many as 999 hosts at a time.
### [Get-NetworkAudit](Get-NetworkAudit)
Discovers the local network and runs port scans on all hosts found for specific or default sets of ports, displaying MAC ID vendor info.
### [Get-QuickPing](Get-QuickPing)
Performs a quick ping on a range of IP addresses and returns an array of IP addresses
that responded to the ping and an array of IP addresses that failed to respond.
### [Get-WebCertAudit](Get-WebCertAudit)
Retrieves the certificate information for a web server.
### [Join-CSVFile](Join-CSVFile)
Joins multiple CSV files with the same headers into a single CSV file.
### [Merge-ADAuditZip](Merge-ADAuditZip)
Combines multiple audit report files into a single compressed ZIP file.
### [Merge-NmapToADHostAudit](Merge-NmapToADHostAudit)
Merges Nmap network audit data with Active Directory host audit data.
### [Send-AuditEmail](Send-AuditEmail)
This is a wrapper function for Send-MailKitMessage and takes string arrays as input.
### [Submit-FTPUpload](Submit-FTPUpload)
Uploads a file to an FTP server using the WinSCP module.

View File

@@ -0,0 +1,21 @@
Microsoft Public License (MS-PL)
This license governs use of the accompanying software. If you use the software, you
accept this license. If you do not accept the license, do not use the software.
1. Definitions
The terms "reproduce," "reproduction," "derivative works," and "distribution" have the
same meaning here as under U.S. copyright law.
A "contribution" is the original software, or any additions or changes to the software.
A "contributor" is any person that distributes its contribution under this license.
"Licensed patents" are a contributor's patent claims that read directly on its contribution.
2. Grant of Rights
(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
3. Conditions and Limitations
(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.

View File

@@ -0,0 +1,20 @@
psDoc is a Powershell Help Document generator.
----
### Using psDoc ###
To generate documentation off of your module, simply import your module
```
Import-Module MySpecialModule
```
And generate the documentation
```
.\psDoc.ps1 -moduleName MySpecialModule
```
### License ###
[Microsoft Public License (Ms-PL)](https://opensource.org/licenses/MS-PL)

View File

@@ -0,0 +1,194 @@
function TrimAllLines([string] $str) {
$lines = $str -split "`n"
for ($i = 0; $i -lt $lines.Count; $i++) {
$lines[$i] = $lines[$i].Trim()
}
# Trim EOL.
($lines | Out-String).Trim()
}
function FixMarkdownString([string] $in = '', [bool] $includeBreaks = $false, [bool]$BlankStringToSpace = $False) {
if ($in -eq $null) { return }
if($in -eq "" -and $BlankStringToSpace ) { return " " }
$replacements = @{
'\' = '\\'
'`' = '\`'
'*' = '\*'
'_' = '\_'
'{' = '\{'
'}' = '\}'
'[' = '\['
']' = '\]'
'(' = '\('
')' = '\)'
'#' = '\#'
'+' = '\+'
'!' = '\!'
}
$rtn = $in.Trim()
foreach ($key in $replacements.Keys) {
$rtn = $rtn.Replace($key, $replacements[$key])
}
$rtn = TrimAllLines $rtn
if ($includeBreaks) {
$crlf = [Environment]::NewLine
$rtn = $rtn.Replace($crlf, " $crlf")
}
$rtn
}
function FixMarkdownCodeString([string] $in) {
if ($in -eq $null) { return }
TrimAllLines $in
}
function IncludeTableOfContents {
return "{toc:printable=true|style=square|maxLevel=2|indent=5px|minLevel=2|class=bigpink|exclude=[1//2]|type=list|outline=true|include=.*}"
}
@"
h1. $moduleName
$(IncludeTableOfContents)
\\
\\
"@
$progress = 0
$commandsHelp | % {
Update-Progress $_.Name 'Documentation'
$progress++
@"
h2. $(FixMarkdownString($_.Name))
"@
$synopsis = $_.synopsis.Trim()
$syntax = $_.syntax | out-string
if(-not ($synopsis -ilike "$($_.Name.Trim())*")){
$tmp = $synopsis
$synopsis = $syntax
$syntax = $tmp
@"
h3. Synopsis
$(FixMarkdownString($syntax))
"@
}
@"
h3. Description
$(FixMarkdownString $(($_.Description | out-string).Trim()) $true)
"@
@"
h3. Syntax
{code:theme=Confluence|linenumbers=false|language=Powershell|firstline=0001|collapse=false}
$(TrimAllLines $synopsis)
{code}
"@
if (!($_.alias.Length -eq 0)) {
@"
h3. $($_.Name) Aliases
"@
$_.alias | % {
@"
- $($_.Name)
"@
}
@"
"@
}
if($_.parameters){
@"
h3. Parameters
||Name||Alias||Description||Required?||Pipeline Input||Default Value||
"@
$_.parameters.parameter | % {
@"
|$(FixMarkdownString $_.Name $false $true)|$(FixMarkdownString $_.Aliases $false $true)|$(FixMarkdownString $($_.Description | out-string).Trim() $true $true)|$(FixMarkdownString $_.Required $false $true)|$(FixMarkdownString $_.PipelineInput $false $true)|$(FixMarkdownString $_.DefaultValue $false $true)|
"@
}
@"
"@
}
$inputTypes = $(FixMarkdownString($_.inputTypes | out-string))
if ($inputTypes.Length -gt 0 -and -not $inputTypes.Contains('inputType')) {
@"
h3. Inputs
- $inputTypes
"@
}
$returnValues = $(FixMarkdownString($_.returnValues | out-string))
if ($returnValues.Length -gt 0 -and -not $returnValues.StartsWith("returnValue")) {
@"
h3. Outputs
- $returnValues
"@
}
$notes = $(FixMarkdownString($_.alertSet | out-string))
if ($notes.Trim().Length -gt 0) {
@"
h3. Note
$notes
"@
}
if(($_.examples | Out-String).Trim().Length -gt 0) {
@"
h3. Examples
"@
$_.examples.example | % {
@"
{code:title=$(FixMarkdownString($_.title.Trim(('-',' '))))|theme=Confluence|linenumbers=true|language=Powershell|firstline=0001|collapse=false}
$(FixMarkdownCodeString($_.code | out-string ))
{code}
$(FixMarkdownString($_.remarks | out-string ) $true)
"@
}
}
if(($_.relatedLinks | Out-String).Trim().Length -gt 0) {
@"
h3. Links
"@
$_.links | % {
@"
- [$($_.name)|$($_.link)]
"@
}
}
@"
\\
\\
\\
----
\\
\\
\\
"@
}

View File

@@ -0,0 +1,346 @@
@"
<!DOCTYPE html>
<!--
<auto-generated>
<synopsis>
This code was generated by a tool. on: $(Get-Date)
</synopsis>
<description>
If you'd like to regenerate the documentation, please open up powershell and run
> .\psDoc.ps1 -moduleName NameOfYourModule
If the documentation is incomplete, or eronious,
please edit the comments at the top of the module method within it's respecive .ps1 file.
</description>
</auto-generated>
-->
<html lang="en">
<head>
<title>$moduleName Documentation</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link href="https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shCore.min.css" rel="stylesheet" charset="utf-8">
<link href="https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shCoreDefault.min.css" rel="stylesheet" charset="utf-8">
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet" charset="utf-8">
<!-- 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]-->
<style>
.syntaxhighlighter {
overflow-y: hidden !important;
overflow-x: auto !important;
}
pre {
min-height: 30px;
}
.navbar-nav {
height: 100%;
overflow-y: auto;
}
.form-group {
padding-top: 12px;
padding-left: 12px;
padding-right: 12px;
}
.sidebar-nav .navbar-header {
float: none;
}
.sidebar-nav .navbar li a {
padding-top: 4px;
padding-bottom: 4px;
}
@media (min-width: 768px) {
.sidebar-nav .navbar .navbar-collapse {
padding: 0;
max-height: none;
}
.sidebar-nav .navbar ul {
float: none;
}
.sidebar-nav .navbar ul:not {
display: block;
}
.sidebar-nav .navbar li {
float: none;
display: block;
}
}
</style>
</head>
<body>
<div class="container-fluid">
<div class="row-fluid">
<div><h1>$moduleName</h1></div>
</div>
<div class="row-fluid">
<div class="col-lg-3 col-md-4 col-sm-5 col-xs-12">
<div class="sidebar-nav">
<div class="navbar navbar-default" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".sidebar-navbar-collapse">
<span class="sr-only">Toggle</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<span class="visible-xs navbar-brand">click menu to open</span>
</div>
<div class="navbar-collapse collapse sidebar-navbar-collapse">
<div class="form-group">
<input class="form-control" id="searchinput" type="search" placeholder="Filter..." />
</div>
<ul class="nav navbar-nav list-group" id="searchList">
"@
$progress = 0
$commandsHelp | % {
Update-Progress $_.Name 'Navigation'
$progress++
" <li class=`"nav-menu list-group-item`"><a href=`"#$($_.Name)`">$($_.Name)</a></li>"
}
@'
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
</div>
<div class="col-lg-9 col-md-8 col-sm-7 col-xs-12">
'@
$progress = 0
$commandsHelp | % {
Update-Progress $_.Name 'Documentation'
$progress++
@"
<div id=`"$(FixString($_.Name))`" class="toggle_container">
<div class="page-header">
<h2> $(FixString($_.Name)) </h2>
"@
$syn = FixString($_.synopsis)
if(!($syn).StartsWith($(FixString($_.Name)))){
@"
<p>$syn</p>
<p>$(FixString(($_.Description | out-string).Trim()) $true)</p>
"@
}
@"
</div>
"@
if (!($_.alias.Length -eq 0)) {
@"
<div class='panel panel-default'>
<div class='panel-heading'>
<h3 class='panel-title'> $($_.Name) Aliases </h3>
</div>
<div class='panel-body'>
<ul>
"@
$_.alias | % {
@"
<li>$($_.Name)</li>
"@
}
@"
</ul>
</div>
</div>
"@
}
if (!($_.syntax | Out-String ).Trim().Contains('syntaxItem')) {
@"
<div>
<h3> Syntax </h3>
</div>
<div class="panel panel-default">
<div class='panel-body'>
<pre class="brush: ps">$(FixString($_.syntax | out-string))</pre>
</div>
</div>
"@
}
if($_.parameters){
@"
<div>
<h3> Parameters </h3>
<table class="table table-striped table-bordered table-condensed visible-on">
<thead>
<tr>
<th>Name</th>
<th class="visible-lg visible-md">Alias</th>
<th>Description</th>
<th class="visible-lg visible-md">Required?</th>
<th class="visible-lg">Pipeline Input</th>
<th class="visible-lg">Default Value</th>
</tr>
</thead>
<tbody>
"@
$_.parameters.parameter | % {
@"
<tr>
<td><nobr>-$(FixString($_.Name))</nobr></td>
<td class="visible-lg visible-md">$(FixString($_.Aliases))</td>
<td>$(FixString(($_.Description | out-string).Trim()) $true)</td>
<td class="visible-lg visible-md">$(FixString($_.Required))</td>
<td class="visible-lg">$(FixString($_.PipelineInput))</td>
<td class="visible-lg">$(FixString($_.DefaultValue))</td>
</tr>
"@
}
@"
</tbody>
</table>
</div>
"@
}
$inputTypes = $(FixString($_.inputTypes | out-string))
if ($inputTypes.Length -gt 0 -and -not $inputTypes.Contains('inputType')) {
@"
<div>
<h3> Inputs </h3>
<p>The input type is the type of the objects that you can pipe to the cmdlet.</p>
<ul><li>$inputTypes</li></ul>
</div>
"@
}
$returnValues = $(FixString($_.returnValues | out-string))
if ($returnValues.Length -gt 0 -and -not $returnValues.StartsWith("returnValue")) {
@"
<div>
<h3> Outputs </h3>
<p>The output type is the type of the objects that the cmdlet emits.</p>
<ul><li>$returnValues</li></ul>
</div>
"@
}
$notes = $(FixString($_.alertSet | out-string))
if ($notes.Trim().Length -gt 0) {
@"
<div class='panel panel-default'>
<div class='panel-heading'>
<h3 class='panel-title'> Note </h3>
</div>
<div class='panel-body'>$notes</div>
</div>
"@
}
if(($_.examples | Out-String).Trim().Length -gt 0) {
@"
<div>
<h3> Examples </h3>
</div>
<div class='panel panel-default'>
<div class='panel-body'>
"@
$_.examples.example | % {
@"
<strong>$(FixString($_.title.Trim(('-',' '))))</strong>
<pre class="brush: ps">$(FixString($_.code | out-string ).Trim())</pre>
<div>$(FixString($_.remarks | out-string ).Trim())</div>
"@
}
@"
</div>
</div>
<p class='pull-right'><a onclick='document.body.scrollTop = document.documentElement.scrollTop = 0;' style='cursor: pointer;'>Top of page</a>
"@
}
if(($_.relatedLinks | Out-String).Trim().Length -gt 0) {
@"
<div>
<h3> Links </h3>
<div>
<ul>
"@
$_.links | % {
@"
<li class='$($_.cssClass)'><a href='$($_.link)' target='$($_.target)'>$($_.name)</a></li>
"@
}
@"
</ul>
</div>
</div>
"@
}
@"
</div>
"@
}
@'
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js" ></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/js/bootstrap.min.js" charset="utf-8"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shCore.min.js" charset="utf-8"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushPowerShell.min.js" charset="utf-8"></script>
<script>
$(document).ready(function() {
$(".toggle_container").hide();
var previousId;
if(location.hash) {
var id = location.hash.slice(1); //Get rid of the # mark
var elementToShow = $("#" + id); //Save local reference
if(elementToShow.length) { //Check if the element exists
elementToShow.slideToggle('fast'); //Show the element
elementToShow.addClass("check_list_selected"); //Add class to element (the link)
}
previousId = id;
}
$('.nav-menu a, .psLink a').click(function() {
$(".sidebar-navbar-collapse").collapse('hide');
$('.toggle_container').hide(); // Hide all
var elem = $(this).prop("hash");
$(elem).toggle('fast'); // Show HREF/to/ID one
history.pushState({}, '', $(this).attr("href"));
window.scrollTo(0, 0);
return false;
});
SyntaxHighlighter.defaults['toolbar'] = false;
SyntaxHighlighter.defaults['gutter'] = false;
SyntaxHighlighter.all();
$('#searchList').btsListFilter('#searchinput', {itemChild: 'a', initial: false, resetOnBlur: true});
$(document).keyup(function( e ) {
if(!$('#searchinput').is(':focus') && e.which >= 65 && e.which <= 90 ){
$('#searchinput').val(String.fromCharCode(e.keyCode));
$('#searchinput').focus();
}
});
$(document).click(function() {
$('#searchinput').blur();
});
});
</script>
<!-- bootstrap-list-filter.min.js - removed as external resource and added as content -->
<script>
/*
* bootstrap-list-filter v0.1.7 - 2015-03-30
*
* Copyright 2015 Stefano Cudini
* stefano.cudini@gmail.com
* http://labs.easyblog.it/
*
* Licensed under the MIT license.
*
* Demos:
* http://labs.easyblog.it/bootstrap-list-filter/
*
* Source:
* git@github.com:stefanocudini/bootstrap-list-filter.git
*
*/
!function(a){a.fn.btsListFilter=function(b,c){function d(a,b){return a.replace(/\{ *([\w_]+) *\}/g,function(a,c){return b[c]||""})}function e(a,b){var c;return b=b||300,function(){var d=this,e=arguments;clearTimeout(c),c=setTimeout(function(){a.apply(d,Array.prototype.slice.call(e))},b)}}var f,g=this,h=a(this),i=a(b),j=h;return c=a.extend({delay:300,minLength:1,initial:!0,eventKey:"keyup",resetOnBlur:!0,sourceData:null,sourceTmpl:'<a class="list-group-item" href="#"><span>{title}</span></a>',sourceNode:function(a){return d(c.sourceTmpl,a)},emptyNode:function(){return'<a class="list-group-item well" href="#"><span>No Results</span></a>'},itemEl:".list-group-item",itemChild:null,itemFilter:function(b,d){d=d&&d.replace(new RegExp("[({[^.$*+?\\]})]","g"),"");var e=a(b).text(),f=c.initial?"^":"",g=new RegExp(f+d,"i");return g.test(e)}},c),i.on(c.eventKey,e(function(){var b=a(this).val();c.itemEl&&(j=h.find(c.itemEl)),c.itemChild&&(j=j.find(c.itemChild));var d=j.filter(function(){return c.itemFilter.call(g,this,b)}),e=j.not(d);c.itemChild&&(d=d.parents(c.itemEl),e=e.parents(c.itemEl).hide()),""!==b&&b.length>=c.minLength?(d.show(),e.hide(),"function"===a.type(c.sourceData)?(d.hide(),e.hide(),f&&(a.isFunction(f.abort)?f.abort():a.isFunction(f.stop)&&f.stop()),f=c.sourceData.call(g,b,function(b){if(f=null,d.hide(),e.hide(),h.find(".bts-dynamic-item").remove(),b&&0!==b.length)for(var i in b)a(c.sourceNode.call(g,b[i])).addClass("bts-dynamic-item").appendTo(h);else a(c.emptyNode.call(g)).addClass("bts-dynamic-item").appendTo(h)})):0===d.length&&a(c.emptyNode.call(g)).addClass("bts-dynamic-item").appendTo(h)):(d.show(),e.show(),h.find(".bts-dynamic-item").remove())},c.delay)),c.resetOnBlur&&i.on("blur",function(){a(this).val("").trigger(c.eventKey)}),h}}(jQuery);
</script>
</body>
</html>
'@

View File

@@ -0,0 +1,159 @@
function TrimAllLines([string] $str) {
$lines = $str -split "`n"
for ($i = 0; $i -lt $lines.Count; $i++) {
$lines[$i] = $lines[$i].Trim()
}
# Trim EOL.
($lines | Out-String).Trim()
}
function FixMarkdownString([string] $in = '', [bool] $includeBreaks = $false) {
if ($in -eq $null) { return }
$replacements = @{
'\' = '\\'
'`' = '\`'
'*' = '\*'
'_' = '\_'
'{' = '\{'
'}' = '\}'
'[' = '\['
']' = '\]'
'(' = '\('
')' = '\)'
'#' = '\#'
'+' = '\+'
'!' = '\!'
'<' = '\<'
'>' = '\>'
}
$rtn = $in.Trim()
foreach ($key in $replacements.Keys) {
$rtn = $rtn.Replace($key, $replacements[$key])
}
$rtn = TrimAllLines $rtn
$crlf = [Environment]::NewLine
if ($includeBreaks) {
$rtn = $rtn.Replace($crlf, " $crlf")
}
else {
$rtn = $rtn.Replace($crlf, " ").Trim()
}
$rtn
}
function FixMarkdownCodeString([string] $in) {
if ($in -eq $null) { return }
TrimAllLines $in
}
@"
# $moduleName Module
"@
$progress = 0
$commandsHelp | % {
Update-Progress $_.Name 'Documentation'
$progress++
@"
## $(FixMarkdownString($_.Name))
"@
$synopsis = $_.synopsis.Trim()
$syntax = $_.syntax | out-string
if (-not ($synopsis -ilike "$($_.Name.Trim())*")) {
$tmp = $synopsis
$synopsis = $syntax
$syntax = $tmp
@"
### Synopsis
$(FixMarkdownString($syntax))
"@
}
@"
### Syntax
``````powershell
$($synopsis)
``````
"@
if (!($_.alias.Length -eq 0)) {
@"
### $($_.Name) Aliases
"@
$_.alias | % {
@"
- $($_.Name)
"@
}
@"
"@
}
if ($_.parameters) {
@"
### Parameters
| Name | Alias | Description | Required? | Pipeline Input | Default Value |
| - | - | - | - | - | - |
"@
$_.parameters.parameter | % {
@"
| <nobr>$(FixMarkdownString($_.Name))</nobr> | $(FixMarkdownString($_.Aliases)) | $(FixMarkdownString(($_.Description | out-string).Trim())) | $(FixMarkdownString($_.Required)) | $(FixMarkdownString($_.PipelineInput)) | $(FixMarkdownString($_.DefaultValue)) |
"@
}
}
$inputTypes = $(FixMarkdownString($_.inputTypes | out-string))
if ($inputTypes.Length -gt 0 -and -not $inputTypes.Contains('inputType')) {
@"
### Inputs
- $inputTypes
"@
}
$returnValues = $(FixMarkdownString($_.returnValues | out-string))
if ($returnValues.Length -gt 0 -and -not $returnValues.StartsWith("returnValue")) {
@"
### Outputs
- $returnValues
"@
}
$notes = $(FixMarkdownString($_.alertSet | out-string))
if ($notes.Trim().Length -gt 0) {
@"
### Note
$notes
"@
}
if (($_.examples | Out-String).Trim().Length -gt 0) {
@"
### Examples
"@
$_.examples.example | % {
@"
**$(FixMarkdownString($_.title.Trim(('-',' '))))**
``````powershell
$(FixMarkdownCodeString($_.code | out-string ))
``````
$(FixMarkdownString($_.remarks | out-string ) $true)
"@
}
}
if (($_.relatedLinks | Out-String).Trim().Length -gt 0) {
@"
### Links
"@
$_.links | % {
@"
- [$($_.name)]($($_.link))
"@
}
}
}

View File

@@ -0,0 +1,63 @@
param(
[parameter(Mandatory=$true, Position=0)] [string] $moduleName,
[parameter(Mandatory=$false, Position=1)] [string] $template = "./out-html-template.ps1",
[parameter(Mandatory=$false, Position=2)] [string] $outputDir = './help',
[parameter(Mandatory=$false, Position=3)] [string] $fileName = 'index.html'
)
function FixString ($in = '', [bool]$includeBreaks = $false){
if ($in -eq $null) { return }
$rtn = $in.Replace('&', '&amp;').Replace('<', '&lt;').Replace('>', '&gt;').Trim()
if($includeBreaks){
$rtn = $rtn.Replace([Environment]::NewLine, '<br>')
}
return $rtn
}
function Update-Progress($name, $action){
Write-Progress -Activity "Rendering $action for $name" -CurrentOperation "Completed $progress of $totalCommands." -PercentComplete $(($progress/$totalCommands)*100)
}
$i = 0
$commandsHelp = (Get-Command -module $moduleName) | get-help -full | Where-Object {! $_.name.EndsWith('.ps1')}
foreach ($h in $commandsHelp){
$cmdHelp = (Get-Command $h.Name)
# Get any aliases associated with the method
$alias = get-alias -definition $h.Name -ErrorAction SilentlyContinue
if($alias){
$h | Add-Member Alias $alias
}
# Parse the related links and assign them to a links hashtable.
if(($h.relatedLinks | Out-String).Trim().Length -gt 0) {
$links = $h.relatedLinks.navigationLink | % {
if($_.uri){ @{name = $_.uri; link = $_.uri; target='_blank'} }
if($_.linkText){ @{name = $_.linkText; link = "#$($_.linkText)"; cssClass = 'psLink'; target='_top'} }
}
$h | Add-Member Links $links
}
# Add parameter aliases to the object.
foreach($p in $h.parameters.parameter ){
$paramAliases = ($cmdHelp.parameters.values | where name -like $p.name | select aliases).Aliases
if($paramAliases){
$p | Add-Member Aliases "$($paramAliases -join ', ')" -Force
}
}
}
# Create the output directory if it does not exist
if (-Not (Test-Path $outputDir)) {
New-Item -Path $outputDir -ItemType Directory | Out-Null
}
$totalCommands = $commandsHelp.Count
if (!$totalCommands) {
$totalCommands = 1
}
$template = Get-Content $template -raw -force
Invoke-Expression $template > "$outputDir\$fileName"