使用 Read-Host 无法识别 PowerShell 乘数

PowerShell multiplier not recognized using Read-Host

有没有办法让 Read-Host 识别 PowerShell 乘数,如 KB、MB、GB、TB 和 PB?如果我手动填充 $freespace 变量,第一个示例工作得很好,但在第二个示例中使用 Read-Host 填充 $freespace 变量时不起作用。必须是一个简单的解决方案来提示用户输入并将值识别为整数而不是字符串。

#this works just fine. The PowerShell multiplier GB is recognized if typed in.

$freespace = 6GB

If ($freeSpace -le 5GB) {
    Write-Host “Free disk space is less than 5 GB”
} ElseIf ($freeSpace -le 10GB) {
    Write-Host “Free disk space is less than 10 GB”
} ElseIf ($freeSpace -le 20GB) {
    Write-Host “Free disk space is less than 20 GB”
} Else {
    Write-Host “Free disk space is more than 20 GB”
}

#This does not work. The variable is populated by Read-Host as a [string] 

$freespace = Read-Host -Prompt 'Please enter a value for Freespace'

If ($freeSpace -le 5GB) {
    Write-Host “Free disk space is less than 5 GB”
} ElseIf ($freeSpace -le 10GB) {
    Write-Host “Free disk space is less than 10 GB”
} ElseIf ($freeSpace -le 20GB) {
    Write-Host “Free disk space is less than 20 GB”
} Else {
    Write-Host “Free disk space is more than 20 GB”
}

你的读取主机是一个字符串而不是一个整数试试下面的

[int]$freespace = 读取主机提示 'Please enter a value for Freespace'

当你这样做时:

$freespace = Read-Host -Prompt 'Please enter a value for Freespace'

存储在 $freespace 变量中的值将是 [String] 类型,而您可能需要 [UInt64](正整数)。您可以使用如下代码将 [String] 类型转换为 [UInt64] 类型:

do {
  $entry = Read-Host "Please enter a value for freespace, in GB"
  $freespace = $entry -as [UInt64]
  $ok = ($null -ne $freespace) -and ($freespace -lt 1024)
  if ( -not $ok ) {
    Write-Host "Please enter a value in the range 0 to 1023"
  }
until ( $ok )
$freespace *= 1GB

首先,您提示输入 [String] 并将其存储在 $entry 中。接下来,我们使用 -as 运算符 cast 将字符串值转换为 [UInt64] 值。如果转换失败,$freespace 变量将包含 $nulldo 循环将重复,直到输入数值。

在您的脚本中使用上述代码,$freespace 将在 do 循环完成后成为一个数值。最后一行将其转换为 GB。

回答原问题:

Is there a way to get Read-Host to recognize PowerShell multipliers like KB, MB, GB, TB, and PB?

Windows PowerShell 识别二进制乘数后缀 - kb, mb, gb, tb, pb - 字面量 , not 当(隐含地)从字符串 转换 时,后者是 Read-Host cmdlet 总是 returns .

字符串形式识别的唯一上下文是基于运算符的表达式,其中字符串操作数被隐式转换为number,这使得一个相当简单和安全的 workaround.[1]

# 0 + forces the RHS string to be converted to a number, which
# in this particular context *does* work with binary multiplier suffixes 
PS> 0 + '1kb'
1024

此解决方法也适用于 PowerShell (Core) 7+,但 您可以简单地使用
[long] '1kb'
,因为 此类字符串现在 在隐式到数字转换期间始终 受支持

应用于您的代码:

while ($true) {
  try { 
    $freeSpace = 0 + (Read-Host -Prompt 'Please enter a value for Freespace')
    break # Valid input received; exit the loop.
  } catch { 
    Write-Warning 'Please enter a valid number.' # Prompt again.
  }
}

If ($freeSpace -lt 5GB) {
    "Free disk space is less than 5 GB"
} ElseIf ($freeSpace -lt 10GB) {
    "Free disk space is less than 10 GB"
} ElseIf ($freeSpace -lt 20GB) {
    "Free disk space is less than 20 GB"
} Else {
    "Free disk space is more than 20 GB"
}

[1] 虽然使用 Invoke-Expression (iex) 在技术上也可行,但通常应 避免 并使用此 cmdlet由于其固有的安全风险,只能作为最后的手段。通常可以获得更好的替代品。如果确实别无选择,请只在您自己提供或完全信任的输入上使用它 - 参见

更正

$freeSpace = $null
do {
 [int]$freeSpaceRaw = Read-Host -Prompt 'Please enter a value for Freespace in GB example 5 for 5GB '
  try { $freeSpace = 0 + $freeSpaceRaw } catch { Write-Warning 'Please enter a valid number.' }
} while ($null -eq $freeSpace)

If ($freeSpace -lt 5) {
    "Free disk space is less than 5 GB"
} ElseIf ($freeSpace -lt 10) {
    "Free disk space is less than 10 GB"
} ElseIf ($freeSpace -lt 20) {
    "Free disk space is less than 20 GB"
} Else {
    "Free disk space is more than 20 GB"
}