Show human-readable file sizes in the default PowerShell ls command
try this
PS> gc c:\scripts\type\shrf.ps1xml
<Types>
<Type>
<Name>System.IO.FileInfo</Name>
<Members>
<ScriptProperty>
<Name>FileSize</Name>
<GetScriptBlock>
switch($this.length) {
{ $_ -gt 1tb }
{ "{0:n2} TB" -f ($_ / 1tb) }
{ $_ -gt 1gb }
{ "{0:n2} GB" -f ($_ / 1gb) }
{ $_ -gt 1mb }
{ "{0:n2} MB " -f ($_ / 1mb) }
{ $_ -gt 1kb }
{ "{0:n2} KB " -f ($_ / 1Kb) }
default
{ "{0} B " -f $_}
}
</GetScriptBlock>
</ScriptProperty>
</Members>
</Type>
</Types>
PS> Update-TypeData -AppendPath c:\scripts\type\shrf.ps1xml -verbose
PS> get-childItem $env:windir | select Name,FileSize,length
PS> # you can paste this in your profile
PS>
you can also use dynamic type data with PS3:
PS> Update-TypeData -TypeName System.IO.FileInfo -MemberName FileSize -MemberType ScriptProperty -Value {
switch($this.length) {
{ $_ -gt 1tb }
{ "{0:n2} TB" -f ($_ / 1tb) }
{ $_ -gt 1gb }
{ "{0:n2} GB" -f ($_ / 1gb) }
{ $_ -gt 1mb }
{ "{0:n2} MB " -f ($_ / 1mb) }
{ $_ -gt 1kb }
{ "{0:n2} KB " -f ($_ / 1Kb) }
default
{ "{0} B " -f $_}
}
} -DefaultDisplayPropertySet Mode,LastWriteTime,FileSize,Name
First, create the following function:
Function Format-FileSize() {
Param ([int64]$size)
If ($size -gt 1TB) {[string]::Format("{0:0.00} TB", $size / 1TB)}
ElseIf ($size -gt 1GB) {[string]::Format("{0:0.00} GB", $size / 1GB)}
ElseIf ($size -gt 1MB) {[string]::Format("{0:0.00} MB", $size / 1MB)}
ElseIf ($size -gt 1KB) {[string]::Format("{0:0.00} kB", $size / 1KB)}
ElseIf ($size -gt 0) {[string]::Format("{0:0.00} B", $size)}
Else {""}
}
You can then pipe the output of Get-ChildItem
through Select-Object
and use a calculated property to format the filesize:
Get-ChildItem | Select-Object Name, @{Name="Size";Expression={Format-FileSize($_.Length)}}
The function could of course be improved to account for sizes in the PB range and more, or to vary the number of decimal points as necessary.