Share via


Dynamically populate powershell switch statement

Question

Monday, January 6, 2014 8:20 PM

Hi,

I need help dynamically creating switch statement selections.

I can do this OK.

$ar = "RED","GREEN"

$ANS = (Read-Host "Choose from these $ar")
Choose from options RED GREEN: RED
$ANS
RED
switch ($ANS){

GREEN {write-host "GREEN"}
RED {write-host "RED"}
default {write-host "NO GOOD"}
}

RED

But What if I want to dynamically populate the choices of Red and Green from the $ar array? It does not work. For example if I replace this..

"GREEN {write-host "GREEN"}
RED {write-host "RED"}"

with this..

"foreach($y in $ar){
$y
{write-host "$y"}
}"

Purpose to dynamically create the menu contents based on the array and provide actions based on those. My contents are never static.

I assume I can dynamically populate these somehow but I get an error..

Missing statement block in switch statement clause.

Any ideas?

All replies (4)

Monday, January 6, 2014 8:40 PM ✅Answered | 4 votes

A switch statement is probably not appropriate, in this case.  You can just use a loop with an "if" statement instead:

$found = $false

foreach ($y in $ar)
{
    if ($ANS -eq $y)
    {
        Write-Host $y
        $found = $true
        break
    }
}

if (-not $found)
{
    Write-Host "NO GOOD"
}

For this simple example, you could also just use a conditional with the -Contains operator:

if ($ar -contains $ANS)
{
    Write-Host $ANS
}
else
{
    Write-Host "NO GOOD"
}

Monday, January 6, 2014 10:22 PM ✅Answered | 3 votes

Or, if you're absolutely adamant in using the switch statement, this is something you can do:

$validAnswerArray = @('yes','no','maybe')

$switchBlockTemplate = @'
param($ANS)
switch ($ANS)
{

'@

$actionStatementTemplate = 'Write-Host "{0}"'

$switchBlockContent = [String]::Empty

foreach ($validAnswer in $validAnswerArray)
{
    $actionStatement = $actionStatementTemplate -f $validAnswer
    $switchBlockContent += '"' + $validAnswer + '" { ' + $actionStatement + " }`r`n" 
}

$switchBlockContent += "default { Write-Host `"No Good`" }`r`n"

$switchBlock = [scriptblock]::Create($switchBlockTemplate + $switchBlockContent + '}')

cls
$ANS = Read-Host
Invoke-Command -ScriptBlock:$switchBlock -ArgumentList:@($ANS)

This is how you build dynamic statements in general.


Monday, January 6, 2014 11:45 PM

I am not good with powershell and I appreciate your feedback. The if statement inside the loop going through the array looking for a match in elements works better indeed. I am a sysadmin definitely not a programmer so i appreciate the advice on when and when not to use things like switch. This would have saved me some time.

Thanks again!


Monday, January 6, 2014 11:47 PM

I appreciate the reply. This looks complicated for my level but I will keep this in my notes for the future.

Thanks again