简体   繁体   中英

PowerShell multiplier not recognized using Read-Host

Is there a way to get Read-Host to recognize PowerShell multipliers like KB, MB,GB,TB, and PB? The first example works just fine if I populate the $freespace variable by hand but does not work in the second example using Read-Host to populate the $freespace variable. The has to be a simple solution to get prompt for user input and have the value recognized as an integer rather than a string.

#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”
}

When you do this:

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

The value stored in the $freespace variable will be of type [String] , whereas you probably want an [Int] (integer). You can convert the [String] type to the [Int] type using code like the following:

do {
  $entry = Read-Host "Please enter a value for freespace"
  $freespace = $entry -as [Int]
  $ok = $null -ne $freespace
  if ( -not $ok ) {
    Write-Host "Please enter a numeric value"
  }
until ( $ok )

First, you prompt for a [String] and store it in $entry . Next, we cast the string value to an [Int] value using the -as operator. If the conversion fails, the $freespace variable will contain $null . The do loop will repeat until a numeric value is entered.

your read host is a string not an int try the below

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

Windows PowerShell only recognizes the binary multiplier suffixes - kb , mb , gb , tb , pb - in number literals , and not when (implicitly) converting from a string , the latter being what the Read-Host cmdlet invariably returns.

The only context where the string form is recognized is an operator-based expression in which a string operand is implicitly converted to a number, which enables a fairly simple and safe workaround. [1]

PS> 0 + '1kb'
1024

This workaround also works in PowerShell (Core) 7+ , but there you could simply use
[long] '1kb' , because such strings are now consistently supported during implicit to-number conversion.

Applied to your code:

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

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] While using Invoke-Expression ( iex ) would technically work too, this cmdlet should generally be avoided and used only as a last resort , due to its inherent security risks. Superior alternatives are usually available. If there truly is no alternative, only ever use it on input you either provided yourself or fully trust - see this answer .

Correction

$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"
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM