Skip to content

Variables & Data Types

Note

Learn how to store and work with data using PowerShell variables and understand common data types.

Overview

Variables in PowerShell are containers that store data. They always start with a $ symbol and can hold different types of data like text, numbers, true/false values, and more. PowerShell automatically figures out what type of data you're storing (this is called "type inference"), but you can also be explicit about types when needed.

Basic Syntax

# Create a variable (assignment)
$variableName = "value"

# Use a variable
Write-Output $variableName

# Explicitly type a variable
[string]$name = "Raymond"
[int]$age = 30

Key Points

  • Variables always start with $
  • Variable names are NOT case-sensitive ($Name and $name are the same)
  • Use descriptive names ($userList not $ul)
  • PowerShell automatically determines the data type unless you specify it

Common Data Types

Strings (Text)

# Single quotes - literal string (what you see is what you get)
$name = 'Raymond'

# Double quotes - allows variable interpolation
$greeting = "Hello, $name!"  # Result: "Hello, Raymond!"

# Multi-line string with here-string
$longText = @"
This is line 1
This is line 2
Variables work here too: $name
"@

Numbers

# Integers (whole numbers)
$count = 42
$negative = -10

# Decimals (floating point)
$price = 19.99
$percentage = 0.85

# Math operations
$sum = 10 + 5          # 15
$difference = 20 - 8   # 12
$product = 4 * 7       # 28
$quotient = 15 / 3     # 5
$remainder = 17 % 5    # 2 (modulo - remainder after division)

Booleans (True/False)

# Boolean values
$isActive = $true
$isDeleted = $false

# Booleans from comparisons
$result = 10 -gt 5     # $true (10 is greater than 5)
$check = "test" -eq "TEST"  # $true (case-insensitive by default)

$null (Empty/Nothing)

# Represents "no value" or "nothing"
$emptyVariable = $null

# Check if variable is null
if ($null -eq $myVar) {
    Write-Output "Variable is null or doesn't exist"
}

Common Use Cases

Use Case 1: Storing Command Output

What it does: Capture the result of a command for later use

# Store all running processes in a variable
$processes = Get-Process

# Store files from a directory
$files = Get-ChildItem -Path C:\Temp

# Now you can work with the data multiple times without re-running the command
$processes | Where-Object {$_.CPU -gt 100}

Use Case 2: String Manipulation

What it does: Work with and modify text

# Combine strings
$firstName = "John"
$lastName = "Doe"
$fullName = "$firstName $lastName"  # "John Doe"

# String methods
$text = "  PowerShell  "
$text.Trim()           # "PowerShell" (removes spaces)
$text.ToUpper()        # "  POWERSHELL  "
$text.Replace("Power", "Super")  # "  SuperShell  "

# Check string length
$message = "Hello"
$message.Length        # 5

Use Case 3: Type Casting (Converting Types)

What it does: Convert data from one type to another

# Convert string to number
$stringNumber = "42"
$actualNumber = [int]$stringNumber
$result = $actualNumber + 10  # 52

# Convert number to string
$number = 100
$text = [string]$number
$combined = $text + " dollars"  # "100 dollars"

# Convert to boolean
[bool]"text"    # $true (non-empty string)
[bool]""        # $false (empty string)
[bool]0         # $false
[bool]1         # $true

Real-World Examples

Example: Building a File Path

Scenario: Create a file path using variables for flexibility

# Define path components
$baseFolder = "C:\Users"
$username = "raymond"
$subfolder = "Documents"
$filename = "report.txt"

# Build the complete path
$fullPath = "$baseFolder\$username\$subfolder\$filename"
# Result: C:\Users\raymond\Documents\report.txt

# Even better - use Join-Path for cross-platform compatibility
$fullPath = Join-Path -Path $baseFolder -ChildPath $username
$fullPath = Join-Path -Path $fullPath -ChildPath $subfolder
$fullPath = Join-Path -Path $fullPath -ChildPath $filename

Example: Calculating and Formatting Results

Scenario: Calculate disk space and display in readable format

# Get disk info (in bytes)
$disk = Get-PSDrive C
$freeSpaceBytes = $disk.Free

# Convert to gigabytes
$freeSpaceGB = [math]::Round($freeSpaceBytes / 1GB, 2)

# Create readable message
$message = "Free space on C: drive: $freeSpaceGB GB"
Write-Output $message

Explanation: We store the disk info, convert bytes to GB using math, round to 2 decimal places, and create a friendly message.

Important Type Casting Examples

# String to Integer
[int]"123"              # 123
[int]"123.45"           # 123 (truncates decimal)

# String to DateTime
[datetime]"2025-11-29"  # Friday, November 29, 2025 12:00:00 AM

# Number formatting
$price = 1234.5
"{0:C}" -f $price       # $1,234.50 (currency format)
"{0:N2}" -f $price      # 1,234.50 (2 decimal places)

Variable Scope

Variable scope determines where a variable can be accessed and modified. Understanding scope is critical for writing predictable scripts and functions.

Available Scopes

PowerShell provides three main scope modifiers:

local: (default, function-only) - Default scope when you don't specify one - Variables exist only within the current function or script block - Not accessible outside the function where it was created - Automatically cleaned up when the function exits

script: (entire script file) - Available throughout the entire script file - Shared across all functions within the same script - Persists for the lifetime of the script execution - Cleaned up when the script completes

global: (entire session — dangerous) - Available everywhere in the PowerShell session - Persists even after your script finishes - Can interfere with other scripts and functions - Can cause unexpected side effects and conflicts

Best Practice

👉 Use script:, not global:

Global variables pollute the PowerShell session and can cause conflicts. Use script: scope to share variables across functions within your script, and pass values as parameters when calling external scripts or functions.

Scope Examples

# Local scope (default) - only exists in this function
function Test-Local {
    $localVar = "I'm local"
    Write-Output $localVar
}
Test-Local                  # Works: "I'm local"
Write-Output $localVar      # Doesn't work: variable doesn't exist outside function

# Script scope - accessible throughout the script
$script:configPath = "C:\Config\settings.json"

function Get-Config {
    # Can access $script:configPath here
    $config = Get-Content $script:configPath
    return $config
}

function Set-Config {
    # Can also access it here
    $newConfig | Set-Content $script:configPath
}

# Global scope (use sparingly!)
$global:userName = "Raymond"  # Available everywhere, even after script ends

Practical Example: Script-Scoped Variables

# Good practice: Use script scope for shared configuration
$script:logPath = "C:\Logs\myapp.log"
$script:retryCount = 3
$script:timeout = 30

function Write-Log {
    param($Message)
    # Access script-scoped variable
    Add-Content -Path $script:logPath -Value "$(Get-Date): $Message"
}

function Connect-Service {
    param($ServiceUrl)

    $attempts = 0
    while ($attempts -lt $script:retryCount) {
        try {
            # Connection logic here
            Write-Log "Connected to $ServiceUrl"
            return $true
        }
        catch {
            $attempts++
            Write-Log "Retry $attempts of $script:retryCount"
            Start-Sleep -Seconds $script:timeout
        }
    }
    return $false
}

Scope Hierarchy

When PowerShell looks for a variable, it searches in this order:

  1. Local scope (current function/script block)
  2. Script scope (current script file)
  3. Global scope (PowerShell session)
$global:value = "global"
$script:value = "script"

function Test-Hierarchy {
    $value = "local"
    Write-Output $value              # "local" (finds it in local scope first)
    Write-Output $script:value       # "script" (explicitly request script scope)
    Write-Output $global:value       # "global" (explicitly request global scope)
}

Tips & Tricks

Use Descriptive Names

# Bad - unclear what these mean
$a = Get-Process
$x = 100

# Good - clear and readable
$runningProcesses = Get-Process
$maxRetryCount = 100

String Interpolation vs Concatenation

# Concatenation (works but clunky)
$message = "Hello, " + $firstName + " " + $lastName + "!"

# Interpolation (cleaner and easier to read)
$message = "Hello, $firstName $lastName!"

Watch Out for Type Confusion

# This might not do what you expect!
$result = "10" + "5"    # "105" (string concatenation, not addition)

# Be explicit with types
$result = [int]"10" + [int]"5"  # 15 (actual math)

Null vs Empty String

$null -eq ""           # $false - they are NOT the same!
$null -eq $undefined   # $true - undefined variables are $null

# Always check for null before using a variable
if ($null -ne $myVariable) {
# Safe to use $myVariable
}

Additional Resources