PowerShell: Hudu Table of Contents
Recently I have been trying to make our documentation more accessible and easier for our staff to find things. As part of this I thought it would be helpful to have a table of contents of every KB article split by the folders they were in.
I created this script that will generate a table of contents article in your global knowledge base and in every customer knowledge base as well. It arranges it by folders, sorts everything by name alphabetically and uses descending <Hx> tags for sub folders so the Table of Contents Hudu generates on an article will work as well to jump between folders. I hope people find this helpful!
Script
You can access the latest version of the script on my GitHub here https://github.com/lwhitelock/HuduAutomation/blob/main/Hudu-Generate-TOC.ps1
## This script will generate a Table of Contents in your Global KB and in each of your Customer's KBs
# Author: Luke Whitelock
# Date: 02-04-2022
$VaultName = "Your Key Vault"
#### Hudu Settings ####
$HuduAPIKey = Get-AzKeyVaultSecret -vaultName $VaultName -name "HuduAPIKey" -AsPlainText
# Set the base domain of your Hudu instance without a trailing /
$HuduBaseDomain = Get-AzKeyVaultSecret -vaultName $VaultName -name "HuduBaseDomain" -AsPlainText
$TOCArticleName = 'Table of Contents'
import-module HuduAPI
New-HuduAPIKey $HuduAPIKey
New-HuduBaseUrl $HuduBaseDomain
function Get-ProcessedFolder{
param (
$FolderParentID,
$FolderName,
$FolderDepth,
$Articles,
$Folders,
$HTML
)
if ($FolderDepth -gt 6) {
$Depth = 6
} else {
$Depth = $FolderDepth
}
if ($Depth -ne 0){
$HTML.add("<h$($Depth)>$FolderName</h$FolderDepth><ul>")
} else {
$HTML.add("<ul>")
}
foreach ($Article in ($Articles | where-object {$FolderParentID -eq $_.folder_id} | sort-object name)){
$HTML.add("<li><a href='$($Article.url)'>$($Article.Name)</a></li>")
}
foreach ($Folder in ($Folders | where-object {$FolderParentID -eq $_.parent_folder_id} | sort-object name)){
Get-ProcessedFolder -FolderParentID $folder.id -FolderName $Folder.name -FolderDepth ($FolderDepth + 1) -Articles $Articles -Folders $Folders -HTML $HTML
}
$HTML.add("</ul><br />")
}
$AllArticles = Get-HuduArticles | Where-Object {$_.archived -eq $false}
$Folders = Get-HuduFolders
$TableOfContentsArticles = Get-HuduArticles -Name $TOCArticleName
# Process the Global KB First
$GlobalKBs = $AllArticles | where-object { $_.company_id -eq $null }
$GlobalFolders = $Folders | where-object { $_.company_id -eq $null }
[System.Collections.Generic.List[PSCustomObject]]$GlobalHTML = @()
$GlobalHTML.add('<h1 class="align-center">' + $TOCArticleName + '</h1>')
Get-ProcessedFolder -FolderParentID $null -FolderName "Top Level Documents" -FolderDepth 0 -Articles $GlobalKBs -Folders $GlobalFolders -HTML $GlobalHTML
$KBArticle = $TableOfContentsArticles | where-object {$_.company_id -eq $null}
$KBCount = ($KBArticle | measure-object).count
if ( $KBCount -eq 0){
$Null = New-HuduArticle -Name $TOCArticleName -Content ($GlobalHTML -join '')
} elseif ($KBCount -eq 1){
$Null = Set-HuduArticle -ArticleId $KBArticle.Id -Content ($GlobalHTML -join '') -Name $TOCArticleName
} else {
Write-Error "Multiple KB Articles found with the same name"
}
# Generate it for each company
foreach ($CompanyID in ($AllArticles.company_id | select-object -unique)) {
$CompanyArticles = $AllArticles | where-object { $_.company_id -eq $CompanyID }
$CompanyFolders = $Folders | where-object { $_.company_id -eq $CompanyID }
[System.Collections.Generic.List[PSCustomObject]]$CompanyHTML = @()
$CompanyHTML.add('<h1 class="align-center">' + $TOCArticleName + '</h1>')
Get-ProcessedFolder -FolderParentID $null -FolderName "Top Level Documents" -FolderDepth 0 -Articles $CompanyArticles -Folders $CompanyFolders -HTML $CompanyHTML
$CompanyArticle = $TableOfContentsArticles | where-object {$_.company_id -eq $CompanyID}
$CompanyCount = ($CompanyArticle | measure-object).count
if ( $CompanyCount -eq 0){
$Null = New-HuduArticle -Name $TOCArticleName -Content ($CompanyHTML -join '') -company_id $CompanyID
} elseif ($CompanyCount -eq 1){
$Null = Set-HuduArticle -ArticleId $CompanyArticle.Id -Content ($CompanyHTML -join '') -Name $TOCArticleName -company_id $CompanyID
} else {
Write-Error "Multiple KB Articles found with the same name - Company ID: $CompanyID"
}
}