If you haven't already done so, check out my post on why PowerShell makes a great first programming language. This is a follow up post to that one.

The Syllabus
- Visual Studio Code (VS Code)
- Navigating the File System
- Variables
- Data Types
- Arrays
- Operators
- Functions
- Control Flow
- Loops
Visual Studio Code
Installing Visual Studio Code
Follow this guide and get Visual Studio Code installed on your system.

Install the PowerShell Extension
Installing this extension will allow VS Code to run and debug your code.
Click the Extensions marketplace icon

Install the official PowerShell extension

Navigating the File System
You should be comfortable navigating your way around the file system in the terminal in order to be a confident programmer. At a minimum, the ability to move around the file system and create, copy, move, and delete files and directories (folders) is an absolute requirement.
You are probably used to seeing a view such as this:

I have open in my Windows Explorer GUI the C:\Users\Test\Desktop\Test Folder
directory. Inside of this directory, there are:
- Directories
- folder1
- folder2
- folder3
- Files
- file1.txt
- file2.txt
- file3.txt
In a typical GUI file explorer, you would double-click to open a file folder. In a terminal, you are still doing the same things – opening folders, opening files, adding and removing things – they just look different.
For these exercises, I am going to use PowerShell inside of the Windows Terminal app.
Check Your Current Location
In the GUI, you can just look up at the top bar and see your current folder in the file system.

In PowerShell, use the Get-Location
or pwd
commands. pwd
stands for Print Working Directory – or print the directory you are currently working in.
Get-Location
Path
----
C:\Users\Test\Desktop\Test Folder
pwd
Path
----
C:\Users\Test\Desktop\Test Folder
List the Contents of the Current Directory
Use the Get-ChildItem
or ls
commands.
Get-ChildItem
Directory: C:\Users\Test\Desktop\Test Folder
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 1/13/2022 6:11 PM folder1
d----- 1/13/2022 6:11 PM folder2
d----- 1/13/2022 6:11 PM folder3
-a---- 1/13/2022 6:18 PM 0 file1.txt
-a---- 1/13/2022 6:18 PM 0 file2.txt
-a---- 1/13/2022 6:18 PM 0 file3.txt
ls
Directory: C:\Users\Test\Desktop\Test Folder
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 1/13/2022 6:11 PM folder1
d----- 1/13/2022 6:11 PM folder2
d----- 1/13/2022 6:11 PM folder3
-a---- 1/13/2022 6:18 PM 0 file1.txt
-a---- 1/13/2022 6:18 PM 0 file2.txt
-a---- 1/13/2022 6:18 PM 0 file3.txt
Create a Directory
Use the New-Item
or mkdir
commands
New-Item -ItemType Directory -Name 'folder4'
Directory: C:\Users\Test\Desktop\Test Folder
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 1/13/2022 6:30 PM folder4
mkdir folder5
Directory: C:\Users\Test\Desktop\Test Folder
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 1/13/2022 6:31 PM folder5
Rename a Directory
Use the Rename-Item
, Move-Item
, or mv
commands. Seeing the word move when talking about renaming something can be confusing.
# Whenever a name contains a space
# You must wrap it in single or double quotes
Rename-Item folder1 'folder 1'
Move-Item 'folder 1' folder1
mv folder1 folder-1
Delete a Directory
Remove-Item folder4
# Use the -Recurse -Force options
# To delete a folder that is not empty
Remove-Item folder5 -Recurse -Force
Create a File
New-Item -ItemType File -Name 'file4.txt'
Directory: C:\Users\Test\Desktop\Test Folder
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 1/13/2022 6:34 PM 0 file4.txt
Rename a File
Rename-Item file1 .txt 'file 1.txt'
Move-Item 'file 1.txt' file-1.txt
mv file-1.txt file1.txt
Delete a File
Remove-Item 'file4.txt'
Moving in and out of Directories
These are called relative paths:
.
is another way to say the current folder..
is another way to say the parent folder – or the folder above this one
They are not absolute paths, because they don't reference the entire base of the current directory. There's no explicit reference to the parent(s).
Let's take a look at the contents in the current directory again:
ls
Directory: C:\Users\Test\Desktop\Test Folder
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 1/13/2022 6:11 PM folder-1
d----- 1/13/2022 6:11 PM folder2
d----- 1/13/2022 6:11 PM folder3
-a---- 1/13/2022 6:18 PM 0 file1.txt
-a---- 1/13/2022 6:18 PM 0 file2.txt
-a---- 1/13/2022 6:18 PM 0 file3.txt
-a---- 1/13/2022 6:34 PM 0 file4.txt
We can identify a directory easily, as they start with d-----
. I am going to change into the directory folder2
# The .\ syntax is saying
# the current folder and then
# the file or folder within
# this location
cd .\folder2
pwd
Path
----
C:\Users\Test\Desktop\Test Folder\folder2
Now, I am in the folder2
directory and the parent directory is Test Folder
. I am going to go up a level and back into the Test Folder
directory.
cd ..
pwd
Path
----
C:\Users\Test\Desktop\Test Folder
I am now back in the Test Folder
directory.
Finally, I can move to a completely different directory by providing its absolute path.
Set-Location 'C:\Windows\System32'
pwd
Path
----
C:\windows\System32
Refer back to this article for a refresher on some other basic PowerShell commands if needed.

Variables
Create the Script File

Go to File > Save
and save your file as variables.ps1
. I created a new folder to store my script files. Fill out these fields as shown below and click Save
.


What is a Variable?
In programming, a variable is a placeholder where we can put some data that can be referenced repeatedly throughout the lifetime of the script or program.
The placeholder's name never changes, although the contents inside of the placeholder may change and that is why it is called a variable.
Write Some Code
Quick Tip: You can put as many comments as you like in your code. Comments are there for you and other people who read your code. The PowerShell interpreter ignores comments and they do not affect the functionality of your code.
# This is a single-line comment
<#
This is
A multi-line comment
This will
Comment out all these lines
#>
# Creates a variable called "name" and stores the value "John Doe"
$name = 'John Doe'
Write-Host "Hello, $name"
# The variable already exists, change the value stored inside to "Jane Doe"
$name = 'Jane Doe'
Write-Host "Hello, $name"
Press the Run
button and observe the output in the integrated PowerShell console window.


Data Types
Create the Script File

Go to File > Save
and save your file as data-types.ps1
.
Common Data Types
Some primitive data types that you should know for programming are:
- Integer
- Floating-point (number with a decimal point)
- Character
- String
- Boolean
Write Some Code
$integer = 10
$float = 10.1
$boolean = $false
# A string may be wrapped in
# Single quotes ' '
# Or, double quotes " "
$string1 = 'hello world!'
$string2 = "100"
# Must specify [char] here
# Because PowerShell will try to cast it as string
[char]$char1 = 'y'
[char]$char2 = '1'
$integer.GetType()
$float.GetType()
$boolean.GetType()
$string1.GetType()
$string2.GetType()
$char1.GetType()
$char2.GetType()
Review the Output

10
:Int32
is a 32-bit integer10.1
:Double
is a kind of floating point integer$false
:Boolean
is aTrue
orFalse
value; on or off'hello world!'
:String
- When you hear the word string, just imagine a piece of string and you are adding each letter to the string one at a time.
- I say this because a string is actually just a connection of individual characters *
"100"
:String
y
:Char
a single character1
:Char
a single character
* More Info About Strings
I told you to imagine a piece of string and you are putting the letters of the word on the piece of string one at a time. I said that a String
is just a connection of individual characters. Let me demonstrate.
Let's take the word superman
for example. The word superman
is 8 characters long. So, you've placed 8 letters onto your piece of string.

With computers, counting starts at 0. So, 0
is getting the first character from the string superman
, which is the letter s
.
More Info About Data Types
PowerShell – like Python – is a flexible language. It is not inherently a strictly type-enforced language. This is because the PowerShell interpreter makes a best effort to classify the data you are entering.
The interpreter is what runs your code when you press the Run
button. This is known as a REPL. Read Evaluate Print Loop – the interpreter reads your code, processes it, prints output to the screen, and loops back to restart the process.
With PowerShell, you can manually cast an input as a certain type. Here are some examples:
# PowerShell will interpret this an integer
100
# PowerShell will interpret this as a string
'a'
# PowerShell will interpret this as a double
3.14
# Cast the integer as a string
[String]100
# Cast the double as a string
[String]3.14
# Cast 'a' as a char, not a string
[Char]'a'
# Cast 'f' as a byte
[Byte]'f'
# True, on
[Bool]1
# False, off
[Bool]0
Arrays
Create the Script File

Go to File > Save
and save your file as arrays.ps1
What is an Array?
Think of an array as a shopping cart. You can put all kinds of things in a shopping cart. The shopping cart is holding a collection of items. Some arrays can hold a collection of items that are totally unrelated.
You can make arrays that more strict. Again, imagine a shopping cart, but this shopping cart is only allowed to hold a collection of fruit. Some arrays have this kind of behavior.
Write Some Code
$integer = 10
$float = 10.1
$boolean = $false
$string = 'hello world!'
$char = 'y'
# Put some items in the array
# This array is going to hold
# An integer, a flow, a char, a string, and a boolean type
$array = @($integer, $float, $boolean, $string, $char)
# Return is a keyword that will return
# A value back to the standard output
return $array

Operators
Create the Script File

Go to File > Save
and save your file as operators.ps1
PowerShell Operators
Most operators are standard across programming languages, but PowerShell has a few operators that don't align with what you will see in other languages
- Arithmetic Operators
+
addition-
subtraction*
multiplication/
division%
modulo (divide and return remainder)
- Relational Operators
-eq
(usually==
or===
in other languages)-ne
(usually!=
in other languages)-gt
(usually>
in other languages)-lt
(usually<
in other languages)-ge
(usually>=
in other languages)-le
(usually<=
in other languages)
This really only scratches the surface of available PowerShell operators. Please take a moment to review the official documentation to learn more.

Write Some Code
1 -eq 1
2 -eq 1
'a' -eq 'a'
'a' -eq 'b'
'a' -ne 'b'
$true -eq $true
$false -eq $true
2 -ne 1
5 -gt 2
4 -lt 3
2 -lt 5
10 -ge 10
10 -ge 9
9 -ge 10
10 -le 10
10 -le 11
9 -le 10
20 * 2 -gt 10 * 2
2 * 2 -eq 4

Functions
Create the Script File

Go to File > Save
and save your file as functions.ps1
The Use of Functions
DRY code is good code. Don't Repeat Yourself. In other words, if you find yourself repeating code multiple times, then it's time for a function.
A function is a piece of code that is designed to do one task really well. Functions should be lean and precise.
Example of Code that is Not DRY
Here is some code where we want to check if two numbers added together are less than 5. This code is not DRY, because I've repeated the same code block twice. This is a very contrived example, but it is true nonetheless.

Example of DRY Code

I used some color-coded lines to demonstrate how the parameters are linked within the function and the user input. $firstNumber
and $secondNumbers
are variables that will hold user input when the function is called. These variables are referenced internally inside the function.

$firstNumber
and $secondNumber
are called parameters. Then, when the function is called – as pictured above – and input is provided, that is called passing an argument to a parameter.
Write Some Code
function Confirm-UserIsValid ($firstName, $lastName) {
$allowedUser = 'John.Doe'
$username = "$firstName.$lastName"
return $username -eq $allowedUser
}
# Passing the arguments: Jane and Doe
Confirm-UserIsValid -firstName 'Jane' -lastName 'Doe'
# Passing the arguments: James and Doe
Confirm-UserIsValid -firstName 'James' -lastName 'Doe'
# Passing the arguments: John and Doe
Confirm-UserIsValid -firstName 'John' -lastName 'Doe'

Follow Up
Notice how I create a new variable using the existing variables: $username = "$firstName.$lastName"
. What I've done is created a String
by wrapping the variables in double quotes.
What would happen if I had written it like this: '$firstName.$lastName'
? Let's use some code to find out.


Why did that happen? When you wrap a string in single quotes, you create a string literal
. That means anything between the single quotes should be interpreted exactly as it appears, so don't interpret the variables to their values.
Control Flow
Create the Script File

Go to File > Save
and save your file as control-flow.ps1
Using Logic to Control a Script
The whole point of control flow is to direct the outcome of a script. When you use control flow you are saying, "If something is true, do this." This where the concept of Boolean
logic is factored into programming.
Remember that Boolean
is true or false. If something is true, do this; otherwise, do this. Or, if something is false, do this; otherwise, do this.
Code Example 1
$age = 20
if ($age -le 10) {
# Run this code if
# Age is less than or equal to 10
Write-Host "Your bedtime is at 8:00 PM"
}
elseif ($age -gt 10 -and $age -le 18) {
# Otherwise
# Run this code if
# Age is between 11 and 18
Write-Host "Your bedtime is at 10:00 PM"
}
elseif ($age -gt 18 -and $age -le 30) {
# Otherwise
# Run this code if
# Age is between 19 and 30
Write-Host "Your bedtime is at midnight"
}
else {
# Otherwise
# Run this code if
# Age is any other number
Write-Host "Your bedtime is at 11:00 PM"
}

These conditions are all chained together.
if (try this first)
elseif (then, try this)
esleif (then, try this)
else (run this if all else fails)
Code Example 2
$string = 'code'
if ($string -eq 'code') {
Write-Host "Code! Nice!"
}
if ($string.Length -eq '4') {
Write-Host "Your string is 4 characters long."
}
if ($string -eq 'yoda') {
Write-Host "Do or do not, there is no try."
}

These conditions are not chained together. Each if
clause will run independently regardless of the result of the last if
clause.
if (try this)
if (also, try this)
if (also, try this)
Code Example 3
$color = 'orange'
switch ($color) {
'red' {
Write-Host "Red."
break
}
'orange' {
Write-Host "Orange."
break
}
'yellow' {
Write-Host "Yellow."
break
}
'green' {
Write-Host "Green."
break
}
'blue' {
Write-Host "Blue."
break
}
'indigo' {
Write-Host "Indigo."
break
}
'violet' {
Write-Host "Violet."
break
}
default {
Write-Host "Enter a valid color."
break
}
}

The break
keyword tells the program to stop testing conditions once a match has been found. The default
keyword tells the program to run this code if nothing matches.
Loops
Create the Script File

Go to File > Save
and save your file as loops.ps1
What are Loops?
Loops are useful for:
- Running a block of code a specific number of times
- Processing arrays
Beware of Infinite Loops
Infinite loops are loops where you have created a condition that will unceasingly be True
. Infinite loops will break a program and can crash a computer.
Example of an Infinite Loop
while ($true) {
Write-Host "Infinite loop!"
}

Why does this cause an infinite loop? Because, $true
never stops being $true
. The output just keeps going and going. If you ever get into an infinite loop, you can stop it by pressing CTRL + C
, which should discontinue script execution.
Types of Loops
for
foreach
while
do while
Code Example 1
$repetitions = 10
for ($counter = 0 ; $counter -lt $repetitions ; $counter++) {
Write-Host "Loop $counter"
}

I want my code to loop 10 times. Remember that in computing, counting starts from 0. Let's take a look at what this loop does.
$repetitions = 10
: The number times I want the code to repeat$counter = 0
: I am going to start my loop counter at zero$counter -lt $repetitions
: Run the loop as long as this is true$counter++
:$counter
started at 0,++
means add1
to that value, so now$counter
is equal to1
. It will continue to increment by one at each loop.
Code Example 2
# Make an array of animals
# It's an array of strings
# Each string is an animal name
$animals = @('dog', 'cat', 'parrot', 'horse')
foreach ($animal in $animals) {
Write-Host "Say hello to the $animal"
}

Let's take a look further at how this loop works.

Pretend you have a bucket of $animals
. You are going to take one animal out at a time and place it in $animal
. You keep repeating this until you've emptied the $animals
bucket.
Code Example 3
$counter = 0
while ($counter -ne 10) {
Write-Host $counter
$counter++
}

In the case of the while
loop, the program keeps processing the code while the condition is true.
Code Example 4
$counter = 0
do {
Write-Host $counter
$counter++
}
while ($counter -ne 10)
Similar to the while
loop, the do while
loop is simply saying do this while this condition is true.
Final Project
function Get-RandomNumberFromRange ($startingNumber, $endingNumber) {
# With integers you can create an array of integers easily
# For example 1..10
# Will create an array from 1 to 10
# In this case we'll create an array of integers
# Between the start and end numbers
$numberArray = $startingNumer..$endingNumber
# This is called passing input down the pipeline
# We pass the $numbers variable to the
# Get-Random cmdlet
# The Get-Random cmdlet will pick a random number
# From the array of numbers
$randomNumber = $numberArray | Get-Random
return $randomNumber
}
# Integers
# If you wrapped them in quotes
# They'd be strings
# And, it would break the program
$start = 1
$end = 20
$randomNumber = Get-RandomNumberFromRange -startingNumber $start -endingNumber $end
Write-Host "Let's play a guessing game" -ForegroundColor Green
Write-Host "I will choose a random number between $start and $end" -ForegroundColor Magenta
Write-Host "See if you can guess what it is" -ForegroundColor Cyan
# The Read-Host cmdlet is how you get input from a user
$guess = Read-Host -Prompt "Enter a number between $start and $end"
while ($guess -lt $start -and $guess -gt $end) {
$guess = Read-Host "Your choice was not between $start and $end, try again"
}
if ($guess -eq $randomNumber) {
Write-Host "Great guess! The random number is: $randomNumber and you chose: $guess!" -ForegroundColor Green
}
else {
Write-Host "Better luck next time. The number is: $randomNumber and you chose: $guess." -ForegroundColor Yellow
}

Intro to Object-Oriented Programming
When you're comfortable with the concepts here, head on to the next post for a brief introduction to object-oriented programming with PowerShell.
