Understanding how to store and manage data in PowerShell: variables with $name, automatic and preference variables, data types from string, number, boolean, datetime, array, and hashtable, casting techniques, string manipulation with interpolation and here-strings, the format operator, and the differences between array, ArrayList, and generic List.

In episode 2 you talked to PowerShell through Verb-Noun cmdlets. Now it's time to touch the raw materials of every script: data. Every script — no matter how small — ultimately reads data, stores it, modifies it, and then displays the results. Episode 3 equips you with the language to manage that data: variables and data types.
Think of variables as labeled boxes on your workbench — you put something in, give it a name, and take it back out whenever you want. Data types are the kind of contents in the box: text, numbers, lists, or key-value pairs. Understanding both determines how finely you control your scripts.
Variables in PowerShell always start with a dollar sign. Variable names are case-insensitive — $nama is the same as $NAMA — and cannot contain spaces or start with a number. Create and use your first variable:
$nama = "Arman"
$usia = 28
Write-Host "Halo, $nama"PowerShell provides built-in variables that always exist and are automatically populated by the system. The three you'll encounter most often:
| Variable | Contents | Example Use |
|---|---|---|
$PSVersionTable | PowerShell engine information | Check version and edition |
$_ | Current item in the pipeline | Parameter in Where-Object |
$args | Function/script arguments | Reading positional parameters |
$_ in particular is the pipeline's best friend — in the function and pipeline episodes you'll use it constantly. As a quick exercise, look at $PSVersionTable.PSVersion in your console.
Preference variables change the default behavior of a session. The two most influential:
| Variable | Controls | Common Values |
|---|---|---|
$ErrorActionPreference | How errors are handled | Continue, Stop, SilentlyContinue |
$VerbosePreference | How detailed verbose messages are | SilentlyContinue, Continue |
For example, to make a script stop immediately on error, set $ErrorActionPreference = "Stop" at the top — a failing command will halt execution.
The $env: prefix reads Windows environment variables — data available to all processes, like which user is logged in. Try $env:USERNAME for the active username and $env:PATH for the list of program folders — very useful for scripts that adjust paths per user.
Every value in PowerShell has a type. Prefixing with [type] clarifies or forces interpretation:
| Type | Accelerator | Example Value |
|---|---|---|
| Text | [string] | "Hello world" |
| Integer | [int] | 42 |
| Large integer | [int64] | 9223372036854775807 |
| Decimal | [double] | 3.14 |
| High precision | [decimal] | 0.99 |
| Boolean | [bool] | $true, $false |
| Time & date | [datetime] | 2026-08-03 |
| List of values | [array] | 1, 2, 3 |
| Key-value pairs | [hashtable] | name maps to value |
| Custom object | [PSCustomObject] | Your own object |
Check the type of a value with GetType():
(42).GetType().Name
(3.14).GetType().Name
("teks").GetType().NameCasting forces a value to change type — it matters because operation behavior depends on type: 1 + 2 gives 3, while "1" + "2" gives the text "12":
[int]"42"
[string]42
[int]$false
[datetime]"2026-08-03"Casting isn't just conversion — it's also validation. [int]"abc" will error because "abc" isn't a number. This is useful for validating input in scripts later.
Strings are the most used type, so master how to manipulate them.
You can join strings with the + sign or directly insert variables within double quotes:
$depan = "Arman"
$gabungan = $depan + " Dwi"
$selamat = "Halo, $depan"
Write-Host $gabungan
Write-Host $selamatInterpolation with double quotes only happens if the variable is inside double quotes; single quotes treat everything as raw text.
For long multi-line text, here-strings are the answer — they're opened and closed with three quotes. Open and close with double quotes if you want variables interpolated, or single quotes if everything must be treated as literal text:
$nama = "Arman"
$surat = @"
Halo $nama,
Ini isi surat yang panjang.
Variabel $nama akan diinterpolasi di sini.
"@
Write-Host $suratThe single-quote variant (opened and closed with @' and '@) works identically, except for one thing: $nama inside is read as plain text, not a variable. Choose as needed — interpolation for templates, literal for code you want displayed as-is.
Every string has built-in .NET methods for manipulation: .ToUpper() converts to uppercase, .Replace() replaces pieces of text, .Trim() removes surrounding spaces, and .Length tells you the text length:
$kata = "PowerShell"
$kata.ToUpper()
$kata.Replace("Shell", "Awan")
" rapi ".Trim()
$kata.LengthThe format operator -f inserts values into predefined positions — a clean alternative to complicated interpolation:
$tahun = 2026
"Belajar {0} dimulai tahun {1}" -f "PowerShell", $tahunString comparison in PowerShell is case-insensitive by default — "Powershell" -eq "powershell" evaluates to $true. If you need case-sensitive comparison, add the letter c: -ceq. This detail prevents classic bugs when filtering data.
An array is a sequential collection of values. Create, index, and count its contents:
$buah = @("Apel", "Mangga", "Pisang")
$buah[0]
$buah.Count
$buah[0..1]Indexing starts at zero: $buah[0] takes the first element. The .. operator creates ranges, so $buah[0..1] takes the first two elements at once.
A standard array is fixed length, so adding an element means creating a new array:
$buah = @("Apel", "Mangga")
$buah += "Pisang"
$buah.CountThe += syntax is simple, but for thousands of additions, copying the whole array becomes slow. For that scenario, use ArrayList or the generic List:
$daftar = [System.Collections.ArrayList]::new()
[void]$daftar.Add("Apel")
[void]$daftar.Add("Mangga")
$daftar.CountThe rule of thumb: array @(...) for static collections, ArrayList/List for collections that grow dynamically. [void] in front of .Add() suppresses the method's output so it doesn't fill the screen.
Note
[hashtable] and [PSCustomObject] will be dissected in the pipeline and object manipulation episodes. The key concept from now: arrays for ordered lists, hashtables for fast key-based lookups, and custom objects for shaping data with clean named properties.
Episode 3 gives you control over data: $nama variables, automatic and preference variables, data types from string to hashtable, casting for conversion and validation, the art of string manipulation with interpolation, here-strings, methods, and the format operator, plus arrays with all their variants.
Key takeaways:
$_, $PSVersionTable, and $env: are the ones you'll encounter most.[int] and [string] changes how operations work.@(...) for static collections; ArrayList/List for growing collections.In the next episode, episode 4, we learn about operators & expressions — arithmetic, comparison, logic, assignment, redirection, and special operators like dot-sourcing, range, and format. These are the "engine" that drives the data you've just mastered. See you in episode 4!