Flow control is an important step in your PowerShell journey. When I was in school, there was an entire unit on conditional statements and a separate one on loops. It’s not really that bad, and easy enough to combine into one long post.
Conditional Statements
Conditional statements fire off if something is true or false. This is usually done through an expression but can be triggered with Booleans.
Logically, the easiest way to think about it is: “If this, then that.”
$myFruit = "apple"
if ($myFruit -eq "apple") { # Always indent the code to execute below
Write-Output("My fruit is an apple.")
}
You can add an elseif
if there is an additional action to be taken.
“If not this, but this, do this.”
$myFruit = "banana"
if ($myFruit -eq "apple") { # All false blocks skip
Write-Output("My fruit is an apple.")
}
elseif ($myFruit -eq "orange") {
Write-Output("My fruit is an orange.")
}
elseif ($myFruit -eq "banana") {
Write-Output("My fruit is a banana.")
}
Lastly, we can use else
to handle anything not specified.
$myFruit = "gopher"
if ($myFruit -eq "apple") {
Write-Output("My fruit is an apple.")
}
elseif ($myFruit -eq "orange") {
Write-Output("My fruit is an orange.")
}
elseif ($myFruit -eq "banana") {
Write-Output("My fruit is a banana.")
}
else {
Write-Output("Is that really a fruit?")
}
It’s also possible to “nest” these statements, so as long as they’re in the correct brackets you can get as specific as you’d like.
$myFruit = "crabapple"
if ($myFruit -like "*apple") {
Write-Output("My fruit is an apple.")
if ($myFruit -like "*granny*") {
Write-Output("My fruit is a Granny Smith Apple.")
}
elseif ($myFruit -like "*crab*") {
Write-Output("My fruit is a crabapple.")
}
}
You can also use the switch
function to do similar.
switch ($myFruit) {
"apple" {
Write-Output"My fruit is an apple.")
}
"banana" {
Write-Output("My fruit is a banana.")
}
"orange" {
Write-Output("My fruit is an orange.")
}
default {
Write-Output("Is that really a fruit?")
}
}
Loops
Loops are where the real time-savings come in. With them you can run code as many times as needed which makes things like bulk changes a breeze.
ForEach
– Run code for every object in a group.
$cities = @("New York", "Palo Alto", "Austin")
ForEach ($city in $cities) {
Write-Output("My home is the city of $city.")
}
We can alternatively pipe an array to ForEach
to do this, where $_
is the variable.
@("New York", "Palo Alto", "Austin") | ForEach {
Write-Output("My home is the city of $_.")
}
ForEach can also be run with ranges.
($i in 1..3) | ForEach {
Write-Output("Number: $i")
}
Do Until
– Run code until a condition is true.
$number = Get-Random -Minimum 1 -Maximum 10
Do {
$guess = Read-Host -Prompt "What's your guess?"
if ($guess -lt $number) {
Write-Output 'Too low!'
}
elseif ($guess -gt $number) {
Write-Output 'Too high!'
}
}
Until ($guess -eq $number)
Write-Output("Correct!")
Do While
– Run code until a condition is false.
$number = Get-Random -Minimum 1 -Maximum 10
Do {
$guess = Read-Host -Prompt "What's your guess?"
if ($guess -lt $number) {
Write-Output 'Too low!'
}
elseif ($guess -gt $number) {
Write-Output 'Too high!'
}
}
While ($guess -ne $number)
Write-Output("Correct!")
For
– Run code a given number of times.
This is similar to ForEach
and While
. When using For
you must specify a condition, as well as variable initialization, and iteration instructions.
The below code will initialize $i
as 1, and continue to run as long as $i
is less than or equal to 5, and increment $i
by one each completed run.
# (initialization; condition; iteration)
for ($i = 1; $i -le 5; $i++) {
Write-Output("Number: $i")
}
Control Flow Statements
Control Flow statements alter the way a flow works.
Break
– Exits the loop or switch, continuing to the next block.
ForEach ($i in 1..10) {
if ($i -eq 5) {
Write-Output("Reached the break statement.")
break
}
Write-Output("Number: $i")
}
Write-Output("Loop ended.")
Return
– Exits the function and returns a value. This is generally used with functions, which we’ll cover next, so it’s okay not to understand. This can be used to move variables between scopes.
function Divide-Numbers($a, $b) {
if ($b -eq 0) {
return "Error: Division by zero is not allowed."
}
return $a / $b
}
$result = Divide-Numbers 5 3
Write-Output("Product: $result")
Continue – Skip to the next iteration of a loop.
ForEach ($i in 1..5) {
if ($i -eq 3) {
Write-Output("Skipping $i.")
continue
}
Write-Output("Number: $i")
}
That is the gist of flow control. You can do more complex things by nesting and adding variables. If you want a fun exercise to do, plot out a Choose-Your-Own-Adventure game. The way I’d do that is plotting it out with a spreadsheet or bullet list.
[0] You wake up in a dark room. On one side a shadow waves against the wall, on the other there's a glimpse of light.
- Go toward light [1]
- Go toward shadow [2]
[2] You go toward the light and see goblins smoking meat on an immaculately clean smart pellet grill!
Take the food and run [1]
Swear Allegiance to Warchief Regeat [2]
Let me know if you make a CYOA you want to share!