PowerShell's range operator - .. - generates an array of discrete values[1] from the range endpoints, which can have the following types (in a given expression, both endpoints must have the same type):
[int] (System.Int32)
- e.g.,
1..3 creates array 1, 2, 3
- Note: While the minimum and maximum endpoint values allowed are
[int]::MinValue and [int]::MaxValue, respectively, the resulting array must additionally not have more than 2,146,435,071 elements (2+ billion), which is the max. element count for a single-dimensional [int] array in .NET - see this answer for background information.
Alternatively, only in PowerShell [Core, 6+]: characters, which are enumerated between the endpoints by their underlying code points ("ASCII values").
- e.g.,
'a'..'c' creates array [char] 'a', [char] 'b', [char] 'c'
Instances of numeric types other than [int] are quietly coerced to the latter - if they can fit into the [int] range - in which case half-to-even midpoint rounding is performed for non-integral types; e.g., implicit [double] instances 23.5 and 24.5 are both coerced to 24.
Because [int] 23.976 is 24, your 23.976..60 expression creates array 24, 25, 26, ..., 60 which is not your intent.
In short: You cannot use .. to describe an uncountable range of non-integers (fractional numbers).
Instead, use -ge (greater than or equal) and -le (less than or equal) to test against the endpoints:
-not ($value -ge 23.976 -and $value -le 60)
Additionally, in order to make the -ge and -le operations work as intended, convert the return value from Read-Host, which is always a string, to a number.
If you were to use $value as directly returned by Read-Host, you'd get lexical (text sort order-based) comparison, not numeric comparison.
Therefore, cast the Read-Host return value to [double]:
$value = try { [double] (Read-Host 'Specify a value between 23.976 and 60') }
catch {}
Note: The try / catch handles the case when the user enters text that cannot be interpreted as a [double] representation.
To put it all together:
do {
$value = try { [double] (Read-Host 'Specify a value between 23.976 and 60') }
catch {}
} while (-not ($value -ge 23.976 -and $value -le 60))
[1] Strictly speaking, .. creates a lazy enumerable that only becomes an [object[]] array when enumeration is performed and the results are collected, such as when a .. operation participates in a larger expression or it is captured in a variable.
-geand a-lecompound test.Do { $value = Read-host "Specify a value between 23.976 and 60"} while ( $value -ge 23.976 ) -and ( $value -lt 60 )...doesn't seem to workwhiletest needs to be in one parenthesis pair. you have it broken into two. wrap the whole thing in another paren pair. [2] yourwhiletest is backwards. as it stands the only accepted answers will be OUTSIDE the range. you want the test to validate IN the range, so the "keep doing it until you get it right" test needs to be "while OUTSIDE of the target range. [grin]$valueis text. you likely will need to convert the digit text to a number. i would use[float]. [grin]-geand-leand generally needing to convertRead-Hostoutput to a number for numerical comparison ([double]is probably preferable). The fundamental problem here is the attempt to use a..range for checking a non-integer number range, but thewhilecondition syntax and the logic are otherwise correct (the outside-the-range logic is in the-notcontains). As for the..operator: The min. / max. endpoint values are[int]::MinValueand[int]::MaxValue, and, additionally, the resulting array must not have more than2,146,435,071elements.