Use Functions with a Switch Statement

Hello,

I’m trying to figure out how I can use a function to validate the selection made in my switch statement and store it in a variable that can be used to run specified code for the selected task.

I could easily reuse the same variable for each switch statement and run the code, but I was looking to see if I could run the script, make my selection and then let the function store the appropriate value in the variable that I’ll be using in the switch statement code.

For example, I’m trying to use an if/elseif statement in the function to store my specified value based on the menu selection:

function Get-TaskName { 
    
    param($TaskName)
    if    ($selection -eq '1'){ $TaskName = "Mirror ALL VM's to NAS" }
    elseif($selection -eq '2'){ $TaskName = "Mirror SOURCE VMs to NAS" }
    elseif($selection -eq '3'){ $TaskName = "Mirror Clients/Servers to NAS" }
    elseif($selection -eq '4'){ $TaskName = "Copy ALL VM's to HOST" }
    elseif($selection -eq '5'){ $TaskName = "Copy SOURCE VM's to HOST" }

}

I know it’s not formatted correctly, but I just wanted to be able to display it so everything lines up…

In the switch statement below, I want to use that $TaskName variable as part of the logfile name.

SAMPLE CODE:

Show-Menu
$selection = Read-Host 'Please make a selection'
$hostname = $env:computername # Get Hostname
$TaskName = Get-TaskName

    switch ($selection)
    {
        # Mirror ALL VM's to NAS
    '1' { 
            
        if($hostname -ne 'GHOST'){
            Write-Host "Wrong Host! Wrong Choice! Try again SUCKA!" -ForegroundColor Red
            exit
        }else{
            Write-Host "Started running $TaskName..." -ForegroundColor Yellow
            pause # only used for testing purposes
        } 
    }

I thought I could tuck $TaskName = Get-TaskName below my menu selection line, but no values are being stored in the $TaskName variable that I can use.

My script runs fine otherwise. I’m just trying to not have to add each of those to each switch statement code to run.

Any help/advice would be greatly appreciated…

Okay, so it looks like I may have accidently got the function to work. I’m still testing it out to make sure it works throughout the script and will report back.

It looks like I needed to add return $TaskName at the bottom of the function.
I even added [string] for param([string]$TaskName) but that didn’t make any difference. It works without it.

Perhaps I’m still missing something to get everything out of this function…?

Is it better to leave in [string] and perhaps make it [CmdletBinding()]?

Here’s what it looks like now:

function Get-TaskName { 

  [CmdletBinding()]
  param([string]$TaskName)
  
  if    ($selection -eq '1'){ $TaskName = "Mirror ALL VM's to NAS" }
  elseif($selection -eq '2'){ $TaskName = "Mirror SOURCE VMs to NAS" }
  elseif($selection -eq '3'){ $TaskName = "Mirror Clients/Servers to NAS" }
  elseif($selection -eq '4'){ $TaskName = "Copy ALL VM's to HOST" }
  elseif($selection -eq '5'){ $TaskName = "Copy SOURCE VM's to HOST" }
  return $TaskName

}

You don’t need to use the return keyword with PowerShell. Any unassigned output is returned.

A switch would be better than lots of elseif statements:

function Get-TaskName {

    [CmdletBinding()]
    param([int]$Selection)

    switch ($Selection) {
        1 { "Mirror ALL VM's to NAS" }
        2 { "Mirror SOURCE VMs to NAS" }
        3 { "Mirror Clients/Servers to NAS" }
        4 { "Copy ALL VM's to HOST" }
        5 { "Copy SOURCE VM's to HOST" }    
    }

}

$TaskName = Get-TaskName -Selection 4

The apostrophes and slash are going to cause you pain if you really do want to use them in logfile names.

2 Likes

Hi Matt,

Thanks for helping me clean up my messy function. I took your advice and used your switch statement in the function and ran my tests. I only had to make some minor changes for it to work in my existing script.

The return thing was confusing me during some of my earlier experiments. Some worked and some didn’t. I honestly couldn’t figure it out.

After comparing the two, I certainly can’t argue with that. I’ll be experimenting with this in future scripts I’m currently converting from batch to posh. This was VERY HELPFUL indeed.

So, all I had to do was change the following:

  • $selection to $SelTask as that’s the variable for my switch statement in the main menu.
  • Added $task = Get-TaskName -SelTask $selection right before my main menu is initiated.
  • And cleaned up the task names by dropping the slash you pointed out, as well as those apostrophe’s.

Not much different than you gave me, but here it is:

function Get-TaskName {

    [CmdletBinding()]
    param([int]$SelTask)

    switch ($SelTask) {
        1 { "Mirror ALL VMs to NAS" }
        2 { "Mirror SOURCE VMs to NAS" }
        3 { "Mirror Clients-Servers to NAS" }
        4 { "Copy ALL VMs to HOST" }
        5 { "Copy SOURCE VMs to HOST" }    
    }

}

And here’s where I was able to call your function with the new parameters:

 Show-Menu
 $selection = Read-Host 'Please make a selection'

 # Get Function Values
 $copy = Get-CopyOptions
 $source =Get-Source
 $dest = Get-Dest
 $task = Get-TaskName -SelTask $selection


    Switch ($selection)

I tested all five options and everything is working perfectly!

Thanks again, Matt