Bash & PowerShell Scripting for Absolute Beginners

๐Ÿš€ Bash & PowerShell Scripting
for Absolute Beginners

Learn to automate tasks and save hours of work with simple scripts. No programming experience needed!

โฑ๏ธ ~2.5 hours of learning ahead
Start scrolling to track your progress!

1. What is Scripting and Why Should You Care?

Welcome! Let’s Start Simple

Congratulations on taking the first step into the world of scripting! You’re about to learn something that will save you countless hours and make you look like a tech wizard to your friends and colleagues.

But first, let’s answer the big question: What exactly is scripting?

๐Ÿณ The Recipe Analogy

Think of a script like a recipe. When you make pancakes, you follow steps:

  1. Mix flour, eggs, and milk
  2. Heat the pan
  3. Pour batter
  4. Flip when bubbles appear
  5. Serve with syrup

A script is the same thingโ€”it’s a list of instructions for your computer to follow automatically. Instead of you clicking buttons and typing things manually, the computer reads your “recipe” and does all the steps for you!

Why Scripting is Your New Superpower

Imagine if you had to:

  • Rename 500 files (would take hours manually!)
  • Back up important folders every day
  • Create user accounts for 50 new employees
  • Check if your servers are running every morning

With scripting, you write the instructions once, and the computer does the work thousands of times without complaining, making mistakes, or needing coffee breaks!

Manual Work vs. Scripted Work

Manual: 4 hours
โ†’
Script: 10 seconds

Write once, run forever!

Meet Your Two New Friends: Bash and PowerShell

Think of Bash and PowerShell as two different languages that computers understand. They both help you automate tasks, but they’re used in different situations:

Bash PowerShell
๐Ÿง Used on Linux/Mac computers ๐ŸชŸ Used on Windows computers (but also works on Linux/Mac!)
Simple, concise commands More descriptive, English-like commands
Example: ls (list files) Example: Get-ChildItem (get files)
Popular in web servers, DevOps Popular in IT administration, system management

๐Ÿ’ก Good News!

The concepts you learn apply to both languages! It’s like learning to driveโ€”once you know the basics, you can drive different cars. We’ll show you how to do the same task in both Bash and PowerShell throughout this guide.

โš ๏ธ Common Confusion: Script vs. Program

Scripts are usually simpler, text-based instructions that run line-by-line. You can open and read them like a text file.

Programs (like Microsoft Word or Chrome) are compiled, complex applications that have been converted into computer code.

Think of it this way: A script is like a handwritten recipe; a program is like a cake-making machine in a factory.

๐ŸŽฏ Try It Now: Open Your Terminal/Shell

On Windows:

  1. Press Windows Key + R
  2. Type powershell and press Enter
  3. A blue window appearsโ€”that’s PowerShell!

On Mac:

  1. Press Command + Space
  2. Type terminal and press Enter
  3. A white or black window appearsโ€”that’s your Terminal!

On Linux:

  1. Press Ctrl + Alt + T
  2. Your terminal opens automatically!

โœ… Success! If you see a window with text and a blinking cursor, you did it! Don’t worry if it looks intimidatingโ€”we’ll make it friendly.

โœ… Checkpoint #1 (10 minutes)

What you’ve learned so far:

  • Scripts are lists of instructions for computers
  • They save you from repetitive manual work
  • Bash and PowerShell are two popular scripting languages
  • You successfully opened your terminal/shell!

๐ŸŽ‰ Great start! Take a 2-minute break, stretch, then continue to Section 2.

2. Your First Commands: Talking to Your Computer

Understanding the Command Line

That window you opened? It’s called a terminal (Mac/Linux) or shell (Windows). Think of it as a text-based conversation with your computer.

๐Ÿ’ฌ The Text Message Analogy

Using the command line is like texting your computer:

  • You: Type a command (your message)
  • Computer: Reads it and responds
  • You: Send another command based on the response

It’s a back-and-forth conversation, except your computer follows instructions exactly as you type them!

Your First Command: Hello, World!

Let’s make your computer say something. This is the traditional first step for all programmers!

Simple

Bash: Display Text

echo "Hello, World!"

What this does: The computer prints “Hello, World!” to the screen.

Breaking it down:

  • echo = the command to display text
  • “Hello, World!” = the text to display
Simple

PowerShell: Display Text

Write-Host "Hello, World!"

What this does: Same thingโ€”displays “Hello, World!”

Breaking it down:

  • Write-Host = command to write to screen
  • “Hello, World!” = the text to display

๐Ÿ’ก Notice the Pattern?

Every command has this structure:

COMMAND
+
WHAT TO DO WITH

It’s like English: “Verb + Object” โ†’ “Display this text” or “List these files”

Useful Everyday Commands

Let’s learn commands you’ll use all the time. These are like the basic vocabulary words in any language.

Medium

Show Current Location

Bash:

pwd

PowerShell:

Get-Location

What it does: Shows which folder you’re currently in (like checking “You Are Here” on a mall map)

Output example: /home/username or C:\Users\username

Medium

List Files in Current Folder

Bash:

ls

PowerShell:

Get-ChildItem

What it does: Shows all files and folders where you are (like opening a drawer and seeing what’s inside)

You’ll see: Names of files and folders in that location

Practical

Change to a Different Folder

Bash:

cd Documents

PowerShell:

Set-Location Documents

What it does: Moves you into the Documents folder (like walking into a different room in your house)

Pro tip: Type cd .. to go back to the parent folder (like walking out of a room)

How Folders Work in the Command Line

Think of your computer as a house:

๐Ÿ  Home (your starting point)
โ”œโ”€โ”€ ๐Ÿ“ Documents
โ”‚   โ”œโ”€โ”€ ๐Ÿ“„ report.doc
โ”‚   โ””โ”€โ”€ ๐Ÿ“„ notes.txt
โ”œโ”€โ”€ ๐Ÿ“ Pictures
โ”‚   โ””โ”€โ”€ ๐Ÿ–ผ๏ธ vacation.jpg
โ””โ”€โ”€ ๐Ÿ“ Downloads
    โ””โ”€โ”€ ๐Ÿ“ฆ software.zip

When you cd Documents, you’re entering the Documents “room”

โš ๏ธ Common Confusion: Case Sensitivity

Bash: Cares about uppercase/lowercase!

  • โœ… cd Documents works
  • โŒ cd documents might not work (if folder is “Documents”)

PowerShell: Doesn’t care about case

  • โœ… Set-Location Documents works
  • โœ… set-location documents also works!

๐ŸŽฏ Try It Now: Navigate Your Computer

Challenge: Let’s explore your computer using commands!

  1. Check where you are: Type pwd (Bash) or Get-Location (PowerShell)
  2. See what’s here: Type ls (Bash) or Get-ChildItem (PowerShell)
  3. Go to Documents: Type cd Documents (or Set-Location Documents)
  4. List files there: Use the list command again
  5. Go back home: Type cd (Bash) or Set-Location ~ (PowerShell)

โœ… Success! If you moved between folders and saw different files, you’re navigating like a pro!

โœ… Checkpoint #2 (25 minutes total)

What you’ve learned:

  • The command line is like a text conversation with your computer
  • Commands have a structure: COMMAND + WHAT
  • Basic commands: display text, show location, list files, change folders
  • Bash is case-sensitive; PowerShell isn’t
  • You navigated your file system using commands!

๐ŸŽ‰ You’re doing great! Take a break, grab some water, and let’s move on to variables.

3. Variables: Giving Your Computer a Memory

What is a Variable?

Imagine you’re following a recipe, and it says “add the mixture.” But what’s “the mixture”? It’s whatever you created in step 3โ€”maybe eggs and flour.

A variable is like a labeled container that holds information your computer needs to remember.

๐Ÿ“ฆ The Box Analogy

Think of variables as labeled boxes:

๐Ÿ“ฆ username
contains: “Sarah”
๐Ÿ“ฆ age
contains: 25
๐Ÿ“ฆ city
contains: “Portland”

You can:

  • Put things in the box (assign a value)
  • Look in the box (use the value)
  • Change what’s in the box (update the value)
  • Use what’s in multiple boxes together (combine values)

Creating Your First Variable

Simple

Bash: Create and Use a Variable

name="Alice"
echo "Hello, $name!"

Output: Hello, Alice!

Breaking it down:

  • name=”Alice” โ†’ Put “Alice” in a box labeled “name”
  • $name โ†’ Look in the box and use what’s inside
  • โš ๏ธ Notice: No spaces around the = sign!
Simple

PowerShell: Create and Use a Variable

$name = "Alice"
Write-Host "Hello, $name!"

Output: Hello, Alice!

Breaking it down:

  • $name = “Alice” โ†’ Create a variable
  • Notice the $ before the nameโ€”that’s how PowerShell knows it’s a variable
  • Spaces around = are fine in PowerShell!

๐Ÿ’ก Key Difference

Bash: $ is used when you read the variable ($name)

PowerShell: $ is used when you create and read the variable ($name)

Types of Information You Can Store

Medium

Storing Numbers and Doing Math

Bash:

age=25
next_year=$((age + 1))
echo "Next year I'll be $next_year"

PowerShell:

$age = 25
$nextYear = $age + 1
Write-Host "Next year I'll be $nextYear"

Output: Next year I’ll be 26

What’s happening: We’re doing math! The computer calculates 25 + 1 and stores the result.

Medium

Combining Text (Concatenation)

Bash:

first_name="John"
last_name="Smith"
full_name="$first_name $last_name"
echo "Welcome, $full_name!"

PowerShell:

$firstName = "John"
$lastName = "Smith"
$fullName = "$firstName $lastName"
Write-Host "Welcome, $fullName!"

Output: Welcome, John Smith!

What’s happening: We’re gluing text together like building with LEGO blocks!

Practical

Real-World Example: File Backup

Bash:

today=$(date +%Y-%m-%d)
filename="backup_$today.tar.gz"
echo "Creating: $filename"

PowerShell:

$today = Get-Date -Format "yyyy-MM-dd"
$filename = "backup_$today.zip"
Write-Host "Creating: $filename"

Output: Creating: backup_2025-10-13.zip

Why this is useful: Every day, your backup file has a different name with the date! No more overwriting yesterday’s backup.

How Variables Flow in a Script

Step 1: Create variable
    ๐Ÿ“ฆ name = "Sarah"
    
Step 2: Use it later
    "Hello, Sarah!"  (pulled from the box)
    
Step 3: Change it
    ๐Ÿ“ฆ name = "Mike"  (replaced what's in the box)
    
Step 4: Use it again
    "Hello, Mike!"  (now uses the new value)

โš ๏ธ Common Confusion: Quotes or No Quotes?

Text needs quotes:

  • โœ… name=”Alice”
  • โŒ name=Alice (might work but can cause problems)

Numbers don’t need quotes:

  • โœ… age=25
  • โš ๏ธ age=”25″ (works but treated as text, not a number)

Rule of thumb: When in doubt, use quotes! They rarely hurt and often help.

Naming Your Variables

Good variable names make your scripts easy to understand. It’s like labeling boxes clearly!

โŒ Bad Names โœ… Good Names Why?
x username Descriptive and clear
temp current_temperature Says exactly what it holds
data1 user_email Specific purpose is obvious

๐Ÿ’ก Naming Conventions

Bash style: my_variable_name (lowercase with underscores)

PowerShell style: $MyVariableName (PascalCase or camelCase)

Both work, but consistency makes your code easier to read!

๐ŸŽฏ Try It Now: Create a Personal Greeting Script

Your mission: Create a script that greets you personally!

For Bash users:

  1. Type: name=”YourName” (use your actual name!)
  2. Type: age=25 (use your actual age)
  3. Type: echo “Hi, I’m $name and I’m $age years old”
  4. Press Enter after each line

For PowerShell users:

  1. Type: $name = “YourName”
  2. Type: $age = 25
  3. Type: Write-Host “Hi, I’m $name and I’m $age years old”

Bonus Challenge: Add a third variable for your city and include it in your greeting!

โœ… Success! If you see your personalized greeting, you’ve mastered variables!

โœ… Checkpoint #3 (45 minutes total)

What you’ve learned:

  • Variables are labeled containers that store information
  • You can store text, numbers, and combine them
  • Bash uses $ when reading; PowerShell uses $ always
  • Good names make your scripts readable
  • You created your own personalized greeting!

๐ŸŽ‰ Halfway there! You’re building real scripting skills. Take a 5-minute break!

4. Input & Output: Having a Conversation

Making Your Scripts Interactive

So far, we’ve been hardcoding values (writing them directly in the script). But what if you want your script to ask questions and respond based on the answers?

๐ŸŽค The Survey Analogy

Imagine you’re conducting a survey:

  1. You ask: “What’s your name?”
  2. Person responds: “Sarah”
  3. You record: Write “Sarah” on your clipboard
  4. You use it: “Thanks, Sarah! Next question…”

Scripts work the same wayโ€”they can ask questions, wait for answers, and then use those answers!

Getting Input from Users

Simple

Bash: Ask for Input

echo "What is your name?"
read name
echo "Hello, $name!"

What happens:

  1. Script asks the question
  2. Cursor blinks, waiting for you to type
  3. You type your name and press Enter
  4. Script greets you!

Key command: read gets input and stores it in a variable

Simple

PowerShell: Ask for Input

$name = Read-Host "What is your name?"
Write-Host "Hello, $name!"

What happens:

  1. Script displays the question
  2. Waits for your input
  3. Stores your answer in $name
  4. Uses it in the greeting

Key command: Read-Host asks and stores in one step!

Different Types of Output

We’ve been using echo and Write-Host, but there are other ways to show information:

Medium

Colorful Output (PowerShell)

Write-Host "Success!" -ForegroundColor Green
Write-Host "Warning!" -ForegroundColor Yellow
Write-Host "Error!" -ForegroundColor Red

Why it’s useful: Colors help users quickly understand if something worked or failed!

Colors available: Black, Blue, Cyan, Gray, Green, Magenta, Red, White, Yellow

Medium

Writing to a File Instead of Screen

Bash:

echo "Log entry: Process started" > log.txt
echo "Log entry: Task completed" >> log.txt

PowerShell:

"Log entry: Process started" | Out-File log.txt
"Log entry: Task completed" | Out-File log.txt -Append

What’s happening:

  • > or Out-File creates/overwrites the file
  • >> or -Append adds to the end without deleting what’s there
Practical

Real-World: User Registration Script

Bash:

echo "=== User Registration ==="
read -p "Enter your username: " username
read -p "Enter your email: " email
read -sp "Enter your password: " password
echo ""
echo "Registration complete for $username"
echo "$username registered on $(date)" >> users.log

PowerShell:

Write-Host "=== User Registration ===" -ForegroundColor Cyan
$username = Read-Host "Enter your username"
$email = Read-Host "Enter your email"
$password = Read-Host "Enter your password" -AsSecureString
Write-Host "Registration complete for $username" -ForegroundColor Green
"$username registered on $(Get-Date)" | Out-File users.log -Append

Cool features:

  • read -sp (Bash) hides password as you type
  • -AsSecureString (PowerShell) secures the password
  • Logs each registration with a timestamp

Input โ†’ Process โ†’ Output Flow

1. INPUT (User types)
   ๐Ÿ‘ค User enters: "Tokyo"
   โ†“
2. PROCESS (Script works)
   ๐Ÿ’พ Store in variable: city = "Tokyo"
   ๐Ÿงฎ Maybe do calculations or checks
   โ†“
3. OUTPUT (Show results)
   ๐Ÿ“บ Display: "Welcome to Tokyo!"
   ๐Ÿ“„ Save to file: "User visited Tokyo"

๐Ÿ’ก Making Better Prompts

Instead of: “Enter value:”

Try: “Enter your age (18-100):”

Good prompts tell users:

  • What to enter
  • What format is expected
  • Any limits or requirements

It’s like giving clear directions instead of just saying “Go that way!”

โš ๏ธ Common Confusion: When to Use Quotes in Output

Text needs quotes in the command:

  • โœ… echo “Hello”
  • โŒ echo Hello (works but can be tricky with spaces)

Variables inside quotes work automatically:

  • โœ… echo “Hi, $name” โ†’ “Hi, Sarah”
  • โŒ echo Hi, $name โ†’ might not work as expected

Rule of thumb: Always wrap your text and variables in quotes for reliable output!

๐ŸŽฏ Try It Now: Build a Simple Calculator

Challenge: Create a script that asks for two numbers and adds them!

For Bash:

echo "Simple Calculator"
read -p "Enter first number: " num1
read -p "Enter second number: " num2
result=$((num1 + num2))
echo "Result: $num1 + $num2 = $result"

For PowerShell:

Write-Host "Simple Calculator" -ForegroundColor Cyan
$num1 = Read-Host "Enter first number"
$num2 = Read-Host "Enter second number"
$result = [int]$num1 + [int]$num2
Write-Host "Result: $num1 + $num2 = $result" -ForegroundColor Green

Try it: Run this code and enter 10 and 5. You should see: Result: 10 + 5 = 15

Bonus Challenges:

  1. Change the + to – for subtraction
  2. Try multiplication (use * in Bash, same in PowerShell)
  3. Add a welcome message at the start
โœ… Checkpoint #4 (65 minutes total)

What you’ve learned:

  • Scripts can ask questions and get answers from users
  • Input: read (Bash), Read-Host (PowerShell)
  • Output can go to screen or files
  • Colors make output more user-friendly
  • You built an interactive calculator!

๐ŸŽ‰ You’re over halfway! Your scripts are getting interactive. Quick stretch break!

5. Making Decisions: If This, Then That

Scripts That Make Choices

Real power comes when your script can make decisions based on situations. This is called “conditional logic” or “if-statements.”

๐ŸŒฆ๏ธ The Weather Analogy

Every morning you make a decision:

  • IF it’s raining โ†’ bring an umbrella
  • ELSE IF it’s sunny โ†’ wear sunglasses
  • ELSE (neither) โ†’ just go outside normally

Your script can make similar decisions! It checks conditions and does different things based on what it finds.

Your First If-Statement

Simple

Bash: Basic If-Statement

age=18

if [ $age -ge 18 ]; then
    echo "You can vote!"
else
    echo "Too young to vote"
fi

Breaking it down:

  • if [ condition ] = check if something is true
  • then = do this if true
  • else = otherwise, do this
  • fi = end of if-statement (“if” backwards!)

Comparison operators:

  • -eq = equal to
  • -ne = not equal
  • -gt = greater than
  • -ge = greater than or equal
  • -lt = less than
  • -le = less than or equal
Simple

PowerShell: Basic If-Statement

$age = 18

if ($age -ge 18) {
    Write-Host "You can vote!" -ForegroundColor Green
}
else {
    Write-Host "Too young to vote" -ForegroundColor Yellow
}

Breaking it down:

  • if (condition) = check if true
  • { } = curly braces contain the code to run
  • else { } = what to do otherwise

Comparison operators:

  • -eq = equal to
  • -ne = not equal
  • -gt = greater than
  • -ge = greater than or equal
  • -lt = less than
  • -le = less than or equal

๐Ÿ’ก Notice the Pattern?

Both languages use the same operators for numbers! -ge, -lt, etc.

The main difference is syntax (how you write it), not the logic!

Multiple Conditions: If, Else If, Else

Medium

Grade Calculator

Bash:

score=85

if [ $score -ge 90 ]; then
    echo "Grade: A - Excellent!"
elif [ $score -ge 80 ]; then
    echo "Grade: B - Good job!"
elif [ $score -ge 70 ]; then
    echo "Grade: C - Average"
elif [ $score -ge 60 ]; then
    echo "Grade: D - Needs improvement"
else
    echo "Grade: F - Failed"
fi

PowerShell:

$score = 85

if ($score -ge 90) {
    Write-Host "Grade: A - Excellent!" -ForegroundColor Green
}
elseif ($score -ge 80) {
    Write-Host "Grade: B - Good job!" -ForegroundColor Cyan
}
elseif ($score -ge 70) {
    Write-Host "Grade: C - Average" -ForegroundColor Yellow
}
elseif ($score -ge 60) {
    Write-Host "Grade: D - Needs improvement" -ForegroundColor DarkYellow
}
else {
    Write-Host "Grade: F - Failed" -ForegroundColor Red
}

How it works: Script checks each condition in order until one is true, then stops.

Medium

Checking If Files Exist

Bash:

filename="data.txt"

if [ -f "$filename" ]; then
    echo "File exists! Reading..."
    cat "$filename"
else
    echo "File not found! Creating..."
    echo "Sample data" > "$filename"
fi

PowerShell:

$filename = "data.txt"

if (Test-Path $filename) {
    Write-Host "File exists! Reading..."
    Get-Content $filename
}
else {
    Write-Host "File not found! Creating..."
    "Sample data" | Out-File $filename
}

Why this is powerful: Script adapts to what it finds! If the file exists, it reads it. If not, it creates it.

File tests (Bash):

  • -f = file exists
  • -d = directory exists
  • -r = file is readable
  • -w = file is writable
Practical

Real-World: Disk Space Monitor

Bash:

usage=$(df -h / | tail -1 | awk '{print $5}' | sed 's/%//')

if [ $usage -gt 90 ]; then
    echo "CRITICAL: Disk $usage% full!"
    echo "Alert sent on $(date)" >> disk_alerts.log
elif [ $usage -gt 75 ]; then
    echo "WARNING: Disk $usage% full"
elif [ $usage -gt 50 ]; then
    echo "OK: Disk $usage% used"
else
    echo "GOOD: Plenty of space ($usage%)"
fi

PowerShell:

$disk = Get-PSDrive C
$usage = [math]::Round(($disk.Used / ($disk.Used + $disk.Free)) * 100)

if ($usage -gt 90) {
    Write-Host "CRITICAL: Disk $usage% full!" -ForegroundColor Red
    "Alert sent on $(Get-Date)" | Out-File disk_alerts.log -Append
}
elseif ($usage -gt 75) {
    Write-Host "WARNING: Disk $usage% full" -ForegroundColor Yellow
}
elseif ($usage -gt 50) {
    Write-Host "OK: Disk $usage% used" -ForegroundColor Cyan
}
else {
    Write-Host "GOOD: Plenty of space ($usage%)" -ForegroundColor Green
}

Real-world use: Run this daily to monitor disk space and get alerts before you run out!

Decision Flow Visualization

Start
  โ†“
Is condition 1 true?
  โ”œโ”€ YES โ†’ Do action 1 โ†’ End
  โ””โ”€ NO
      โ†“
  Is condition 2 true?
      โ”œโ”€ YES โ†’ Do action 2 โ†’ End
      โ””โ”€ NO
          โ†“
      Do default action โ†’ End

โš ๏ธ Common Confusion: = vs -eq

Single = is for assignment (storing):

  • โœ… age=25 โ†’ Put 25 into age

-eq is for comparison (checking):

  • โœ… if [ $age -eq 25 ] โ†’ Check if age equals 25

Why the difference? It prevents accidental overwrites! If you could use = for both, you might accidentally change values when you meant to check them.

Memory trick:

  • = โ†’ “Make it equal” (assignment)
  • -eq โ†’ “Is it equal?” (comparison)

๐ŸŽฏ Try It Now: Build a Password Checker

Challenge: Create a script that checks if a password is strong enough!

For Bash:

echo "Password Strength Checker"
read -sp "Enter password: " password
echo ""

length=${#password}

if [ $length -ge 12 ]; then
    echo "โœ“ Strong password!"
elif [ $length -ge 8 ]; then
    echo "โš  Medium password"
else
    echo "โœ— Weak password! Use at least 8 characters"
fi

For PowerShell:

Write-Host "Password Strength Checker" -ForegroundColor Cyan
$password = Read-Host "Enter password" -AsSecureString
$plainPassword = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
    [Runtime.InteropServices.Marshal]::SecureStringToBSTR($password))
$length = $plainPassword.Length

if ($length -ge 12) {
    Write-Host "โœ“ Strong password!" -ForegroundColor Green
}
elseif ($length -ge 8) {
    Write-Host "โš  Medium password" -ForegroundColor Yellow
}
else {
    Write-Host "โœ— Weak password! Use at least 8 characters" -ForegroundColor Red
}

Try it: Test with different password lengths!

Bonus Challenges:

  1. Add a check for maximum length (e.g., >20 = too long)
  2. Change the threshold values to make it stricter
  3. Add a congratulations message for strong passwords
โœ… Checkpoint #5 (90 minutes total)

What you’ve learned:

  • If-statements let scripts make decisions
  • Structure: if โ†’ check condition โ†’ do something
  • Multiple conditions: if, else if, else
  • Comparison operators: -eq, -gt, -lt, etc.
  • You built a password strength checker!

๐ŸŽ‰ Almost there! You’re learning how to make smart scripts. One more big concept!

6. Loops: Doing Things Repeatedly

The Power of Repetition

This is where scripting really shines! Loops let you do the same thing over and over without copy-pasting code.

๐Ÿƒ The Marathon Analogy

Imagine you need to:

  • Run around a track 10 times
  • Count each lap
  • Shout “Lap X completed!” after each one

You wouldn’t write:

Run lap 1, shout “Lap 1!”
Run lap 2, shout “Lap 2!”
Run lap 3, shout “Lap 3!”…(yikes!)

Instead, you’d say: “For each lap from 1 to 10, run and shout the number”

That’s exactly what a loop doesโ€”one instruction that repeats automatically!

Your First Loop: The For Loop

Simple

Bash: Count to 5

for i in 1 2 3 4 5; do
    echo "Number: $i"
done

Output:

Number: 1
Number: 2
Number: 3
Number: 4
Number: 5

Breaking it down:

  • for i in = for each item
  • 1 2 3 4 5 = the list of items
  • do = start of repeated action
  • done = end of repeated action
Simple

PowerShell: Count to 5

foreach ($i in 1..5) {
    Write-Host "Number: $i"
}

Output: Same as Bash!

Breaking it down:

  • foreach = for each item
  • $i in 1..5 = variable in range 1 to 5
  • { } = curly braces contain repeated code

Cool PowerShell trick: 1..5 automatically creates the range!

Looping Through Files

One of the most common uses: doing something to every file in a folder!

Medium

List All .txt Files

Bash:

for file in *.txt; do
    echo "Found: $file"
    echo "Size: $(wc -l < "$file") lines"
done

PowerShell:

foreach ($file in Get-ChildItem *.txt) {
    Write-Host "Found: $($file.Name)"
    $lines = (Get-Content $file).Count
    Write-Host "Size: $lines lines"
}

What's happening:

  • *.txt = matches all files ending in .txt
  • Loop processes each file one at a time
  • Could rename, copy, or modify each file!
Medium

Rename Multiple Files

Bash:

counter=1
for file in *.jpg; do
    newname="photo_$counter.jpg"
    mv "$file" "$newname"
    echo "Renamed $file to $newname"
    ((counter++))
done

PowerShell:

$counter = 1
foreach ($file in Get-ChildItem *.jpg) {
    $newName = "photo_$counter.jpg"
    Rename-Item $file $newName
    Write-Host "Renamed $($file.Name) to $newName"
    $counter++
}

Result: IMG_1234.jpg โ†’ photo_1.jpg, IMG_5678.jpg โ†’ photo_2.jpg, etc.

Real-world use: Organize hundreds of downloaded photos instantly!

Practical

Backup Script with Logs

Bash:

echo "Starting backup at $(date)"
backup_dir="/backup/$(date +%Y%m%d)"
mkdir -p "$backup_dir"

for folder in Documents Pictures Videos; do
    echo "Backing up $folder..."
    cp -r ~/"$folder" "$backup_dir/"
    if [ $? -eq 0 ]; then
        echo "โœ“ $folder backed up successfully"
    else
        echo "โœ— $folder backup failed!"
    fi
done

echo "Backup completed at $(date)"

PowerShell:

Write-Host "Starting backup at $(Get-Date)"
$backupDir = "C:\Backup\$(Get-Date -Format 'yyyyMMdd')"
New-Item -ItemType Directory -Path $backupDir -Force | Out-Null

foreach ($folder in @("Documents", "Pictures", "Videos")) {
    Write-Host "Backing up $folder..." -ForegroundColor Cyan
    $source = "$env:USERPROFILE\$folder"
    Copy-Item $source $backupDir -Recurse -ErrorAction SilentlyContinue
    if ($?) {
        Write-Host "โœ“ $folder backed up successfully" -ForegroundColor Green
    }
    else {
        Write-Host "โœ— $folder backup failed!" -ForegroundColor Red
    }
}

Write-Host "Backup completed at $(Get-Date)" -ForegroundColor Green

Why this is amazing: One script backs up multiple folders, creates dated backups, and logs success/failure!

The While Loop: Loop Until a Condition

While loops run as long as something is true. Great for waiting or monitoring!

Simple

Countdown Timer

Bash:

counter=5
while [ $counter -gt 0 ]; do
    echo "$counter seconds remaining..."
    sleep 1
    ((counter--))
done
echo "Time's up!"

PowerShell:

$counter = 5
while ($counter -gt 0) {
    Write-Host "$counter seconds remaining..."
    Start-Sleep -Seconds 1
    $counter--
}
Write-Host "Time's up!" -ForegroundColor Red

What happens: Counts down from 5 to 1, waiting 1 second between each number!

Loop Flow Visualization

FOR LOOP:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Start               โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
       โ†“
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Get next item        โ”‚ โ†โ”€โ”
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
       โ†“                    โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚ Do action with item  โ”‚   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
       โ†“                    โ”‚
   More items? โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
       โ”‚ No
       โ†“
   End

WHILE LOOP:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Check condition     โ”‚ โ†โ”€โ”
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
       โ†“                   โ”‚
   True?                   โ”‚
       โ†“ Yes               โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚ Do action            โ”‚  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
       โ”‚                   โ”‚
       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
       โ†“ No
   End

โš ๏ธ Common Confusion: Infinite Loops

Be careful! If the condition never becomes false, the loop runs forever!

Dangerous example:

# DON'T DO THIS!
counter=5
while [ $counter -gt 0 ]; do
    echo "Running..."
    # Oops! Forgot to decrease counter
done

This loops forever because counter stays 5!

How to fix: Always make sure something changes that will eventually make the condition false

How to stop a runaway loop: Press Ctrl+C

๐ŸŽฏ Try It Now: Build a File Organizer

Challenge: Create a script that organizes files by extension!

Setup first (create test files):

Bash:

touch test1.txt test2.txt photo1.jpg photo2.jpg doc1.pdf

PowerShell:

New-Item test1.txt, test2.txt, photo1.jpg, photo2.jpg, doc1.pdf -ItemType File

Then run the organizer:

Bash:

for file in *; do
    if [ -f "$file" ]; then
        ext="${file##*.}"
        mkdir -p "$ext"_files
        mv "$file" "$ext"_files/
        echo "Moved $file to $ext"_files/"
    fi
done

PowerShell:

foreach ($file in Get-ChildItem -File) {
    $ext = $file.Extension.TrimStart('.')
    $folder = "$ext" + "_files"
    New-Item -ItemType Directory -Path $folder -Force | Out-Null
    Move-Item $file $folder
    Write-Host "Moved $($file.Name) to $folder"
}

Result:

  • txt_files/ (contains test1.txt, test2.txt)
  • jpg_files/ (contains photo1.jpg, photo2.jpg)
  • pdf_files/ (contains doc1.pdf)

โœ… Success! Files automatically organized by type!

โœ… Checkpoint #6 (115 minutes total)

What you've learned:

  • Loops repeat actions automatically
  • For loops: process items in a list
  • While loops: repeat while condition is true
  • Loop through files with wildcards (* pattern)
  • You built a file organizer!

๐ŸŽ‰ Amazing progress! One final section to tie it all together!

7. Your First Complete Script

Bringing It All Together

You've learned all the pieces! Now let's combine them into a real, useful script that you might actually use.

๐Ÿฐ The Recipe Book Analogy

You've learned:

  • Commands (ingredients)
  • Variables (prep bowls)
  • Input/Output (serving)
  • If-statements (adjusting for taste)
  • Loops (repeating steps)

Now we're combining them into a complete recipeโ€”a full script that does something impressive!

Project: System Health Checker

Let's build a script that checks your computer's health and gives you a report!

Complete Bash Script

system_health.sh

#!/bin/bash
# System Health Checker
# Checks disk space, memory, and CPU

echo "================================"
echo "   SYSTEM HEALTH REPORT"
echo "   Generated: $(date)"
echo "================================"
echo ""

# Get hostname
hostname=$(hostname)
echo "Computer: $hostname"
echo ""

# Check Disk Space
echo "--- DISK SPACE ---"
disk_usage=$(df -h / | tail -1 | awk '{print $5}' | sed 's/%//')

if [ $disk_usage -gt 90 ]; then
    echo "โŒ CRITICAL: Disk $disk_usage% full"
    status="CRITICAL"
elif [ $disk_usage -gt 75 ]; then
    echo "โš ๏ธ  WARNING: Disk $disk_usage% full"
    status="WARNING"
else
    echo "โœ… OK: Disk $disk_usage% used"
    status="GOOD"
fi
echo ""

# Check Memory
echo "--- MEMORY ---"
if command -v free &> /dev/null; then
    mem_usage=$(free | grep Mem | awk '{print int($3/$2 * 100)}')
    echo "Memory usage: $mem_usage%"
    
    if [ $mem_usage -gt 90 ]; then
        echo "โŒ HIGH: Memory almost full"
        status="CRITICAL"
    elif [ $mem_usage -gt 75 ]; then
        echo "โš ๏ธ  MEDIUM: Monitor memory"
    else
        echo "โœ… OK: Memory healthy"
    fi
fi
echo ""

# Check recent files
echo "--- RECENT CHANGES ---"
echo "Last 5 modified files in home directory:"
counter=1
for file in $(ls -t ~ | head -5); do
    echo "  $counter. $file"
    ((counter++))
done
echo ""

# Save report
report_file="health_report_$(date +%Y%m%d).txt"
{
    echo "System Health Report"
    echo "Date: $(date)"
    echo "Overall Status: $status"
    echo "Disk Usage: $disk_usage%"
    echo "Memory Usage: $mem_usage%"
} > "$report_file"

echo "================================"
echo "Report saved to: $report_file"
echo "================================"
Complete PowerShell Script

SystemHealth.ps1

# System Health Checker
# Checks disk space, memory, and processes

Write-Host "================================" -ForegroundColor Cyan
Write-Host "   SYSTEM HEALTH REPORT" -ForegroundColor Cyan
Write-Host "   Generated: $(Get-Date)" -ForegroundColor Cyan
Write-Host "================================" -ForegroundColor Cyan
Write-Host ""

# Get computer name
$computerName = $env:COMPUTERNAME
Write-Host "Computer: $computerName"
Write-Host ""

# Check Disk Space
Write-Host "--- DISK SPACE ---" -ForegroundColor Yellow
$disk = Get-PSDrive C
$diskUsage = [math]::Round(($disk.Used / ($disk.Used + $disk.Free)) * 100)

if ($diskUsage -gt 90) {
    Write-Host "โŒ CRITICAL: Disk $diskUsage% full" -ForegroundColor Red
    $status = "CRITICAL"
}
elseif ($diskUsage -gt 75) {
    Write-Host "โš ๏ธ  WARNING: Disk $diskUsage% full" -ForegroundColor Yellow
    $status = "WARNING"
}
else {
    Write-Host "โœ… OK: Disk $diskUsage% used" -ForegroundColor Green
    $status = "GOOD"
}
Write-Host ""

# Check Memory
Write-Host "--- MEMORY ---" -ForegroundColor Yellow
$os = Get-CimInstance Win32_OperatingSystem
$memUsage = [math]::Round((($os.TotalVisibleMemorySize - $os.FreePhysicalMemory) / $os.TotalVisibleMemorySize) * 100)
Write-Host "Memory usage: $memUsage%"

if ($memUsage -gt 90) {
    Write-Host "โŒ HIGH: Memory almost full" -ForegroundColor Red
    $status = "CRITICAL"
}
elseif ($memUsage -gt 75) {
    Write-Host "