Using Switch

Hello,

Please advise if this is possible

$variable = “Do you want reboot computer 1, 2 or both? Type 1 or computerA, 2 or computerB, or 3 for computer A and B”

Switch ($variable) {

1 { Write-Output " Code will be here to reboot computerA" break}
2 { Write-Output" Code will be here to reboot computerB" break }
3 { # How do i call switch 1 and then switch 2 rather than rewriting everything in switch 1 and 2 into switch 3 }
}

The actual code i am writing is much bigger and because i’m struggling to find a way to call switch 1 and 2… im having to duplicate work into switch 3 which seems very inefficient to me.

Thanks for your help!

Maybe use a function, so the amount of code in each switch statement is minimal?

Alternatively, just write the entire thing as a function that takes a string array and cycles through the ones provided?

Otherwise I am not really sure this works for a switch statement, maybe two IFs fits this situation better. You could say IF 1 OR both, followed by IF 2 or Both.

The way you’ve structured the code, there’s going to be some duplication either way (if nothing else, calls to the same function to reboot the computers.)

However, if $variable were an array containing either 1, 2, or both 1 and 2, then this would work:

switch ($variable) {
    1 { Write-Output " Code will be here to reboot computerA" }
    2 { Write-Output" Code will be here to reboot computerB" }
}

Note that you have to get rid of the “break” statements in order for this processing of an entire array to take place. Here’s a more generic example demonstrating the results:

$array = 1,2,4

switch ($array)
{
    1 { "Array contains 1" }
    2 { "Array contains 2" }
    3 { "Array contains 3" }
    4 { "Array contains 4" }
    5 { "Array contains 5" }
}

Edit: The forums are giving me a hard time for some reason; my closing quotes (whether single or double) keep showing up as HTML escape sequences.

One option is a prompt outlined here: ITPro Today: IT News, How-Tos, Trends, Case Studies, Career Tips, More

When you start asking more than simple yes\no questions or have to ask multiple questions to do a task, it’s better to use a GUI interface IMHO. If you created a simple form and checkboxes for each computer with a Reboot button, then you could check 2 of 5 computers and the code is going to do something like foreach checkbox in form { if ($.Checked -eq $true) {Restart-Computer $.Value} }. You just need to make a determination if your scenario is complex enough to warrant a GUI. If you want to try a GUI option, you’ll need Powershell Studio from Sapien Technologies or they have a deprecated free tool (you need to sign up, sign in and there is free tools folder in downloads if I recall correctly) and build the basic form. Powershell uses .NET forms and requires A LOT of code for a form, so a WYSIWYG interface will speed things along.

Using a question & and answer approaches works for a couple of machines but think about the possible combinations when you get to 5 machines! At 20 machines you don’t even want to think about it.

The suggestion of writing a function to do this is the better approach. Create the function so that it can accept an array of computer names. You can then use it like this:

rebootcomputer -comp computera

rebootcomputer -comp computer

rebootcomputer -comp computera, computer

rebootcomputer -comp computera, computer, computer

if you have a lot of computers - put their names in a file then

rebootcomputer -comp (get-content computers.txt)

Forcing you scripts to be interactive negates one of the great advantages of automation - you don’t need to touch it. having a file of computer names as input means I can schedule the reboots to occur overnight. Unless you’re working the night shift you can’t do that with an interactive script

[blockquote]rebootcomputer -comp computera

rebootcomputer -comp computer

rebootcomputer -comp computera, computer

rebootcomputer -comp computera, computer, computer

if you have a lot of computers – put their names in a file then

rebootcomputer -comp (get-content computers.txt)[/blockquote]

Also, just a side note, the Restart-Computer cmdlet already exists and contains all of the functionality (and much more) that Richard shared. Just wanted to ensure it was mentioned before someone attempted to create a function for something that already is available.

Hello Guys,

thanks for the input! I think i will go with the function method - my actual script is quite a large bit of code that needs to be resuable and i think a function might be the cleanest way.

I will just need to work on parameterising the script so it can take various inputs and then translate 3 to mean calling function which i guess could be called from the switch so something like

switch ($variable) {

1 { function-A }
2 { function-B }
3 { function-A, function-B}

}

i’ll give this a go and let you know how i get on - should work fine don’t see any issues with this one.

thanks for your advice everyone!

No - you’re making it over complicated

function reboot {
param ( [string]$computername )

foreach ($computer in $computername) {

add code to reboot here

}

}

Hello!

I won’t be able to use the foreach reason being for each will cycle through each of the computers which is not what is desired.

It should instead be - should computer A be restarted?
- should computer B be restarted?
- should computer A and B be restarted?

I’ve tested the the function method and implemented like this

$computer = read-host "which computer should restart? 1, 2 or 3 (3 for both)

switch ($computer)

1 { function-A ($computer) }
2 { function-A {$computer) }
3 {
$computer = 1
function-A

    $computer = 2 
    function-A 

}

Any alternatives / improvements on this? With foreach we have no control over which one’s we want restarted right?

By the way, this is not actually for a computer restart -the reason script is for creating shares on a VNX SAN - computer restart was just a example to use for the purposes of the idea because its essentially the same thing.

thanks!

Yes foreach iterates through each item that has been passed through as input. Therefore, if you don’t want something to apply, either filter it out, or don’t include it in the input!! You’re massively over complicating something that is as simple as:

Restart-Computer Comp1

OR

Restart-Computer Comp2

OR

Restart-Computer Comp1,Comp2

The above code accomplishes exactly what you’re suggesting by using a switch statement, however it’s done in just one line. The choice for the user is to input the name of the computer they want to restart.

Hi Adnan,

As I understand the thread, restarting a computer is just an example and not at all what you actually want to do. You do want to display an interactive question and trigger one or several action(s) based on the answer.

Assuming that is correct, you need to handle if the user gives an invalid answer and have a “default” action. Also an important thing to note about the switch statement is that any condition that is met will get executed. That being said you could either use Switch like you are using in your post above where the condition 1 only will trigger if the answer is exactly 1, or you could use the parameter -Regex for Switch. -Regex will treat each condition as a regular expression and if it matches the tested value, the scriptblock will execute.

Here is an example where an invalid answer will trigger the question again and if the answer contains ‘A’, action A will get triggered. If the answer contains ‘B’, action B will get triggered. Answer ‘AB’ will result in both actions. A thing to have in mind here is that if a user enters ‘abcdefg’ (which might be considered an invalid answer), a and b will get triggered.

$Question = "Which option would you like? (A,B or AB)"
$KeepLooping = $true
Do
{
    $Answer = Read-Host -Prompt $Question
    Switch -Regex ($Answer) 
    {
        'A' 
        {
            Write-Verbose -Message 'Calling function A'
            # Type your action A here
            $KeepLooping = $false
        }
        'B' 
        {
            Write-Verbose -Message 'Calling function B'
            # Type your action A here
            $KeepLooping = $false
        }
        default 
        {
            Write-Warning -Message 'Unrecognized answer, please try again.'
        }
    }
} While ($KeepLooping)

Hi Simon,

You are spot on.

That’s interesting about the switch statement as I did not think about that at all. Instead I had a try and catch for any values beyond A and B following on from your example so people wouldn’t be able to E or F.

I think that method does accomplish what is necessary and also provides a fail safe too.

Thanks! I’ll let you know if i get any issues.

Cheers,

Adnan

Probably shouldn’t have used the computer-restart as an example lol caused too much confusion - i’ll keep that in mind next time :slight_smile: