1

I want to set a variable for unit sizes like GB or TB to be used in calculating disk capacity. This is my working example:

$SourceDriveLetter = "C"
$SourceDrive = Get-Volume -DriveLetter $SourceDriveLetter
$SourceCapacity = [math]::Round(($SourceDrive.Size/1TB),2)
$SourceCapacity
0.42

I want to set something like this so I can easily change from TB to GB. I use the $Unit elsewhere in an email report.

$SourceDriveLetter = "C"
$Unit = "TB"
$UnitCalc = 1 * [int]$Unit
$SourceDrive = Get-Volume -DriveLetter $SourceDriveLetter
$SourceCapacity = [math]::Round(($SourceDrive.Size/$UnitCalc),2)
$SourceCapacity

I know $Unit is a string to begin with, no exactly sure how to represent it as a literal with the math calculation in $UnitCalc. Any help would greatly be appreciated.

TechFA
  • 129
  • 1
  • 9
  • A terabyte (TB or more precisely TiB) is 1024×1024×1024 bytes = 1073741824 bytes = 2³⁰ bytes. Simply divide by that number. – Martin Liversage Feb 28 '21 at 17:47
  • I want to change $Unit = "TB" to $Unit = "GB" and have it update everywhere else in the script for calculations and remain as a string for output in the email report. A server could have large drives needing TB, others have smaller and need GB represented. Would like to just change it in one spot instead of ten places throughout the script. – TechFA Feb 28 '21 at 17:53
  • 1
    In case you want to have it completely automated: [How to convert value to KB, MB, or GB depending on digit placeholders?](https://stackoverflow.com/a/57535324/1701026) – iRon Feb 28 '21 at 18:03
  • `$unit = 1mb; 200gb/$unit` output `204800` – Daniel Feb 28 '21 at 20:08

3 Answers3

2

If you know all of your units in advance you can just use a switch expression to convert the string into the appropriate value:

$Unit = "TB"
$UnitCalc = switch($Unit) {
  "MB" { 1MB }
  "GB" { 1GB }
  "TB" { 1TB }
  default { throw "unhandled unit '$Unit'" }
}

$capacity = 20TB / $UnitCalc # gives 20

You can reduce to a single line with a hashtable if you don't need the error handling, but note this gives $UnitCalc = $null for unknown unit sizes:

$UnitCalc = @{ "MB" = 1MB; "GB" = 1GB; "TB" = 1TB }[$Unit]
mclayton
  • 8,025
  • 2
  • 21
  • 26
1

How about code that determines the best size to use?

Clear-Host 

$Size = 22373741824

#Updated per MClayton's suggestion, Thanks! 
$Unit = Switch ($Size) {
          {$Size -gt 1PB} { 'PB' ; Break }
          {$Size -gt 1TB} { 'TB' ; Break }
          {$Size -gt 1GB} { 'GB' ; Break }
          {$Size -gt 1Mb} { 'MB' ; Break }
          Default         { 'KB'         }
        }

"Unit is: $unit"

$SourceCapacity = [math]::Round(($Size/$("1"+$Unit)),2)

"Source Drive capacity is: $SourceCapacity $Unit"

Of course you'll replace the Test variable $Size with your retrieved value variable and remove the debug output statements.

HTH

RetiredGeek
  • 2,980
  • 1
  • 7
  • 21
  • 1
    PowerShell has built-in understanding of PB, TB, GB, etc. For example ```PS> 1gb``` outputs 1073741824, so you don't need to use ```[math]::Pow``` for those units - you can just say something like ```{$Size -gt 1pb }```... – mclayton Mar 01 '21 at 14:35
  • mclayton, thanks I should have known that...DUH! – RetiredGeek Mar 01 '21 at 14:45
1

PowerShell already recognizes a shorthand like 1GB, 1TB. If you have the discipline to exclude quotes and include a 1 then your code already works.

$SourceDriveLetter = "C"
$Unit = 1TB
$SourceDrive = Get-Volume -DriveLetter $SourceDriveLetter
$SourceCapacity = [math]::Round(($SourceDrive.Size/$Unit),2)
$SourceCapacity

PS > .\Stack Overflow Demo.ps1
0.91

PS > $SourceDrive.Size / 1GB
930.528869628906
  • Bah those darn quotes got me again, I could have sworn I tried this. Thank you! – TechFA Mar 01 '21 at 13:50
  • This might mess up the email report mentioned in the question if the OP is using the value of ```$Unit```` as a units string - e.g. “drive capacity is $SourceCapacity $Unit” will suddenly look very odd :-). – mclayton Mar 01 '21 at 17:19
  • @mclayton This is true, I guess it was more of a question of how to get it working properly with the shorthand in the variable. I ended up simplifying things with the method iRon mentioned in the comments. I'm just learning so it's good to see there is more than one way to get the job done. Thanks for sharing the knowledge. – TechFA Mar 04 '21 at 05:00