Powershell script ignoring $userInput variable

Viewed 77
function processSearch {
Get-Process -Name "$processSearch*"
}

function processKill {
Stop-Process -Name "$processSearch*"
}

$processSearch = Read-Host -Prompt "Enter the full or partial name of the process: "

processSearch

 if ((Get-Process -Name "$processSearch*") -eq $null) {
    Write-Output "ERROR: NO PROCESS FOUND."
    [Threading.Thread]::Sleep(3000) 
 }

if ((Get-Process -Name "$processSearch*") -ne $null) {
    $userInput= Read-Host -Prompt "Kill process?"
} 
     
if ($userInput -eq "y" -or "Y") {
    processKill
}
elseif ($userInput -eq "n" -or "N") {
    Write-Output "Process not killed."   
}
else {
    Write-Output "ERROR: UNHANDLED INPUT."
}            

When my script gets to $userInput= Read-Host -Prompt "Kill process?", and I enter any text, the script will terminate the selected process.

I'm new to scripting, so please let me know where my logic is flawed, thank you.

2 Answers

The issue you're experiencing is because when you're checking the $userInput variable you've forgotten to declare what variable to check against in your -or part of the clause.

This code:

if ($userInput -eq "y" -or "Y") {
    processKill
}
elseif ($userInput -eq "n" -or "N") {
    Write-Output "Process not killed."   
}
else {
    Write-Output "ERROR: UNHANDLED INPUT."
}  

should become:

if ($userInput -eq "y" -or $userInput -eq "Y") {
    processKill
}
elseif ($userInput -eq "n" -or $userInput -eq "N") {
    Write-Output "Process not killed."   
}
else {
    Write-Output "ERROR: UNHANDLED INPUT."
}  

You could also make the if statements a little less verbose by using the case-sensitive -cin operator as this will check if the value is in an array of given values as below:

if ($userInput -cin "y", "Y") {
    processKill
}
elseif ($userInput -cin "n", "N") {
    Write-Output "Process not killed."   
}
else {
    Write-Output "ERROR: UNHANDLED INPUT."
}

NiMux's answer makes good points, but it's worth taking a step back:

  • PowerShell's operators are case-insensitive by default:

    • 'y' -eq 'Y' is $true.
  • To perform case-sensitive operations, prefix the operator name with c; e.g. -ceq:

    • 'Y' -ceq 'Y' is $true, but 'y' -ceq 'Y' is $false.

Therefore:

  • $userInput -eq 'y' and $userInput -eq 'n' are sufficient in your case.

  • In case you truly have multiple values to test against, use the -inoperator; e.g.:

    • $userInput -in 'y', 'n', 'c'

As for what you tried:

Due to PowerShell's operator precedence,

$userInput -eq "y" -or "Y"

is evaluated as:

($userInput -eq "y") -or ("Y")

That is, the RHS operand of the -or operation is string "Y" alone, and evaluating a non-empty string in PowerShell in a Boolean context always yields $true (irrespective of what the string contains).

In effect, your attempt was therefore equivalent to the following, which is always $true:

($userInput -eq "y") -or $true

The immediate (but suboptimal) fix to your attempt would have been what's shown in NiMux's answer: use of two separate -eq operations ($userInput -eq 'y' -or $userInput -eq 'Y').

Related