powershell

PowerShell only accept Int


I am scripting some code that will help my team automate some AD User mod tasks and ensure that we are doing things consistently. I am prompting for a user's last name (or partial last name) and returning a list of matching users (Index, Name, userID) to ensure we mod the correct account.

For example if I search for Smith it would return:

[0] Smith, John   jsmith
[1] Smith, Jane   jsmith1
[2] Smithfield, Robert  rsmithfield

The tech would then need to enter the corresponding number of the account they want to modify. I put in an input validation check to ensure that a valid index number is chosen (in this case it will not accept a negative int or an int greater than 2).

Unfortunately I do not know how to also ensure that a letter or symbol is not entered. In this case if users enter the number 3 it will return a message of "Invalid Selection" but if they enter the letter d, it accepts it and then errors out.

How do I make it so it will only accept an int?

FYI - after I get this working I will be creating functions and function calls so it would be more modular, this is just initial testing of the concept.

#prompt for last name (or at least portion of last name, then conver to a string with wild card for use in filter
$lname = Read-Host "`nEnter at least the first three chars of users last name (you may enter full last name)"
$search = $lname + "*"

#Empty arrays
$ResultsArray=@("")
$ADUsersList=@("")

#add aduser properties to array, return error and exit if no user found
$ADUsersList += Get-ADUser -filter 'surname -like $search' -Properties * | select name,samaccountname,DistinguishedName
if ($ADUsersList.count -le 1){
    Write-host "USER NOT FOUND"
    return
}

#populate a 2D array with NAM and with UserID
$ResultsArray = @(($ADUsersList.name),($ADUsersList.samaccountname))

#return list of found users and user ids. Preface with index number to use for selection menu
for($i=0;$i-le $ResultsArray[0].length-1;$i++){
    “[{0}] = {1} `t {2}” -f $i,$ResultsArray[0][$i],$ResultsArray[1][$i]
}

#Prompt 
[int]$selection = Read-Host "`nEnter number for user you want to modify"

#Input validation - Only allow a valid index #.  If valid, write user selected to screen before proceeding 
if ($selection -gt $ResultsArray[0].length -or $selection -lt 0){
    Write-host "INVALID SELECTION!!!" -ForegroundColor Red
} 
else {
    Write-Host "`nYou selected user " -nonewline 
    Write-Host $ResultsArray[0][$selection] -nonewline -ForegroundColor Green
    Write-Host " with user ID a of " -nonewline 
    Write-Host $ResultsArray[1][$selection] -nonewline -ForegroundColor Green
}


Solution

  • This might be an easier way to do it, you can use the -as operator for safe conversion and a regex pattern to ensure that the input was a numeric digit:

    $testCollection = 0..(Get-Random -Maximum 10)
    for ($i = 0; $i -le $testCollection.Count - 1; $i++) {
        '[{0}] = {1}' -f $i, $testCollection[$i]
    }
    $selection = (Read-Host "`nEnter number for user you want to modify") -as [int]
    
    if ($selection -notmatch '^[0-9]+$' -or $selection -ge $testCollection.Count) {
        return Write-Warning 'Invalid stuff..'
    }
    $testCollection[$selection]
    

    But even simpler and more robust would be to use Out-GridView -PassThru:

    $selection = Get-ADUser -Filter "surname -like '$search'" |
        Select-Object name, samaccountname, DistinguishedName |
        Out-GridView -PassThru -Title 'Choose a user'
    
    if (-not $selection) {
        return 'Nothing was selected...'
    }
    
    Write-Host "`nYou selected user " -NoNewline 
    Write-Host $selection.Name -NoNewline -ForegroundColor Green
    Write-Host ' with user ID a of ' -NoNewline 
    Write-Host $selection.samAccountName -NoNewline -ForegroundColor Green