Files
asg/DirectoryListing.ps1
T

209 lines
6.2 KiB
PowerShell
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
$root = 'E:\Sync Method\Corporate\Zefiro Methane Corp. - Documents'
$outputDirectory = 'C:\Users\MattSpeer\OneDrive - Add Source Group\Documents\1- Projects\Zefiro - Data Migration'
$textFile = Join-Path $outputDirectory 'Zefiro-Methane-Corp-Documents-tree.txt'
$htmlFile = Join-Path $outputDirectory 'Zefiro-Methane-Corp-Documents-tree.html'
if (-not (Test-Path -LiteralPath $root -PathType Container)) {
throw "Folder not found: $root"
}
New-Item -ItemType Directory -Path $outputDirectory -Force | Out-Null
$script:textLines = [System.Collections.Generic.List[string]]::new()
$script:html = [System.Text.StringBuilder]::new()
$script:scanErrors = 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(
"<li class='error'>Unable to read: $(ConvertTo-HtmlEncoded $_.Exception.Message)</li>"
)
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) {
[void]$script:textLines.Add("$Prefix$connector$($item.Name)")
[void]$script:html.AppendLine(
"<li><details data-path='$pathHtml'><summary>📁 $nameHtml</summary><ul>"
)
Add-TreeItems -Path $item.FullName -Prefix $nextPrefix
[void]$script:html.AppendLine('</ul></details></li>')
}
elseif ($item.PSIsContainer -and $isLink) {
$target = @($item.Target) -join ', '
[void]$script:textLines.Add(
"$Prefix$connector$($item.Name) [Link → $target]"
)
[void]$script:html.AppendLine(
"<li class='link' data-path='$pathHtml'>🔗 $nameHtml <small>→ $(ConvertTo-HtmlEncoded $target)</small></li>"
)
}
else {
[void]$script:textLines.Add("$Prefix$connector$($item.Name)")
[void]$script:html.AppendLine(
"<li class='file' data-path='$pathHtml'>📄 $nameHtml</li>"
)
}
}
}
$rootNameHtml = ConvertTo-HtmlEncoded (Split-Path -Path $root -Leaf)
$rootPathHtml = ConvertTo-HtmlEncoded $root
$generated = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
[void]$script:textLines.Add($root)
[void]$script:html.AppendLine(@"
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Team Site Documents Directory</title>
<style>
body {
font-family: "Segoe UI", Arial, sans-serif;
margin: 24px;
color: #1f2328;
background: #fff;
}
h1 { margin-bottom: 6px; }
.meta { color: #57606a; margin-bottom: 18px; }
.controls {
position: sticky;
top: 0;
background: #fff;
padding: 10px 0;
border-bottom: 1px solid #d0d7de;
z-index: 2;
}
input {
width: min(600px, 70vw);
padding: 8px;
font-size: 14px;
}
button {
padding: 8px 12px;
margin-left: 6px;
}
ul {
list-style: none;
margin: 4px 0 4px 20px;
padding-left: 10px;
border-left: 1px solid #d8dee4;
}
.tree { border-left: 0; margin-left: 0; }
summary { cursor: pointer; padding: 3px; }
.file, .link { padding: 3px; }
.link { color: #8250df; }
.error { color: #cf222e; }
small { color: #57606a; }
.hidden { display: none !important; }
</style>
</head>
<body>
<h1>Team Site – Documents</h1>
<div class="meta">
Generated $generated<br>
Root: <code>$rootPathHtml</code>
</div>
<div class="controls">
<input id="search" type="search" placeholder="Search folders and files">
<button type="button" onclick="setAll(true)">Expand all</button>
<button type="button" onclick="setAll(false)">Collapse all</button>
</div>
<ul class="tree">
<li>
<details open data-path="$rootPathHtml">
<summary>📁 $rootNameHtml</summary>
<ul>
"@)
Add-TreeItems -Path $root -Prefix ''
[void]$script:html.AppendLine(@"
</ul>
</details>
</li>
</ul>
<script>
function setAll(state) {
document.querySelectorAll('details').forEach(function (item) {
item.open = state;
});
}
document.getElementById('search').addEventListener('input', function () {
const term = this.value.trim().toLowerCase();
const nodes = Array.from(document.querySelectorAll('[data-path]'));
nodes.forEach(function (node) {
node.classList.remove('hidden');
});
if (!term) return;
nodes.forEach(function (node) {
if (!node.dataset.path.toLowerCase().includes(term)) {
node.classList.add('hidden');
}
});
nodes.filter(function (node) {
return node.dataset.path.toLowerCase().includes(term);
}).forEach(function (node) {
node.classList.remove('hidden');
let parent = node.parentElement;
while (parent) {
if (parent.tagName === 'DETAILS') {
parent.open = true;
parent.classList.remove('hidden');
}
parent = parent.parentElement;
}
});
});
</script>
</body>
</html>
"@)
$script:textLines | Set-Content -LiteralPath $textFile -Encoding UTF8
$script:html.ToString() | Set-Content -LiteralPath $htmlFile -Encoding UTF8
Write-Host "Text report: $textFile"
Write-Host "HTML report: $htmlFile"
Write-Host "Unreadable folders: $script:scanErrors"
Start-Process $htmlFile