Search code examples
powershelldisk

Conversion between TB, KB, and GB in Powershell Not Working


I am trying to make a function that reads information from disks and output the data used and available. However, some disks have storage in KB, some in GB, and some in TB. I created a function, but it seems to make all values output in GB instead of their actual value.

This is my code:

Function Read-DiskInfo { # retrieves a list of all available disk drives
    Get-PSDrive -PSProvider 'FileSystem' | Select-Object -Property Name, Used, Free
}

Function Get-DiskInfo { # returns information about a specified disk drive
    $diskDrives = Read-DiskInfo
    Write-Host 'Disk Drive Information:' -ForegroundColor Green; $lineBreak
    [string]$unit
    foreach ($disk in $diskDrives) {
        $diskName = ($disk).Name
        $usedSpace = ($disk).Used
        $freeSpace = ($disk).Free

        if ($usedSpace / 1TB -gt 1 ) {
            $usedSpace = [math]::round((($disk).Used) / 1TB , 2)
            $freeSpace = [math]::round((($disk).Free) / 1TB , 2)
            $unit = '(TB)'
        }
        elseif ($usedSpace / 1GB -gt 1) {
            $usedSpace = [math]::round((($disk).Used) / 1GB , 2)
            $freeSpace = [math]::round((($disk).Free) / 1GB , 2)
            $unit = '(GB)'
        }
        else {
            $usedSpace = [math]::round((($disk).Used) / 1KB , 2)
            $freeSpace = [math]::round((($disk).Free) / 1KB , 2)
            $unit = '(KB)'
        }

        $totalSpace = $usedSpace + $freeSpace

        Write-Host 'Disk Label' $unit": " -ForegroundColor Green -NoNewline; $diskName
        Write-Host 'Used Space' $unit": " -ForegroundColor Green -NoNewline; $usedSpace
        Write-Host 'Available Space' $unit": " -ForegroundColor Green -NoNewline; $freeSpace
        Write-Host 'Total Space' $unit": " -ForegroundColor Green -NoNewline; $totalSpace
        if ($diskDrives.length -gt 1) {
            Write-Host $separator
        }
        $lineBreak
    }
}

I expect to receive the output in the corresponding storage data type (KB, GB,TB) but they are all outputted to GB for some reason that I am not sure.


Solution

  • If I understand your question properly, I believe you want each of the sizes formatted into the most fitting unit, so $totalSize could be in TB while $freeSize for the same disk could be in MB.

    In that case, try:

    function Get-SizeUnit {
        [CmdletBinding()]
        param(
            [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
            [ValidateRange(0, [double]::MaxValue)]
            [double]$SizeInBytes
        )
        $units = 'Bytes', 'KB', 'MB', 'GB', 'TB', 'PB'
        $index = 0
        $size  = $SizeInBytes
        while ($size -gt 1024 -and $index -lt $units.Count) {
            $size /= 1024
            $index++
        }
    
        $divider = if ($index) {'1{0}' -f $units[$index]} else {1}
        # output an object
        [PsCustomObject]@{
            Unit = $units[$index]
            Size = [math]::Round($SizeInBytes / $divider, 2)
        }
    }
    
    function Get-DiskInfo { 
        # returns information about a specified disk drive
        $lineBreak  = [environment]::NewLine
        $diskDrives = Get-PSDrive -PSProvider 'FileSystem'
        Write-Host 'Disk Drive Information:' -ForegroundColor Green; $lineBreak
        foreach ($disk in $diskDrives) {
            $usedSpace  = Get-SizeUnit $disk.Used
            $freeSpace  = Get-SizeUnit $disk.Free
            $totalSpace = Get-SizeUnit ($disk.Used + $disk.Free)
    
            Write-Host ('Disk Label: {0}' -f $disk.Name) -ForegroundColor Green
            Write-Host ('Used Space ({0}): {1}' -f $usedSpace.Unit, $usedSpace.Size) -ForegroundColor Green
            Write-Host ('Available Space ({0}): {1}' -f $freeSpace.Unit, $freeSpace.Size) -ForegroundColor Green 
            Write-Host ('Total Space ({0}): {1}' -f $totalSpace.Unit, $totalSpace.Size) -ForegroundColor Green
    
            $lineBreak
        }
    }
    
    Get-DiskInfo