0

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?

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Sv3n
  • 69
  • 1
  • 7
  • 2
    Does this answer your question? [Check if string contains numeric value in PowerShell?](https://stackoverflow.com/questions/51171410/check-if-string-contains-numeric-value-in-powershell) – Nick is tired Jun 20 '21 at 14:48
  • I think IsNumeric does not work for me, I need an integer validation only. I do not know if I am right about this but is there a way to validate it to an integer? – Sv3n Jun 20 '21 at 14:58
  • 2
    The first answer (`$FromInput -match "^\d+$"`) will do that for you, after you've confirmed the string contains an integer, you just need to convert it to one: `[int]$FromInput`. Replace your `($FromInput -isnot [int])` with `!($FromInput -match "^\d+$")` and put a `$FromInput = [int]$FromInput` before your first `if` – Nick is tired Jun 20 '21 at 15:01
  • You were absolutely right! As usual I was wrong. Your answer works a charm. I sincerely apologize and appreciate your help! – Sv3n Jun 20 '21 at 16:35

1 Answers1

1

I think Nicks's link in comment already provides different right answers to your question i.e.: 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
Santiago Squarzon
  • 41,465
  • 5
  • 14
  • 37
  • Soooo as usual, I was wrong. Both yours and Nick's answers did exactly what I had in mind. With the lack of description in my question you still nailed it guys. Srsly, dunno how you do it. Think you're mindreading sometimes, you're that good. Respect! – Sv3n Jun 20 '21 at 16:38
  • 1
    @Sv3n If this answer was helpful to you, please consider [accepting it](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work/5235#5235) as it may help others in the future. – Santiago Squarzon Jul 16 '21 at 14:04