Everything you ever wanted to know about the switch statement - PowerShell (2024)

  • Article

Like many other languages, PowerShell has commands for controlling the flow of execution within yourscripts. One of those statements is the switch statement and in PowerShell, it offersfeatures that aren't found in other languages. Today, we take a deep dive into working with thePowerShell switch.

Note

The original version of this article appeared on the blog written by@KevinMarquette. The PowerShell team thanks Kevin for sharing this content withus. Please check out his blog at PowerShellExplained.com.

The if statement

One of the first statements that you learn is the if statement. It lets you execute a script blockif a statement is $true.

if ( Test-Path $Path ){ Remove-Item $Path}

You can have much more complicated logic using elseif and else statements. Here is an examplewhere I have a numeric value for day of the week and I want to get the name as a string.

$day = 3if ( $day -eq 0 ) { $result = 'Sunday' }elseif ( $day -eq 1 ) { $result = 'Monday' }elseif ( $day -eq 2 ) { $result = 'Tuesday' }elseif ( $day -eq 3 ) { $result = 'Wednesday' }elseif ( $day -eq 4 ) { $result = 'Thursday' }elseif ( $day -eq 5 ) { $result = 'Friday' }elseif ( $day -eq 6 ) { $result = 'Saturday' }$result
Wednesday

It turns out that this is a common pattern and there are many ways to deal with this. Oneof them is with a switch.

Switch statement

The switch statement allows you to provide a variable and a list of possible values. If the valuematches the variable, then its scriptblock is executed.

$day = 3switch ( $day ){ 0 { $result = 'Sunday' } 1 { $result = 'Monday' } 2 { $result = 'Tuesday' } 3 { $result = 'Wednesday' } 4 { $result = 'Thursday' } 5 { $result = 'Friday' } 6 { $result = 'Saturday' }}$result
'Wednesday'

For this example, the value of $day matches one of the numeric values, then the correct name isassigned to $result. We're only doing a variable assignment in this example, but any PowerShellcan be executed in those script blocks.

Assign to a variable

We can write that last example in another way.

$result = switch ( $day ){ 0 { 'Sunday' } 1 { 'Monday' } 2 { 'Tuesday' } 3 { 'Wednesday' } 4 { 'Thursday' } 5 { 'Friday' } 6 { 'Saturday' }}

We're placing the value on the PowerShell pipeline and assigning it to the $result. You can dothis same thing with the if and foreach statements.

Default

We can use the default keyword to identify the what should happen if there is no match.

$result = switch ( $day ){ 0 { 'Sunday' } # ... 6 { 'Saturday' } default { 'Unknown' }}

Here we return the value Unknown in the default case.

Strings

I was matching numbers in those last examples, but you can also match strings.

$item = 'Role'switch ( $item ){ Component { 'is a component' } Role { 'is a role' } Location { 'is a location' }}
is a role

I decided not to wrap the Component,Role and Location matches in quotes here to highlight thatthey're optional. The switch treats those as a string in most cases.

Arrays

One of the cool features of the PowerShell switch is the way it handles arrays. If you give aswitch an array, it processes each element in that collection.

$roles = @('WEB','Database')switch ( $roles ) { 'Database' { 'Configure SQL' } 'WEB' { 'Configure IIS' } 'FileServer' { 'Configure Share' }}
Configure IISConfigure SQL

If you have repeated items in your array, then they're matched multiple times by the appropriatesection.

PSItem

You can use the $PSItem or $_ to reference the current item that was processed. When we do asimple match, $PSItem is the value that we're matching. I'll be performing some advanced matchesin the next section where this variable is used.

Parameters

A unique feature of the PowerShell switch is that it has a number of switch parameters thatchange how it performs.

-CaseSensitive

The matches aren't case-sensitive by default. If you need to be case-sensitive, you can use-CaseSensitive. This can be used in combination with the other switch parameters.

-Wildcard

We can enable wildcard support with the -wildcard switch. This uses the same wildcard logic as the-like operator to do each match.

$Message = 'Warning, out of disk space'switch -Wildcard ( $message ){ 'Error*' { Write-Error -Message $Message } 'Warning*' { Write-Warning -Message $Message } default { Write-Information $message }}
WARNING: Warning, out of disk space

Here we're processing a message and then outputting it on different streams based on the contents.

-Regex

The switch statement supports regex matches just like it does wildcards.

switch -Regex ( $message ){ '^Error' { Write-Error -Message $Message } '^Warning' { Write-Warning -Message $Message } default { Write-Information $message }}

I have more examples of using regex in another article I wrote:The many ways to use regex.

-File

A little known feature of the switch statement is that it can process a file with the -Fileparameter. You use -file with a path to a file instead of giving it a variable expression.

switch -Wildcard -File $path{ 'Error*' { Write-Error -Message $PSItem } 'Warning*' { Write-Warning -Message $PSItem } default { Write-Output $PSItem }}

It works just like processing an array. In this example, I combine it with wildcard matching andmake use of the $PSItem. This would process a log file and convert it to warning and errormessages depending on the regex matches.

Advanced details

Now that you're aware of all these documented features, we can use them in the context of moreadvanced processing.

Expressions

The switch can be on an expression instead of a variable.

switch ( ( Get-Service | Where status -eq 'running' ).name ) {...}

Whatever the expression evaluates to is the value used for the match.

Multiple matches

You may have already picked up on this, but a switch can match to multiple conditions. This isespecially true when using -wildcard or -regex matches. You can add the same condition multipletimes and all are triggered.

switch ( 'Word' ){ 'word' { 'lower case word match' } 'Word' { 'mixed case word match' } 'WORD' { 'upper case word match' }}
lower case word matchmixed case word matchupper case word match

All three of these statements are fired. This shows that every condition is checked (in order). Thisholds true for processing arrays where each item checks each condition.

Continue

Normally, this is where I would introduce the break statement, but it's better that we learn howto use continue first. Just like with a foreach loop, continue continues onto the next item inthe collection or exits the switch if there are no more items. We can rewrite that last examplewith continue statements so that only one statement executes.

switch ( 'Word' ){ 'word' { 'lower case word match' continue } 'Word' { 'mixed case word match' continue } 'WORD' { 'upper case word match' continue }}
lower case word match

Instead of matching all three items, the first one is matched and the switch continues to the nextvalue. Because there are no values left to process, the switch exits. This next example is showinghow a wildcard could match multiple items.

switch -Wildcard -File $path{ '*Error*' { Write-Error -Message $PSItem continue } '*Warning*' { Write-Warning -Message $PSItem continue } default { Write-Output $PSItem }}

Because a line in the input file could contain both the word Error and Warning, we only want thefirst one to execute and then continue processing the file.

Break

A break statement exits the switch. This is the same behavior that continue presents for singlevalues. The difference is shown when processing an array. break stops all processing in the switchand continue moves onto the next item.

$Messages = @( 'Downloading update' 'Ran into errors downloading file' 'Error: out of disk space' 'Sending email' '...')switch -Wildcard ($Messages){ 'Error*' { Write-Error -Message $PSItem break } '*Error*' { Write-Warning -Message $PSItem continue } '*Warning*' { Write-Warning -Message $PSItem continue } default { Write-Output $PSItem }}
Downloading updateWARNING: Ran into errors downloading filewrite-error -message $PSItem : Error: out of disk space+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException

In this case, if we hit any lines that start with Error then we get an error and the switch stops.This is what that break statement is doing for us. If we find Error inside the string and notjust at the beginning, we write it as a warning. We do the same thing for Warning. It's possiblethat a line could have both the word Error and Warning, but we only need one to process. This iswhat the continue statement is doing for us.

Break labels

The switch statement supports break/continue labels just like foreach.

:filelist foreach($path in $logs){ :logFile switch -Wildcard -File $path { 'Error*' { Write-Error -Message $PSItem break filelist } 'Warning*' { Write-Error -Message $PSItem break logFile } default { Write-Output $PSItem } }}

I personally don't like the use of break labels but I wanted to point them out because they'reconfusing if you've never seen them before. When you have multiple switch or foreach statementsthat are nested, you may want to break out of more than the inner most item. You can place a labelon a switch that can be the target of your break.

Enum

PowerShell 5.0 gave us enums and we can use them in a switch.

enum Context { Component Role Location}$item = [Context]::Roleswitch ( $item ){ Component { 'is a component' } Role { 'is a role' } Location { 'is a location' }}
is a role

If you want to keep everything as strongly typed enums, then you can place them in parentheses.

switch ($item ){ ([Context]::Component) { 'is a component' } ([Context]::Role) { 'is a role' } ([Context]::Location) { 'is a location' }}

The parentheses are needed here so that the switch doesn't treat the value [Context]::Location asa literal string.

ScriptBlock

We can use a scriptblock to perform the evaluation for a match if needed.

$age = 37switch ( $age ){ {$PSItem -le 18} { 'child' } {$PSItem -gt 18} { 'adult' }}
'adult'

This adds complexity and can make your switch hard to read. In most cases where you would usesomething like this it would be better to use if and elseif statements. I would consider usingthis if I already had a large switch in place and I needed two items to hit the same evaluationblock.

One thing that I think helps with legibility is to place the scriptblock in parentheses.

switch ( $age ){ ({$PSItem -le 18}) { 'child' } ({$PSItem -gt 18}) { 'adult' }}

It still executes the same way and gives a better visual break when quickly looking at it.

Regex $matches

We need to revisit regex to touch on something that isn't immediately obvious. The use of regexpopulates the $matches variable. I do go into the use of $matches more when I talk aboutThe many ways to use regex. Here is a quick sample to show it inaction with named matches.

$message = 'my ssn is 123-23-3456 and credit card: 1234-5678-1234-5678'switch -regex ($message){ '(?<SSN>\d\d\d-\d\d-\d\d\d\d)' { Write-Warning "message contains a SSN: $($matches.SSN)" } '(?<CC>\d\d\d\d-\d\d\d\d-\d\d\d\d-\d\d\d\d)' { Write-Warning "message contains a credit card number: $($matches.CC)" } '(?<Phone>\d\d\d-\d\d\d-\d\d\d\d)' { Write-Warning "message contains a phone number: $($matches.Phone)" }}
WARNING: message may contain a SSN: 123-23-3456WARNING: message may contain a credit card number: 1234-5678-1234-5678

$null

You can match a $null value that doesn't have to be the default.

$values = '', 5, $nullswitch ( $values ){ $null { "Value '$_' is `$null" } { '' -eq $_ } { "Value '$_' is an empty string" } default { "Value [$_] isn't an empty string or `$null" }}
Value '' is an empty stringValue [5] isn't an empty string or $nullValue '' is $null

When testing for an empty string in a switch statement, it's important to use the comparisonstatement as shown in this example instead of the raw value ''. In a switch statement, the rawvalue '' also matches $null. For example:

$values = '', 5, $nullswitch ( $values ){ $null { "Value '$_' is `$null" } '' { "Value '$_' is an empty string" } default { "Value [$_] isn't an empty string or `$null" }}
Value '' is an empty stringValue [5] isn't an empty string or $nullValue '' is $nullValue '' is an empty string

Also, be careful with empty returns from cmdlets. Cmdlets or pipelines that have no output aretreated as an empty array that doesn't match anything, including the default case.

$file = Get-ChildItem NonExistantFile*switch ( $file ){ $null { '$file is $null' } default { "`$file is type $($file.GetType().Name)" }}# No matches

Constant expression

Lee Dailey pointed out that we can use a constant $true expression to evaluate [bool] items.Imagine if we have several boolean checks that need to happen.

$isVisible = $false$isEnabled = $true$isSecure = $trueswitch ( $true ){ $isEnabled { 'Do-Action' } $isVisible { 'Show-Animation' } $isSecure { 'Enable-AdminMenu' }}
Do-ActionEnabled-AdminMenu

This is a clean way to evaluate and take action on the status of several boolean fields. The coolthing about this is that you can have one match flip the status of a value that hasn't beenevaluated yet.

$isVisible = $false$isEnabled = $true$isAdmin = $falseswitch ( $true ){ $isEnabled { 'Do-Action' $isVisible = $true } $isVisible { 'Show-Animation' } $isAdmin { 'Enable-AdminMenu' }}
Do-ActionShow-Animation

Setting $isEnabled to $true in this example makes sure that $isVisible is also set to $true.Then when $isVisible gets evaluated, its scriptblock is invoked. This is a bit counter-intuitivebut is a clever use of the mechanics.

$switch automatic variable

When the switch is processing its values, it creates an enumerator and calls it $switch. This isan automatic variable created by PowerShell and you can manipulate it directly.

$a = 1, 2, 3, 4switch($a) { 1 { [void]$switch.MoveNext(); $switch.Current } 3 { [void]$switch.MoveNext(); $switch.Current }}

This gives you the results of:

24

By moving the enumerator forward, the next item doesn't get processed by the switch but you canaccess that value directly. I would call it madness.

Other patterns

Hashtables

One of my most popular posts is the one I did on hashtables. One of the use cases fora hashtable is to be a lookup table. That's an alternate approach to a common pattern that aswitch statement is often addressing.

$day = 3$lookup = @{ 0 = 'Sunday' 1 = 'Monday' 2 = 'Tuesday' 3 = 'Wednesday' 4 = 'Thursday' 5 = 'Friday' 6 = 'Saturday'}$lookup[$day]
Wednesday

If I'm only using a switch as a lookup, I often use a hashtable instead.

Enum

PowerShell 5.0 introduced the Enum and it's also an option in this case.

$day = 3enum DayOfTheWeek { Sunday Monday Tuesday Wednesday Thursday Friday Saturday}[DayOfTheWeek]$day
Wednesday

We could go all day looking at different ways to solve this problem. I just wanted to make sure youknew you had options.

Final words

The switch statement is simple on the surface but it offers some advanced features that most peopledon't realize are available. Stringing those features together makes this a powerful feature. I hopeyou learned something that you had not realized before.

Everything you ever wanted to know about the switch statement - PowerShell (2024)

FAQs

What is the switch statement in PowerShell? ›

When you need to check the multiple conditions in PowerShell, we must use the Switch statement. This statement in PowerShell is equivalent to the series of 'If' statements, but it is simple to use. This statement lists each condition and the code of block associated with each condition.

What are the switch parameters in PowerShell? ›

Switch parameters. Switch parameters are parameters that take no parameter value. Instead, they convey a Boolean true-or-false value through their presence or absence, so that when a switch parameter is present it has a true value and when absent it has a false value.

What are the switches that can help the command provide to understand what can happen if the command is provided on PowerShell? ›

Both experienced administrators and script writers, and administrators who are new to Exchange and scripting, can benefit from using the WhatIf, Confirm, and ValidateOnly switches. These switches let you control how your commands run and indicate exactly what a command will do before it affects data.

How to bypass confirm in PowerShell script? ›

Solution: Include the -Confirm parameter with a $false setting. When running cmdlets discussed in this book, you might receive a confirmation message to confirm the action being processed. If you use these cmdlets in scripts, the script will not run straight through without prompting for the confirmation.

How do you explain a switch statement? ›

The switch statement or switch case in java is a multi-way branch statement. Based on the value of the expression given, different parts of code can be executed quickly. The given expression can be of a primitive data type such as int, char, short, byte, and char.

How to use switch in shell scripting? ›

In shell scripting switch case is represented using keywords case and esac which will do multilevel branching and checking in a better way than multiple if-else conditions. Switch case will need an expression which it needs to evaluate and need to perform multiple operations based on the outcome of the expression.

What is the difference between switch and parameter in PowerShell? ›

A switch is similar, you list the name of the switch on call to the function, but unlike a regular parameter you pass in no value. The presence of the switch is enough to tell the function what you want to do.

How do I ping a switch in PowerShell? ›

So, how do you ping in PowerShell? Use the 'Test-Connection' applet. It's that easy. Much like you would use 'ping' in CMD, type in 'Test-Connection' followed by '-Ping', '-TargetName', and an IP address to send a ping to that device.

What are switches in commands? ›

A command-line switch is a modifier that is added to the .exe file. A startup file with a switch looks like this. In this example, a command-line switch has been added to the .exe file for Microsoft Outlook. The switch consists of a forward slash and a word or abbreviation that indicates the switch's action.

How do you switch multiple values in PowerShell? ›

Switch Multiple Values

With the switch statement in PowerShell, we can also test multiple values instead. To do this you will need to comma-separate the values. Each value will then be tested against the conditions inside the switch statement.

What are the most common uses of PowerShell? ›

As a scripting language, PowerShell is commonly used for automating the management of systems. It's also used to build, test, and deploy solutions, often in CI/CD environments. PowerShell is built on the .NET Common Language Runtime (CLR). All inputs and outputs are .NET objects.

What are the parameters of a function in PowerShell? ›

The parameters can be named, positional, switch, or dynamic parameters. Function parameters can be read from the command line or from the pipeline. Functions can return values that can be displayed, assigned to variables, or passed to other functions or cmdlets.

How do I avoid confirmation in PowerShell? ›

If Confirm is explicitly set to false ( -Confirm:$false ), the cmdlet runs without prompting for confirmation and the $ConfirmPreference shell variable is ignored.

How do I prevent confirm in PowerShell? ›

To prevent the confirmation prompt, add -Confirm:$false to the end of the command.

How do I avoid confirm prompt in PowerShell? ›

To suppress confirmation, use -Confirm:$false . Valid values of $ConfirmPreference : None: PowerShell doesn't prompt automatically.

What is the purpose of the switch command? ›

switch command (C and C++) The switch command enables you to transfer control to different commands within the switch body, depending on the value of the switch expression. The switch , case , and default keywords must be lowercase and cannot be abbreviated.

When should a switch () case statement be used? ›

You can use a switch-case when:
  • There are multiple choices for an expression.
  • The condition is based on a predefined set of values such as enums, constants, known types. For example, error codes, statuses, states, object types, etc.
Nov 9, 2021

References

Top Articles
Latest Posts
Article information

Author: Frankie Dare

Last Updated:

Views: 5356

Rating: 4.2 / 5 (73 voted)

Reviews: 88% of readers found this page helpful

Author information

Name: Frankie Dare

Birthday: 2000-01-27

Address: Suite 313 45115 Caridad Freeway, Port Barabaraville, MS 66713

Phone: +3769542039359

Job: Sales Manager

Hobby: Baton twirling, Stand-up comedy, Leather crafting, Rugby, tabletop games, Jigsaw puzzles, Air sports

Introduction: My name is Frankie Dare, I am a funny, beautiful, proud, fair, pleasant, cheerful, enthusiastic person who loves writing and wants to share my knowledge and understanding with you.