Private/ConvertTo-DMCapacityBlock.ps1
|
function ConvertTo-DMCapacityBlock { # Converts a capacity value (e.g. "10GB", "500MB", "2TB", or a raw number) # into 512-byte block counts expected by the OceanStor DeviceManager API. [CmdletBinding()] [OutputType([long])] param( # Capacity with optional unit suffix: "10GB", "500MB", "2TB", or a raw number. [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [object]$Capacity, # How to interpret a bare number with no unit suffix: # 'Blocks' (default) = already in 512-byte blocks # 'GB' = treat the number as gigabytes [ValidateSet('Blocks', 'GB')] [string]$UnitlessUnit = 'Blocks' ) $capacityText = ([string]$Capacity).Trim() $blockCount = [decimal]0 # --- Path 1: input has a recognized unit suffix (MB, GB, TB) --- if ($capacityText -match '^(?<Value>(?:\d+(?:[.,]\d+)?|[.,]\d+))\s*(?<Unit>MB|GB|TB)$') { # Normalize comma decimal separators to dots for culture-invariant parsing $size = [decimal]0 $normalizedValue = $Matches.Value.Replace(',', '.') $parsed = [decimal]::TryParse( $normalizedValue, [Globalization.NumberStyles]::AllowDecimalPoint, [Globalization.CultureInfo]::InvariantCulture, [ref]$size ) if (-not $parsed -or $size -le 0) { throw "Capacity must be greater than zero. Received '$capacityText'." } # 1 block = 512 bytes, so: MB = 2^20/2^9, GB = 2^30/2^9, TB = 2^40/2^9 $blocksPerUnit = switch ($Matches.Unit.ToUpperInvariant()) { 'MB' { [decimal]2048 } # 1 MB = 2,048 blocks 'GB' { [decimal]2097152 } # 1 GB = 2,097,152 blocks 'TB' { [decimal]2147483648 } # 1 TB = 2,147,483,648 blocks } $blockCount = $size * $blocksPerUnit } # --- Path 2: bare integer — interpretation depends on $UnitlessUnit --- else { $unitlessValue = [long]0 if (-not [long]::TryParse( $capacityText, [Globalization.NumberStyles]::Integer, [Globalization.CultureInfo]::InvariantCulture, [ref]$unitlessValue )) { throw "Invalid capacity '$capacityText'. Use a positive value followed by MB, GB, or TB (for example, 10GB)." } if ($unitlessValue -le 0) { throw "Capacity must be greater than zero. Received '$capacityText'." } $blockCount = if ($UnitlessUnit -eq 'GB') { [decimal]$unitlessValue * [decimal]2097152 } else { # Already in 512-byte blocks — pass through as-is [decimal]$unitlessValue } } # Guard: block count must fit in [long] and must be a whole number # (fractional blocks aren't valid for the API) if ($blockCount -gt [long]::MaxValue) { throw "Capacity '$capacityText' exceeds the supported maximum." } if ([decimal]::Truncate($blockCount) -ne $blockCount) { throw "Capacity '$capacityText' does not resolve to a whole number of 512-byte blocks." } return [long]$blockCount } |