functions/powershell/module/Export-FunctionDocs.ps1
function Export-FunctionDocs { <# .SYNOPSIS Exports Markdown documentation files for PowerShell functions from a source directory. .DESCRIPTION This function recursively scans a directory for `.ps1` files, filters them using an optional `exclude-files.json`, dot-sources each script, and generates one `.md` file per function using PlatyPS-style help content. The content is extracted using the helper function `Get-HelpContent`. Each `.md` file contains sections such as SYNOPSIS, DESCRIPTION, PARAMETERS, EXAMPLES, NOTES, and LINKS based on the parsed help content of each function. .PARAMETER SourcePath The root path to recursively search for `.ps1` function files. .PARAMETER OutputPath The target folder where `.md` documentation files will be saved. If the path does not exist, it will be created automatically. .EXAMPLE Export-FunctionDocs -SourcePath "C:\Repo\MyModule" -OutputPath "C:\Docs\MyModule" Exports all functions from `.ps1` files under `C:\Repo\MyModule`, excluding those listed in `exclude-files.json`, and writes `.md` documentation files to `C:\Docs\MyModule`. .NOTES • All `.ps1` files are dot-sourced during execution – invalid or broken files will trigger warnings. • Each function is written to its own `.md` file using Markdown syntax. .LINK Get-HelpContent Get-FilteredFiles #> [CmdletBinding()] param ( [Parameter(Mandatory)] [string]$SourcePath, [Parameter(Mandatory)] [string]$OutputPath ) $SourcePath = (Resolve-Path -Path $SourcePath).Path Write-Verbose "Suche nach .ps1-Dateien in $SourcePath" $allPs1Files = Get-ChildItem -Path $SourcePath -Recurse -Filter *.ps1 $filteredFiles = Get-FilteredFiles -Files $allPs1Files -ExcludeListFile (Join-Path -Path $SourcePath -ChildPath 'exclude-files.json') -RootPath $SourcePath if (-not (Test-Path $OutputPath)) { New-Item -Path $OutputPath -ItemType Directory -Force | Out-Null } foreach ($file in $filteredFiles) { Write-Verbose "Analysiere Datei: $($file.FullName)" try { . $file.FullName } catch { Write-Warning "Fehler beim Dot-Sourcing der Datei '$($file.FullName)': $_" continue } $functions = Get-Command -CommandType Function | Where-Object { $_.ScriptBlock.File -eq $file.FullName } foreach ($func in $functions) { $funcName = $func.Name Write-Verbose "Verarbeite Funktion: $funcName" try { $helpContent = Get-HelpContent -FilePath $file.FullName -FunctionName $funcName if (-not $helpContent.SYNOPSIS) { Write-Warning "Funktion '$funcName' hat keine .SYNOPSIS-Dokumentation." continue } $mdPath = Join-Path $OutputPath "$funcName.md" Write-Verbose "Erstelle Dokumentation: $mdPath" $lines = @() $lines += "# $funcName" $lines += "" $lines += "## SYNOPSIS" $lines += $helpContent.SYNOPSIS $lines += "" if ($helpContent.DESCRIPTION) { $lines += "## DESCRIPTION" $lines += $helpContent.DESCRIPTION $lines += "" } if ($helpContent.PARAMETER.Keys.Count -gt 0) { $lines += "## PARAMETERS" foreach ($param in $helpContent.PARAMETER.GetEnumerator()) { $lines += "### -$($param.Key)" $lines += $param.Value -split "`r?`n" | ForEach-Object { " $_" } $lines += "" } } if ($helpContent.EXAMPLE) { $lines += "## EXAMPLES" $lines += ($helpContent.EXAMPLE -split "(?m)^\s*$") | ForEach-Object { '```powershell' $_.Trim() '```' '' } } if ($helpContent.NOTES) { $lines += "## NOTES" $lines += $helpContent.NOTES $lines += "" } if ($helpContent.LINK) { $lines += "## LINKS" $lines += $helpContent.LINK $lines += "" } $lines += "---" $lines += "*Datei: $($file.Name)*" Set-Content -Path $mdPath -Value $lines -Encoding UTF8 } catch { Write-Warning "Fehler beim Verarbeiten von '$funcName': $_" } } } } |