How to convert value to KB, MB, or GB depending on digit placeholders?
I have the following
Import-Module SqlServer
$Analysis_Server = New-Object Microsoft.AnalysisServices.Server
$Analysis_Server.connect("$server")
$estimatedSize = $([math]::Round($($($Analysis_Server.Databases[$cube].EstimatedSize)/1024/1024),2))
this generates for me the size in MB
I would like to enhance this to make it more user friendly readable especially for values that are in the double digit MB
for example, sometimes i get values 50.9 MB
which is good. but some other values are 37091 MB
or 3082.86 MB
, and i'd like values like that to be automatically converted to GB (37.09 GB, 3.08 GB
respectively) if they are in the GB range.
and if there are values that are not in MB range, they should be displayed in KB
i.e. 0.78 MB
should just be 780 KB
how can i accomplish this?
Leaving the KB: 1024
vs 1000
discussion aside as we should use KiB but nobody does, including Microsoft (PowerShell, Explorer, etc.):
PS C:\> 1Kb 1024
Using the The Windows Shell shlwapi.h StrFormatByteSize
function:
$Shlwapi = Add-Type -MemberDefinition '
[DllImport("Shlwapi.dll", CharSet=CharSet.Auto)]public static extern int StrFormatByteSize(long fileSize, System.Text.StringBuilder pwszBuff, int cchBuff);
' -Name "ShlwapiFunctions" -namespace ShlwapiFunctions -PassThru
Function Format-ByteSize([Long]$Size) {
$Bytes = New-Object Text.StringBuilder 20
$Return = $Shlwapi::StrFormatByteSize($Size, $Bytes, $Bytes.Capacity)
If ($Return) {$Bytes.ToString()}
}
Examples:
PS C:\> Format-ByteSize 37091MB
36.2 GB
PS C:\> Format-ByteSize 3082.86MB
3.00 GB
PS C:\> Format-ByteSize 0.78MB
798 KB
PS C:\> Format-ByteSize 670
670 bytes
Here's two more ways of formatting a size in bytes:
1) Using a switch()
function Format-Size() {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[double]$SizeInBytes
)
switch ([math]::Max($SizeInBytes, 0)) {
{$_ -ge 1PB} {"{0:N2} PB" -f ($SizeInBytes / 1PB); break}
{$_ -ge 1TB} {"{0:N2} TB" -f ($SizeInBytes / 1TB); break}
{$_ -ge 1GB} {"{0:N2} GB" -f ($SizeInBytes / 1GB); break}
{$_ -ge 1MB} {"{0:N2} MB" -f ($SizeInBytes / 1MB); break}
{$_ -ge 1KB} {"{0:N2} KB" -f ($SizeInBytes / 1KB); break}
default {"$SizeInBytes Bytes"}
}
}
2) By performing a loop where the gives byte size is repeatedly divided by 1024
function Format-Size2 {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[double]$SizeInBytes
)
$units = "Bytes", "KB", "MB", "GB", "TB", "PB", "EB"
$index = 0
while ($SizeInBytes -gt 1024 -and $index -le $units.length) {
$SizeInBytes /= 1024
$index++
}
if ($index) {
return '{0:N2} {1}' -f $SizeInBytes, $units[$index]
}
return "$SizeInBytes Bytes"
}