Initial commit for powershell scripts.
This commit is contained in:
1 parent
f4e5d9dcbd
commit
4fd95b76d6
18 files changed
+1803
No files matched your search
Executable
+209
@@ -0,0 +1,209 @@
|
||||
$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
|
||||
Reference in new issue
Block a user