# encoding: ascii
# api: powershell
# title: Add-ByteFormat
# description: With help of this function you will be able to force nice display of numeric data.
# version: 913.00
# type: function
# author: BartekB
# license: CC0
# function: Add-ByteFormat
# x-poshcode-id: 3393
# x-archived: 2012-05-10T14:15:01
# x-published: 2012-05-02T15:20:00
#
# It’s using best possible unit of measure for *bytes sizes.
# If input object is PSCustomObject it will just modify it’s ToString() method
# If it’s any other type – it will try to remove property, re-add and modify ToString() method.
# Tested both on v2 and v3, works fine in both cases.
#
function Add-ByteFormat {
<#
.Synopsis
Function to make display of custom properties more human-readable.
.Description
With help of this function you will be able to force nice display of numeric data.
It's using best possible unit of measure for *bytes sizes.
If input object is PSCustomObject it will just modify it's ToString() method
If it's any other type - it will try to remove property, re-add and modify ToString() method.
Tested both on v2 and v3, works fine in both cases.
.Example
Get-ChildItem | Add-ByteFormat -Property Length
Output:
Directory: C:\temp\PowerShell\vug\ShowUI
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 26/04/2012 09:36 534.00 B 0_GetProxy.ps1
-a--- 26/04/2012 11:12 266.00 B 1_StackPanel.ps1
-a--- 25/04/2012 19:44 752.00 B 2_SimpleUI.ps1
-a--- 25/04/2012 19:43 913.00 B 3_Przezroczyste.ps1
-a--- 25/04/2012 19:41 1.28 KB 4_ADLastName.ps1
-a--- 25/04/2012 19:42 1.38 KB 5_ADLastName.ps1
-a--- 25/04/2012 19:41 343.00 B 6_RandomFont.ps1
-a--- 25/04/2012 19:54 1.42 KB 7_ADLastName.ps1
-a--- 26/04/2012 11:17 624.00 B 8_Show-Command.ps1
-a--- 26/04/2012 10:28 8.01 KB 9_Show-Picture.ps1
-a--- 25/04/2012 19:27 21.29 KB logo.png
-a--- 15/10/2011 10:34 1.14 MB Normal.png
-a--- 25/05/2011 11:28 222.93 KB Powershell-V2-1280x1024.jpg
-a--- 25/05/2011 11:26 232.69 KB PowerShell1024x768[1].jpg
-a--- 09/01/2011 21:59 80.36 KB powershellpl.png
-a--- 26/04/2012 07:18 5.27 KB Sm-.csv
-a--- 26/04/2012 11:18 8.08 KB WAR.csv
Changes format of the Length property for files in current directory.
As a side effect in v3 it will show folders as having 1B size.
.Example
Get-WmiObject -Class Win32_LogicalDisk | Add-ByteFormat -Property Size, FreeSpace -DecimalPoint 0
Output:
DeviceID : C:
DriveType : 3
ProviderName :
FreeSpace : 9 GB
Size : 298 GB
VolumeName : PXL
Will display disk information using WMI in N0 format.
.Example
Import-Csv Foo.csv | Add-ByteFormat -Property HDSize, RAM | Format-Table -AutoSize
Output:
Name HDSize RAM
---- ------ ---
One 120.50 GB 1.47 GB
Two 58.10 GB 3.47 GB
Three 88.01 GB 1.21 GB
This command is wash & go for data imported from CSV that contains numeric:
-- numeric are no longer strings
-- numeric are displayed in nice(r) fasion.
.Link
http://becomelotr.wordpress.com/2012/05/03/more-on-output/
#>
[CmdletBinding()]
param (
# Properties that will get ToString() method modified to allow better display.
[Parameter(
Mandatory = $true
)]
[string[]]$Property,
# Number of decimal points used.
[Alias('DP')]
[int]$DecimalPoint = 2,
# Object, that has properties that will be modified.
[Parameter(
ValueFromPipeline = $true,
Mandatory = $true
)]
[Object]$InputObject
)
begin {
$MethodOptions = @{
Name = 'ToString'
MemberType = 'ScriptMethod'
PassThru = $true
Force = $true
Value = [ScriptBlock]::Create(@"
"{0:N$DecimalPoint} {1}" -f @(
switch -Regex ([math]::Log(`$this,1024)) {
^0 {
(`$this / 1), ' B'
}
^1 {
(`$this / 1KB), 'KB'
}
^2 {
(`$this / 1MB), 'MB'
}
^3 {
(`$this / 1GB), 'GB'
}
^4 {
(`$this / 1TB), 'TB'
}
default {
(`$this / 1PB), 'PB'
}
}
)
"@
)
}
}
process {
foreach ($Prop in $Property) {
$SelectedProperty = $InputObject.$Prop
if (!$SelectedProperty) {
Write-Verbose "No such property: $Prop"
continue
}
if ( ! ([double]$InputObject.$Prop) ) {
Write-Verbose "Can't be casted into double: $Prop"
continue
}
if ($SelectedProperty -is [System.String]) {
# Need to change property type to make sure we get .ToString() to run... ;)
[Int64]$InputObject.$Prop = $SelectedProperty
}
if (!$InputObject.PSTypeNames.Contains('System.Management.Automation.PSCustomObject')) {
try {
$Member = @{
MemberType = 'NoteProperty'
Name = $Prop
Force = $true
Value = $SelectedProperty
}
$InputObject | Add-Member @Member
} catch {
Write-Verbose "Not able to replace property on this type: $($InputObject.GetType().FullName)"
continue
}
}
$InputObject.$Prop = $InputObject.$Prop | Add-Member @MethodOptions
}
$InputObject
}
}
# Function in action. ;)
([PSCustomObject]@{
Name = 'Anna'
HDSize = 21313123
RAM = 123GB
Foo = '12313213123'
}),([PSCustomObject]@{
Name = 'Ewa'
HDSize = 213112313123
RAM = 1234MB
Foo = '12313213123'
}),([PSCustomObject]@{
Name = 'Adam'
HDSize = 21313
RAM = 530PB
Foo = '1231321113123'
}) | Add-ByteFormat -Property HDSize, RAM, Foo -Verbose
@'
Name,HDSize,RAM,Foo
Anna,21313123,12313213123,12313213123123
Ewa,123123123,123123123123,0
Adam,1231312312313,1231313213123123,12313123123123
'@ | ConvertFrom-Csv | Add-ByteFormat -Property HDSize, RAM, Foo -Verbose