Part 2 - Variables, scope and flow control
Now that you’ve written your first .ps1
script, it’s time to move past static commands. This post covers variables, scope, and flow control. The building blocks of decision-making in your scripts. Once you grasp these, you can write logic that adapts to different inputs, environments, or outcomes.
Declaring and Using Variables
Variables in PowerShell always begin with a dollar sign:
$ServiceName = 'wuauserv'
They’re typeless by default but support strong typing when needed:
[string]$ComputerName = 'SRV01'
[int]$RetryCount = 3
Use Write-Output
to display a variable’s value during script execution:
Write-Output "Target computer: $ComputerName"
Variables are case-insensitive by default, but write them consistently for readability.
Scope: The Underrated Gotcha
PowerShell has several variable scopes:
Global
: accessible anywhere (not recommended in scripts)Script
: accessible throughout the current script fileLocal
: default inside functions or loopsPrivate
: limited to the block in which it’s declared
In most cases, default Local
scope is sufficient. But be mindful when working with nested functions or dot-sourcing.
Example:
$global:VMName = 'TestVM' # Avoid unless absolutely required
Use Write-Output
instead of relying on global state to pass data between components.
Conditional Logic: if
, elseif
, else
Control flow starts with branching. Here’s a simple check for service status:
$service = Get-Service -Name $ServiceName
if ($service.Status -eq 'Running') {
Write-Output "$ServiceName is running."
}
elseif ($service.Status -eq 'Stopped') {
Write-Output "$ServiceName is stopped."
}
else {
Write-Output "$ServiceName is in an unexpected state: $($service.Status)"
}
Keep your conditionals clean and favor -eq
, -ne
, -gt
, -lt
, -like
, and -match
for comparisons. Don’t use ==
.
Switch: A Cleaner Alternative
switch
blocks simplify multiple matching conditions. They’re basically a bunch of if-statements combined:
switch ($service.Status) {
'Running' { Write-Output "Service is up." }
'Stopped' { Write-Output "Service is down." }
default { Write-Output "Unknown state." }
}
Use switch
when comparing one value against multiple known possibilities.
Loops: foreach
, while
, do-until
foreach
Use foreach
when iterating through arrays or collections:
$computers = @('SRV01', 'SRV02', 'SRV03')
foreach ($computer in $computers) {
Write-Output "Pinging $computer..."
Test-Connection -ComputerName $computer -Count 1
}
✅ Prefer
foreach
overForEach-Object
for clarity and performance in scripts.
while
and do
Use these for logic that depends on a condition:
$count = 0
while ($count -lt 3) {
Write-Output "Attempt $count"
$count++
}
Summary
You now know how to:
- Declare and use variables
- Control script flow with
if
,switch
, and loops - Avoid scope-related surprises
- Structure your script’s logic clearly and predictably
This is where your scripts start feeling like real programs—capable of reacting to input, evaluating outcomes, and making decisions.
Coming Up
In Part 3, we’ll introduce functions: how to encapsulate your logic, pass parameters, and build reusable building blocks for clean, modular code.
Until then: Break it down. Use control flow. Keep scripting.