简体   繁体   中英

User input validation in PowerShell

I have this piece of code in PowerShell. I need user input validation to integer with writing output saying what is wrong with the input and expecting correct input.

$FromObj = "Please input object number"
$FromInput = Read-Host $FromObj

while(($FromInput -isnot [int])) {
    #I also want to put in the while that the input has to be an integer, -gt 0, and -lt 800
    Write-Output "Your input has to be a number."
    $FromInput = Read-Host $FromObj
    }
if ($FromInput -le 0) {
    Write-Output "Your input has to be a number greater than 0!"
    $FromInput = Read-Host $FromObj
    }
elseif ($FromInput -ge 800) {
    Write-Output "Your input has to be a number less than 800!"
    $FromInput = Read-Host $FromObj
    }
else {
    $FromInput = $FromInput -as [int]
    }

However, this is not working for me. Could you help me with validating it with writing outputs as the ones displayed above?

I think Nicks's link in comment already provides different right answers to your question ie: using regex to match \d+ (digits) or using [int]::TryParse(...) but to explain why your code is not working:

  • Read-Host will store user input as string unless you manipulate it which is what you were already doing on your last condition (the else {...} statement).

This is why you never get past the $FromInput -isnot [int] condition.

To fix the code you could simply attempt to store user input -as [int] since the beginning and since you have 3 Read-Host on your code you could save the user input attempt -as [int] in a ScriptBlock which then can be easily executed as many times as needed:

$FromObj = "Please input object number"
$giveMeNumber = { (Read-Host $FromObj) -as [int] }
$FromInput = & $giveMeNumber

while($FromInput -isnot [int]) {
    Write-Output "Your input has to be a number."
    $FromInput = & $giveMeNumber
}
if ($FromInput -le 0) {
    Write-Output "Your input has to be a number greater than 0!"
    $FromInput = & $giveMeNumber
}
elseif ($FromInput -ge 800) {
    Write-Output "Your input has to be a number less than 800!"
    $FromInput = & $giveMeNumber
}

Note, even though this works, the statement is not entirely correct since you're breaking out of the while loop after the input is [int] the user could force an incorrect input.

Try this instead which will execute indefinitely until right input:

Clear-Host
$ErrorActionPreference = 'Stop'
$FromObj = "Please input object number"

$scriptBlock = {
    try
    {
        $FromInput = [int](Read-Host $FromObj)

        # Note I'm using Write-Host instead of Write-Ouput, this is because
        # we don't want to store the invalid inputs messages in the
        # $userInput variable.
        if ($FromInput -le 0) {
            Write-Host "Your input has to be a number greater than 0!"
            & $scriptBlock
        }
        elseif ($FromInput -ge 800) {
            Write-Host "Your input has to be a number less than 800!"
            & $scriptBlock
        }
        else {
            $FromInput
        }
    }
    catch
    {
        Write-Host "Your input has to be a number."
        & $scriptBlock
    }
}

$userInput = & $scriptBlock

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