Upload files to "Test Scripts"

This commit is contained in:
2026-07-01 18:53:46 +00:00
parent 2cb36585b7
commit ee8bc83baf
@@ -0,0 +1,215 @@
#Requires -Version 5.1
<#
.SYNOPSIS
Tree-style folder size analysis with depth + minimum size filtering.
.DESCRIPTION
Scans a starting path, calculates folder sizes up to a specified depth,
and outputs a readable tree list (indented paths) for folders >= MinSize.
Defaults:
- Path : C:\
- Depth : 3
- MinSize: 500MB
Supports MinSize as:
- numeric bytes (e.g., 1073741824)
- string with units (e.g., "1GB", "750MB", "200KB")
Optional environment-variable overrides (RMM friendly):
- ROOT_PATH
- DEPTH
- MIN_SIZE
#>
[CmdletBinding()]
param(
[Parameter(Position = 0)]
[string] $Path = "C:\",
[ValidateRange(1, 256)]
[int] $Depth = 3,
[object] $MinSize = "500MB"
)
begin {
function Test-IsAdminOrSystem {
try {
$id = [Security.Principal.WindowsIdentity]::GetCurrent()
# SYSTEM check (PS 5.1 safe)
if ($id.Name -eq 'NT AUTHORITY\SYSTEM') {
return $true
}
$principal = New-Object Security.Principal.WindowsPrincipal($id)
return $principal.IsInRole(
[Security.Principal.WindowsBuiltInRole]::Administrator
)
}
catch {
return $false
}
}
function Convert-ToBytes {
param([Parameter(Mandatory)][object]$Value)
if ($null -eq $Value) { return [int64]0 }
if ($Value -is [byte] -or
$Value -is [int] -or
$Value -is [long] -or
$Value -is [int64] -or
$Value -is [double] -or
$Value -is [decimal]) {
return [int64]$Value
}
$s = ($Value.ToString()).Trim()
$m = [regex]::Match(
$s,
'^\s*(?<num>\d+(\.\d+)?)\s*(?<unit>bytes|b|kb|mb|gb|tb|pb)?\s*$',
'IgnoreCase'
)
if (-not $m.Success) {
throw "Invalid MinSize value: $s"
}
$num = [double]$m.Groups['num'].Value
$unit = $m.Groups['unit'].Value.ToLower()
switch ($unit) {
'' { return [int64]$num }
'b' { return [int64]$num }
'bytes' { return [int64]$num }
'kb' { return $num * 1KB }
'mb' { return $num * 1MB }
'gb' { return $num * 1GB }
'tb' { return $num * 1TB }
'pb' { return $num * 1PB }
default { return [int64]$num }
}
}
function Format-Bytes {
param([int64]$Bytes)
$units = @("Bytes","KB","MB","GB","TB","PB")
$value = [double]$Bytes
$i = 0
while ($value -ge 1024 -and $i -lt ($units.Count - 1)) {
$value /= 1024
$i++
}
if ($i -eq 0) {
return "{0:0} {1}" -f $value, $units[$i]
}
return "{0:N2} {1}" -f $value, $units[$i]
}
# Environment overrides
if ($env:ROOT_PATH) { $Path = $env:ROOT_PATH }
if ($env:DEPTH) { $Depth = [int]$env:DEPTH }
if ($env:MIN_SIZE) { $MinSize = $env:MIN_SIZE }
try {
$Path = (Get-Item -LiteralPath $Path -ErrorAction Stop).FullName
}
catch {
throw "Path '$Path' does not exist or is not accessible."
}
if (-not $Path.EndsWith('\')) {
$Path += '\'
}
$MinBytes = Convert-ToBytes $MinSize
if (-not (Test-IsAdminOrSystem)) {
Write-Warning "Not running as Administrator or SYSTEM. Sizes may be understated."
}
function Get-FolderSizeAtDepth {
param(
[string] $Folder,
[int] $DepthLeft
)
$node = [PSCustomObject]@{
Name = $Folder
Bytes = 0
Children = @()
}
if ($DepthLeft -le 1) {
try {
$node.Bytes = (
Get-ChildItem -LiteralPath $Folder -File -Recurse -Force -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum
).Sum
}
catch {
$node.Bytes = 0
}
return $node
}
$items = Get-ChildItem -LiteralPath $Folder -Force -ErrorAction SilentlyContinue |
Where-Object { -not ($_.Attributes -band [IO.FileAttributes]::ReparsePoint) }
foreach ($item in $items) {
if ($item.PSIsContainer) {
$child = Get-FolderSizeAtDepth -Folder $item.FullName -DepthLeft ($DepthLeft - 1)
$node.Bytes += $child.Bytes
$node.Children += $child
}
else {
$node.Bytes += $item.Length
}
}
return $node
}
function Emit-Tree {
param(
$Node,
[string] $BasePath,
[int] $Level
)
$relative = $Node.Name
if ($relative.StartsWith($BasePath, 'OrdinalIgnoreCase')) {
$relative = ".\" + $relative.Substring($BasePath.Length)
}
$indent = ' ' * (($Level + 1) * 2)
[PSCustomObject]@{
Path = $indent + $relative
Size = Format-Bytes $Node.Bytes
Bytes = $Node.Bytes
Depth = $Level
}
foreach ($child in $Node.Children) {
Emit-Tree -Node $child -BasePath $BasePath -Level ($Level + 1)
}
}
}
process {
$root = Get-FolderSizeAtDepth -Folder $Path -DepthLeft $Depth
Emit-Tree -Node $root -BasePath $Path -Level 0 |
Where-Object { $_.Bytes -ge $MinBytes } |
Select-Object Path, Size
}