<# .SYNOPSIS Generates interactive HTML and plain-text directory tree reports. .DESCRIPTION Recursively scans a target directory and produces two report files: 1. A plain-text ASCII directory tree file (.txt). 2. An interactive HTML tree file (.html) with search filtering and collapse/expand controls. .PARAMETER RootPath The target root folder path to scan. .PARAMETER OutputDirectory The destination directory where reports will be saved. Defaults to the current working directory. .PARAMETER ReportNamePrefix Optional custom prefix for generated filenames. Defaults to the sanitized root folder name. .PARAMETER OpenInBrowser Switch parameter to automatically open the generated HTML report upon completion. .EXAMPLE .\Export-DirectoryTree.ps1 -RootPath "E:\Sync Method\Corporate\Documents" -OutputDirectory "C:\Reports" -OpenInBrowser .NOTES Created: 2025-03-02 Modified: 2026-10-04 #> [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline =$true)] [ValidateNotNullOrEmpty()] [string]$RootPath, [Parameter(Mandatory = $false, Position = 1)] [string]$OutputDirectory = (Get-Location).Path, [Parameter(Mandatory = $false)] [string]$ReportNamePrefix, [switch]$OpenInBrowser ) # 1. Validate & Resolve Paths if (-not (Test-Path -LiteralPath $RootPath -PathType Container)) { Write-Error "Target root directory not found or unreadable: '$RootPath'" return } $ResolvedRoot = (Get-Item -LiteralPath$RootPath).FullName $RootLeafName = Split-Path -Path$ResolvedRoot -Leaf # Auto-generate report prefix if not explicitly provided if ([string]::IsNullOrWhiteSpace($ReportNamePrefix)) { $ReportNamePrefix =$RootLeafName -replace '[\/\\:\*\?"<>\|]', '-' } # Ensure output directory exists if (-not (Test-Path -LiteralPath $OutputDirectory)) { New-Item -ItemType Directory -Path $OutputDirectory -Force | Out-Null } $TextFile = Join-Path -Path $OutputDirectory -ChildPath "$ReportNamePrefix-tree.txt" $HtmlFile = Join-Path -Path $OutputDirectory -ChildPath "$ReportNamePrefix-tree.html" # 2. State Tracking Setup $script:textLines = [System.Collections.Generic.List[string]]::new() $script:html = [System.Text.StringBuilder]::new()$script:scanErrors = 0 $script:totalFiles = 0$script:totalFolders = 0 function ConvertTo-HtmlEncoded { param([string]$Text) return [System.Net.WebUtility]::HtmlEncode($Text) } function Add-TreeItems { param( [string]$Path, [string]$Prefix ) try { $items = @( Get-ChildItem -LiteralPath $Path -Force -ErrorAction Stop | Sort-Object @{ Expression = { if ($_.PSIsContainer) { 0 } else { 1 } } }, Name ) } catch { $script:scanErrors++ [void]$script:textLines.Add("$Prefix[Unable to read: $($_.Exception.Message)]") [void]$script:html.AppendLine( "
  • Unable to read: $(ConvertTo-HtmlEncoded$_.Exception.Message)
  • " ) return } for ($index = 0; $index -lt $items.Count; $index++) { $item =$items[$index]$isLast = $index -eq ($items.Count - 1) $connector = if ($isLast) { '\-- ' } else { '|-- ' } $nextPrefix =$Prefix + $(if ($isLast) { ' ' } else { '| ' }) $nameHtml = ConvertTo-HtmlEncoded$item.Name $pathHtml = ConvertTo-HtmlEncoded$item.FullName $isLink = -not [string]::IsNullOrWhiteSpace([string]$item.LinkType) if ($item.PSIsContainer -and -not $isLink) {$script:totalFolders++ [void]$script:textLines.Add("$Prefix$connector$($item.Name)") [void]$script:html.AppendLine( "
  • 📁 $nameHtml
  • ') } elseif ($item.PSIsContainer -and $isLink) {$script:totalFolders++ $target = @($item.Target) -join ', ' [void]$script:textLines.Add("$Prefix$connector$($item.Name) [Link → $target]") [void]$script:html.AppendLine( "" ) } else { $script:totalFiles++ [void]$script:textLines.Add("$Prefix$connector$($item.Name)") [void]$script:html.AppendLine( "
  • 📄 $nameHtml
  • " ) } } } # 3. Document Building Write-Host "Scanning directory structure: $ResolvedRoot" -ForegroundColor Cyan $rootNameHtml = ConvertTo-HtmlEncoded $RootLeafName$rootPathHtml = ConvertTo-HtmlEncoded $ResolvedRoot$generated = Get-Date -Format 'yyyy-MM-dd HH:mm:ss' [void]$script:textLines.Add($ResolvedRoot) [void]$script:html.AppendLine(@" Directory Tree - $rootNameHtml

    Directory Tree Report

    Root: $rootPathHtml
    Generated: $generated
    "@) # 4. Save Output Files $script:textLines \vert{} Set-Content -LiteralPath$TextFile -Encoding UTF8 $script:html.ToString() \vert{} Set-Content -LiteralPath$HtmlFile -Encoding UTF8 # Output Summary Write-Host "`nScan Completed Successfully:" -ForegroundColor Green Write-Host " Folders Scanned : $script:totalFolders" Write-Host " Files Cataloged : $script:totalFiles" Write-Host " Unreadable Errors: $script:scanErrors" Write-Host " Text Report : $TextFile" Write-Host " HTML Report : $HtmlFile`n" if ($OpenInBrowser) { Start-Process $HtmlFile }