0

For whatever reason the While loop works by itself, the Switch statement works by itself, when I combine them.. the While loop works ok, the Switch statement though.. not so much.

y or n are only values the While loop accepts, the problem is that when I give it y or n, none of the code gets executed, the script just finishes.

PowerShell version is 5.1.

While (($UserInput = Read-Host -Prompt "Are you sure? (y/n)") -notmatch '^n$|^y$') {
    Switch ($UserInput) {
        'y' {
            Try {
                Write-Output "Success."
        }
            Catch {
                Write-Output "Error."
            }
        }
        'n' {
            Write-Output "Cancelled."
        }
    }
}
4
  • here is what your code seems to do -- [1] get input [2] test if it does not match ONLY a y or an n [3] if it fails the test [anything other than a y or a n], it tests against a y or n !!!!! [grin] ///// you already made sure it would NOT have either of those in it ... so why do you expect either of the two switch values to trigger? you would need to include a default to handle non-matches. ///// also, the try/catch does nothing there ... what are you trying to do with that? Commented Feb 19, 2019 at 8:40
  • Well, it should match either y (proceed with executing the command), or n (end the script) and while either y or n are not provided, it should remain in the loop. As to the try/catch, I had some other code there initially, but it doesn't matter since it wouldn't output even the simple Write-Output cmdlets. Commented Feb 19, 2019 at 9:13
  • seriously, follow the logic of your code. [grin] it NEVER reaches the switch because the while says "only run the loop code IF neither an "n" nor a "y" is entered. Commented Feb 19, 2019 at 9:19
  • Yes, it is a bit weird. But when I used -match, the loop broke. If I entered y or n, the correct blocks would get executed, but when I entered something else, it would just end script. That's not exactly a loop. I ended up using not -notmatch, as shown below by @Mudit Bahedia and made some changes, by adding return to each output, otherwise the loop would not end. Commented Feb 19, 2019 at 10:05

2 Answers 2

2

here's a rather more robust method to do what you seem to want. it sets up the valid choices, asks for input, detects invalid input, warns about that, displays the "success" or "failure" messages - all without twisty logic. [grin]

$Choice = ''
$ValidChoiceList = @(
    'n'
    'y'
    )

while ([string]::IsNullOrEmpty($Choice))
    {
    $Choice = Read-Host 'Are you sure? [n/y] '
    if ($Choice -notin $ValidChoiceList)
        {
        [console]::Beep(1000, 300)
        Write-Warning ('Your choice [ {0} ] is not valid.' -f $Choice)
        Write-Warning '    Please try again & choose "n" or "y".'

        $Choice = ''
        pause
        }
    switch ($Choice)
        {
        'y' {Write-Host 'Success!'; break}
        'n' {Write-Warning '    Failure!'; break}
        }
    }

on screen output ...

Are you sure? [n/y] : t
WARNING: Your choice [ t ] is not valid.
WARNING:     Please try again & choose "n" or "y".
Press Enter to continue...: 
Are you sure? [n/y] : y
Success!
Sign up to request clarification or add additional context in comments.

Comments

0

You are using -notmatch. Hence While loop is resulting in false and loop is not getting executed. As you want to execute the script until you get 'y' or 'n' as input, just use ! which will execute the script until it receives 'y' or 'n' as input. Use below code:

While (!($UserInput = Read-Host -Prompt "Are you sure? (y/n)") -notmatch '^n$|^y$') {
Switch ($UserInput) {
    'y' {
        Try {
            Write-Output "Success."
    }
        Catch {
            Write-Output "Error."
        }
    }
    'n' {
        Write-Output "Cancelled."
        }
    }
}

1 Comment

Hi, Thanks and I tried that. Initially it executed the y or n blocks, but wouldn't end the script, once I either entered y or n, it would continue the loop. Then I thought I'd just add break after the Success, Error, Cancelled outputs, which didn't work. Turned out it was return what I was looking for. Now it seems to work as intended.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.