Add-Bar.ps1

function Add-Bar {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory, ValueFromPipeline)]
        [ValidateNotNullOrEmpty()]
        [array]
        $InputObject
        ,
        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [string]
        $Property = 'Count'
        ,
        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [int]
        $Width = $( if ($Host -and $Host.UI) { $Host.UI.RawUI.MaxWindowSize.Width - 20 } else { 50 } )
    )

    Begin {
        Write-Verbose ('[{0}] Initializing' -f $MyInvocation.MyCommand)
        
        $Data = @()
    }

    Process {
        Write-Verbose ('[{0}] Processing {1} items' -f $MyInvocation.MyCommand, $InputObject.Length)

        $InputObject | ForEach-Object {
            if (($_ | Select-Object -ExpandProperty $Property -ErrorAction SilentlyContinue) -eq $null) {
                throw ('Input object does not contain a property called <{0}>.' -f $Property)
            }
            $Data += $_
        }
    }

    End {
        Write-Verbose ('[{0}] Adding bars' -f $MyInvocation.MyCommand)

        $Count = $Data | Microsoft.PowerShell.Utility\Measure-Object -Maximum -Property $Property | Select-Object -ExpandProperty Maximum
        Write-Debug ('[{0}] Maximum value is {1}. This value will be {2} characters long.' -f $MyInvocation.MyCommand, $Count, $Width)

        $Bars = $Data | ForEach-Object {
            $RelativeCount = [math]::Round($_.$Property / $Count * $Width, 0)
            Write-Debug ('[{0}] Value of {1} will be displayed using {2} characters.' -f $MyInvocation.MyCommand, $_.Property, $RelativeCount)

            Write-Debug ('[{0}] Adding member to input object.' -f $MyInvocation.MyCommand)
            $Item = $_ | Select-Object -Property Index,Count | Add-Member -MemberType NoteProperty -Name Bar -Value ('#' * $RelativeCount) -PassThru

            Write-Debug ('[{0}] Adding type name to output object.' -f $MyInvocation.MyCommand)
            $Item.PSTypeNames.Insert(0, 'HistogramBar')

            Write-Debug ('[{0}] Returning output object.' -f $MyInvocation.MyCommand)
            $Item
        }

        Write-Debug ('[{0}] Returning input objects with bars.' -f $MyInvocation.MyCommand)
        $Bars
    }
}

New-Alias -Name ab -Value Add-Bar -Force