functions/Show-FolderUsage.ps1

Function Show-FolderUsage {
    [cmdletbinding(DefaultParameterSetName = '__AllParameterSets')]
    [alias('sfu')]
    [OutputType('PSObject',ParameterSetName='raw')]
    [OutputType('System.String',ParameterSetName='__AllParameterSets')]
    Param(
        [Parameter(
            Position = 0,
            Mandatory = $true,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName,
            HelpMessage = 'Specify the path to the folder to analyze. Use a full file system path')]
        [ValidateNotNullOrEmpty()]
        [string]$Path,

        [Parameter(
            Position = 1,
            ValueFromPipelineByPropertyName,
            HelpMessage = 'Specify the name of a remote computer. You must have admin rights. The default is the localhost.'
        )]
        [ValidateNotNullOrEmpty()]
        [Alias("CN")]
        [string[]]$ComputerName = $env:COMPUTERNAME,

        [Parameter(
            ValueFromPipelineByPropertyName,
            HelpMessage = 'Specify an alternate credential for the remote computer.'
        )]
        [ValidateNotNullOrEmpty()]
        [PSCredential]$Credential,

        [Parameter(
            ValueFromPipelineByPropertyName,
            HelpMessage = 'Specify the minimum percentage to display. The default is 5%'
        )]
        [ValidateRange(1, 99)]
        [int]$Threshold = 5,

        [Parameter(ParameterSetName = 'raw', HelpMessage = 'Display raw output without formatting.')]
        [switch]$Raw
    )

    Begin {
        $PSDefaultParameterValues['_verbose:Command'] = $MyInvocation.MyCommand
        $PSDefaultParameterValues['_verbose:block'] = 'Begin'
        _verbose -message $strings.Starting
        if ($MyInvocation.CommandOrigin -eq 'Runspace') {
            #Hide this metadata when the command is called from another command
            _verbose -message ($strings.PSVersion -f $PSVersionTable.PSVersion)
            _verbose -message ($strings.UsingHost -f $host.Name)
            _verbose -message ($strings.UsingModule -f $DiskReportingModule)
        }

        $sym = ' '

        #define the scriptblock to run remotely
        $sb = {
            param($path)
            Try {
                #validate the path
                $test = Get-Item -Path $path -ErrorAction Stop | Out-Null
                $files = Get-ChildItem -Path $path -File -Recurse -ErrorAction Stop
            }
            Catch {
                $_
            }
            If ($files) {
                $files | Group-Object -Property extension |
                Select-Object -Property Name, Count,
                @{Name = 'Size'; Expression = { ($_.Group | Measure-Object -Property length -Sum).sum } }
            }
        }

        $icmSplat = @{
            ScriptBlock      = $sb
            ArgumentList     = ''
            HideComputerName = $True
            ErrorAction      = 'Stop'
        }

    } #begin
    Process {
        $PSDefaultParameterValues['_verbose:block'] = 'Process'
        Write-Information $PSBoundParameters -Tags runtime
        If ($Credential) {
            _verbose ($strings.RunAs -f $Credential.UserName)
            $icmSplat['Credential'] = $Credential
        }
        #Process computers individually
        foreach ($Computer in $ComputerName) {
            _verbose ($strings.FolderUsage -f $Path, ($Computer.ToUpper()))
            $icmSplat['ArgumentList'] = $Path
            $icmSplat['ComputerName'] = $Computer
            Write-Information $icmSplat -Tags runtime
            Try {
                $data = Invoke-Command @icmSplat
            }
            Catch {
                $_
            }

            If ($data) {
                #get the total sum of all files
                $totalSum = ($data | Measure-Object -Property size -Sum).Sum
                Write-Information "Total size: $totalSum bytes" -Tags data
                $data | Add-Member -MemberType NoteProperty -Name 'Total' -Value $totalSum -Force
                $data | Add-Member -MemberType ScriptProperty -Name 'Pct' -Value { ($this.Size / $this.total) * 100 } -Force
                Write-Information $data -Tags data

                if ($raw) {
                    $data | Select-Object -Property *,
                    @{Name="Path";Expression={_toTitleCase $Path}},
                    @{Name="ComputerName" ;Expression = {$_.PSComputername.ToUpper()}} -ExcludeProperty RunspaceID
                }
                else {
                    #format the results
                    $header = "[$cnStyle{1}$reset] $pathStyle{0}$reset" -f (_toTitleCase $Path), $data[0].PSComputername.ToUpper()
                    #this will be the output
                    $out = @"
 
$header
 
 
"@

                    #filter out extensions with less than the threshold percentage
                    $filtered = $data.Where({ $_.Pct -ge $Threshold })
                    #get longest extension name
                    $maxLength = ($filtered.name) | Select-Object -ExpandProperty length | Sort-Object | Select-Object -Last 1

                    foreach ($item in $filtered) {
                        $pct = $item.Pct
                        [double]$scaled = $pct / 2
                        [int]$used = 50 - $scaled
                        $displayPct = [math]::Round($scaled * 2, 2)
                        $bar = ($sym * $scaled)
                        $remain = 50 - $scaled
                        if ($pct -gt 50) {
                            $bgColor = $redBG
                            $fgColor = $red
                        }
                        elseif ($pct -gt 20) {
                            $bgColor = $yellowBG
                            $fgColor = $yellow
                        }
                        else {
                            $bgColor = $greenBG
                            $fgColor = $green
                        }
                        $out += "{0} [{1}{2}{3}{4}] {5}{6:P2}{3}`n" -f ($item.Name).PadRight($maxLength), $bgColor, $bar, $Reset, (' ' * $remain), $fgColor, ($pct / 100)

                    } #foreach item

                    $out
                }
            } #if data


        } #foreach computer
    } #process
    End {
        $PSDefaultParameterValues['_verbose:block'] = 'End'
        $PSDefaultParameterValues['_verbose:Command'] = $MyInvocation.MyCommand
        _verbose $strings.Ending
    } #end
}