Home > Software engineering >  Trying to check if entered value is integer and above 1. Failing first condition
Trying to check if entered value is integer and above 1. Failing first condition

Time:04-28

Hope you can help.

I have a script which essentially is an interactive menu using the switch function. One of the switch options requires a user to enter an integer by using Read-Host function to set a variable which is used later on in that script block. I'd like the integer to be able to change value a few times in one Powershell session.

I'm trying to add some error messages to stop the rest of the script from running if the value is not an integer or below 0. I'm using the below but no matter what, my Read-Host input will always throw the first error. Could someone let me know what I'm doing wrong? Thank you!

'16'{
     Write-Host `nThis will export results to a CSV file - Please allow time for the report to run`n -BackgroundColor Black -ForegroundColor Yellow
     $InactiveDays = Read-Host "`nEnter How Many Inactive Days To Search By`n" 
     if ($InactiveDays -isnot [int]) {
        Write-Host 'You did not provide a number as input'-BackgroundColor Black -ForegroundColor Red 
            }
     elseif ($InactiveDays -lt 1) {
        Write-Host 'Enter a value above 1 as input' -BackgroundColor Black -ForegroundColor Red
            }
     else
        { *Rest of script } } 

CodePudding user response:

change $InactiveDays -isnot [int] for $InactiveDays -notmatch "\d"

As a few comments mentioned, read-host will always return the type string, which means even if the value is 4 it will not be type int.

You can still interact with it as an int however, because powershell is polymorphic.

The proposed -match "\d" command will instead use regex to check if the value contains only numbers, which will achieve what you wanted.

CodePudding user response:

  • -isnot checks the current type of the LHS, which in your case is always [string], as output by Read-Host, so that $InactiveDays -isnot [int] is by definition always $true.

  • You can use the -as operator for conditional conversion of the LHS to the RHS type: it returns an instance of the RHS type if the conversion is possible, and $null otherwise.

Therefore, replace:

if ($InactiveDays -isnot [int]) {

with:

# Try to convert the string output by Read-Host to [int]
# Yields $null if not possible.
$InactiveDays = $InactiveDays -as [int]

# Check if the conversion yielded an [int]
# You could also use:
#   if ($null -eq $InActiveDays) { ...
if ($InactiveDays -isnot [int]) {

Caveat:

  • This gives you the same conversion behavior that you get when you cast to [int], which is fairly permissive; e.g.:

    [int] '1.5'   # -> 2
    [int] '   '   # -> 0
    [int] '1,000' # -> 1000
    
  • For a stricter interpretation of the input string that rules out the above edge cases, use [int]::TryParse(), as shown in this answer to the question that zett42 links to in a comment.

  • Related