Why some character string caused do/while to fail, but others did not

In the following code snippet, when the second (2nd) “if” statement set the content of $Prompt to a string with the word of ‘NULL’ or ‘FALSE’ or ‘an Enter key’ (note the single quotes), the do {} while loop exited as though $Prompt contained “On” or “Off”. Surely, the do {} while $Prompt test should fail. If the code set $Prompt to ‘TRUE’ or "ABC’ when the user pressed the enter key, it worked as expected. What is so special about storing the string ‘NULL’, ‘FALSE’ or ‘an Enter key’ in a variable, that would cause the unexpected logic?

Clear-Host
Write-Host "Press the Enter key: " -NoNewline
do {
  $Prompt = Read-host
  if($Prompt.ToUpper() -notmatch '["On","Off"]')
  { Write-Host 'Enter ' -NoNewline
    Write-Host 'On ' -NoNewline -ForegroundColor Yellow
    Write-Host 'or ' -NoNewline
    Write-Host 'Off' -NoNewline -ForegroundColor Yellow
    Write-Host ', not ' -NoNewline
    if($Prompt -eq "") {$Prompt = 'NULL'}
    Write-Host "$Prompt " -NoNewline -ForegroundColor Red 
    Write-Host ', please try again: ' -NoNewline
    }
} while ($Prompt.ToUpper() -notmatch '["On","Off"]')

I ran more tests. Here’s the code snippet and the results. If there is no concrete explanation, I will post it as a bug.

Write-Host 'Enter on or off: ' -NoNewline
do {
  $Prompt = Read-host
  if($Prompt.ToUpper() -notmatch '["On","Off"]')
  { if($Prompt -eq "") { $Prompt = 'what' }
    Write-Host 'Incorrect input, please enter On or Off: '
  }
} while ($Prompt.ToUpper() -notmatch '["On","Off"]')
Write-Host 'Exited - Do {} While loop'
# Test results - Fail test means "exited the loop"
# Change $Prompt value in the statement: if($Prompt -eq "") { $Prompt = 'TRUE' }
# Fail test: 'NULL', 'FAIL', 'Enter Key', 'Joke', 'who'
# Pass test: 'TRUE', 'ABC', Numeric input, 'what', 'where'
#
# User input:
# Fail test: 'fila', 'FAIL', 'Enter Key', 'Joke', 'who'
# Pass test: 'TRUE', 'ABC', Numeric input, 'what', 'where'

I think your regex is off.

'O' -match '["On","Off"]'

returns $true and you would would be stuck with “O” in your prompt variable.

This works:

Clear-Host
Write-Host "Press the Enter key: " -NoNewline
do {
  $Prompt = Read-host
  if($Prompt.ToUpper() -notmatch '^(On|Off)$')
  { Write-Host 'Enter ' -NoNewline
    Write-Host 'On ' -NoNewline -ForegroundColor Yellow
    Write-Host 'or ' -NoNewline
    Write-Host 'Off' -NoNewline -ForegroundColor Yellow
    Write-Host ', not ' -NoNewline
    if($Prompt -eq "") {$Prompt = 'NULL'}
    Write-Host "$Prompt " -NoNewline -ForegroundColor Red 
    Write-Host ', please try again: ' -NoNewline
    }
} while ($Prompt.ToUpper() -notmatch '^(On|Off)$')

Thank you.
I misunderstood the -notmatch option. PowerNoobe

For working with arrays, you can use -in and -notin (or -contains and -notcontains if the array is at the left side) to check if a value is in the array. It doesn’t support partial matches, though.