Variables and Data Types
Summary: in this tutorial, you will learn learn powershell variables, .net types, string manipulation, number operations, and boolean values.
Variables and Data Types
Variables are containers for storing data. In PowerShell, variables are special because they don't just hold text—they hold complete .NET objects with properties, methods, and type information. Understanding how PowerShell handles variables and types is fundamental to writing effective scripts.
Understanding PowerShell Variables
Unlike traditional shells where variables are just text strings, PowerShell variables are object-oriented. When you store something in a variable, you're storing a complete .NET object with all its capabilities.
Variable Syntax: The Dollar Sign
All PowerShell variables begin with a dollar sign ($). This immediately distinguishes them from commands, parameters, and other elements:
# Creating variables
$name = "PowerShell"
$version = 7
$isAwesome = $true
# Using variables
Write-Host $name # PowerShell
Write-Host "Version: $version" # Version: 7
The $ prefix tells PowerShell "this is a variable, retrieve its value." Without the $, PowerShell would treat it as a command name or literal text.
Variable Assignment is Simple
Assignment uses the equals sign. PowerShell figures out the type automatically based on what you assign:
$number = 42 # Integer
$text = "Hello" # String
$decimal = 3.14 # Double (floating point)
$flag = $true # Boolean
$today = Get-Date # DateTime object
$processes = Get-Process # Array of Process objects
This automatic type detection is called type inference. PowerShell examines the value and chooses the appropriate .NET type.
Variables Are Case-Insensitive
PowerShell doesn't care about case in variable names:
$MyVariable = "Hello"
$myvariable # "Hello" - same variable
$MYVARIABLE # "Hello" - still same variable
This is different from languages like C# or JavaScript where case matters. PowerShell prioritizes ease of use over case sensitivity.
Variable Naming Rules
Most variable names follow simple rules:
# Letters, numbers, and underscores work fine
$userName = "Alice"
$age23 = 23
$_private = "hidden"
$counter_1 = 0
# Can start with underscore
$_temp = "temporary"
# Numbers can appear after the first character
$var1 = "first"
$var2 = "second"
For special characters or spaces, use braces:
# Special characters need braces
${my-variable} = "works"
${my.variable} = "also works"
${my variable with spaces} = "yes, really"
# Useful for unusual property names or paths
${C:\Path\With\Slashes} = "unusual but valid"
Working with Variable Cmdlets
PowerShell provides cmdlets specifically for managing variables:
# Create a variable explicitly
New-Variable -Name color -Value "blue"
# Modify an existing variable
Set-Variable -Name color -Value "red"
# Read a variable's value
Get-Variable -Name color
# Returns the variable object itself
# Get just the value
(Get-Variable color).Value
# Returns "red"
# Check if a variable exists
Test-Path Variable:\color
# Returns $true or $false
# List all variables in your session
Get-Variable
# Remove a variable
Remove-Variable -Name color
# Clear a variable's value (keep the variable)
Clear-Variable -Name myVar
These cmdlets are useful in scripts when you need programmatic control over variables, especially when variable names are dynamic.
The Variable Provider
PowerShell treats variables as files in a virtual drive called Variable::
# Navigate to the variable drive
Set-Location Variable:
# List all variables like files
Get-ChildItem
# Access a variable like a file
Get-Item PSVersionTable
Get-Content color
# This works because everything in PowerShell is designed
# to use the same cmdlets via providers
This unified interface is part of PowerShell's elegant design—the same commands work for files, registry keys, variables, and more.
Understanding .NET Types
PowerShell is built on .NET, which means every value in PowerShell is a .NET object with a specific type. The type determines what properties and methods are available and how the object behaves.
Checking Variable Types
Every object has a type, and you can inspect it:
$x = 42
$x.GetType()
# Output shows:
# IsPublic IsSerial Name BaseType
# -------- -------- ---- --------
# True True Int32 System.ValueType
The Name column shows Int32—this is a 32-bit integer. The full .NET type name is System.Int32.
For quick checks:
$x = 42
$x.GetType().Name # Int32
$x.GetType().FullName # System.Int32
$text = "hello"
$text.GetType().Name # String
$decimal = 3.14
$decimal.GetType().Name # Double
$flag = $true
$flag.GetType().Name # Boolean
$date = Get-Date
$date.GetType().Name # DateTime
Why Types Matter
Types determine what you can do with a value:
# Integers have mathematical methods
$x = 42
$x + 10 # 52
[Math]::Abs($x) # 42
# Strings have text methods
$text = "hello"
$text.ToUpper() # "HELLO"
$text.Length # 5
$text.Replace("h", "H") # "Hello"
# DateTime objects have date methods
$date = Get-Date
$date.AddDays(7) # Next week
$date.DayOfWeek # Monday, Tuesday, etc.
$date.ToString("yyyy-MM-dd") # "2025-06-15"
Each type has its own set of capabilities. Understanding types helps you know what operations are available.
Type Casting: Forcing a Type
Sometimes PowerShell's automatic type detection doesn't do what you want. You can explicitly specify a type using type casting:
# Force a string to become an integer
[int]$number = "42"
$number.GetType().Name # Int32
# Force an integer to become a string
[string]$text = 42
$text.GetType().Name # String
# String to decimal
[double]$pi = "3.14159"
# Integer to boolean (0 = false, non-zero = true)
[bool]$flag = 1 # $true
[bool]$flag2 = 0 # $false
# String to DateTime
[datetime]$date = "2025-01-15"
$date.DayOfWeek # Wednesday
Type casting is powerful for ensuring variables have the correct type, especially in functions where you want parameter validation.
Type Constraints
You can lock a variable to a specific type:
# Constrain to integer - won't accept other types
[int]$age = 25
# This works
$age = 30
# This fails - can't convert "hello" to integer
$age = "hello"
# Error: Cannot convert value "hello" to type "System.Int32"
Type constraints prevent bugs by ensuring variables only hold valid values. This is especially useful in functions and scripts.
Common .NET Types Reference
Here are the types you'll use most often:
Numeric Types:
[int] # 32-bit integer: -2,147,483,648 to 2,147,483,647
[long] # 64-bit integer: much larger range
[double] # Floating point (decimals): 3.14
[decimal] # High-precision decimal: financial calculations
[byte] # Small positive integer: 0 to 255
Text and Characters:
[string] # Text: "Hello World"
[char] # Single character: 'A'
Logic:
[bool] # Boolean: $true or $false
Date and Time:
[datetime] # Date and time: Get-Date
[timespan] # Duration: New-TimeSpan -Hours 2
Collections:
[array] # Array of objects: @(1, 2, 3)
[hashtable] # Key-value pairs: @{name="value"}
[arraylist] # Dynamically sized list
[pscustomobject] # Custom object with properties
Special Types:
[regex] # Regular expression pattern
[xml] # XML document
[psobject] # PowerShell object wrapper
Working with Strings
Strings are everywhere in PowerShell—file paths, user input, output messages, configuration data. PowerShell provides two types of string literals with different behaviors.
Double-Quoted Strings: Variable Expansion
Double quotes (") create expandable strings. PowerShell looks for variables and expressions inside and replaces them with their values:
$name = "World"
$greeting = "Hello, $name!"
Write-Host $greeting # Hello, World!
# Expressions in $() get evaluated
"Today is $(Get-Date -Format 'yyyy-MM-dd')"
# Today is 2025-06-15
"2 + 2 = $(2 + 2)"
# 2 + 2 = 4
"Process count: $((Get-Process).Count)"
# Process count: 142
The $(...) syntax evaluates an expression and inserts the result. This is incredibly powerful for building dynamic strings.
Single-Quoted Strings: Literal Text
Single quotes (') create literal strings. Everything inside is treated as literal text—no variable expansion:
$name = "World"
$greeting = 'Hello, $name!'
Write-Host $greeting # Hello, $name!
'No expansion: $(Get-Date)'
# No expansion: $(Get-Date)
'Path: C:\Users\$name\Documents'
# Path: C:\Users\$name\Documents
Use single quotes when you want literal text, especially when dealing with paths, regex patterns, or when you don't want variables expanded.
Choosing Between Quote Types
Use double quotes when:
- You want variables expanded
- You need to embed expressions
- Building dynamic output
Use single quotes when:
- You want literal text
- Working with paths (backslashes don't need escaping)
- Writing regex patterns
- Performance matters (no expansion processing)
Escape Characters and Special Sequences
Inside double-quoted strings, the backtick (`) is the escape character:
# Special characters
"Line 1`nLine 2" # Newline
"Column1`tColumn2" # Tab
"Quote: `"Hello`"" # Embedded quote
"Dollar: `$notAVariable" # Literal $ sign
# Common escapes:
# `n - Newline
# `t - Tab
# `r - Carriage return
# `` - Literal backtick
# `$ - Literal dollar sign
# `" - Literal quote
Here-Strings: Multi-Line Text
For multi-line strings, use here-strings. They preserve formatting and don't require escape characters:
# Double-quoted here-string (variables expand)
$name = "Alice"
$message = @"
Hello $name,
This is a multi-line message.
No escaping needed for "quotes".
Variables like $name are expanded.
Regards,
Admin
"@
# Single-quoted here-string (literal)
$script = @'
$name = "Bob"
Write-Host "Hello, $name"
This is literal - nothing expands.
'@
Here-strings start with @" or @' followed by a newline, and end with "@ or '@ on its own line. Perfect for embedding scripts, SQL queries, JSON, or any multi-line text.
String Methods
Strings are objects with many useful methods:
$text = "PowerShell"
# Case conversion
$text.ToUpper() # "POWERSHELL"
$text.ToLower() # "powershell"
# Searching
$text.Contains("Shell") # True
$text.StartsWith("Power") # True
$text.EndsWith("hell") # True
$text.IndexOf("Shell") # 5 (position)
# Replacement
$text.Replace("Shell", "ful") # "Powerful"
# Trimming whitespace
" hello ".Trim() # "hello"
" hello ".TrimStart() # "hello "
" hello ".TrimEnd() # " hello"
# Splitting and joining
"a,b,c".Split(",") # @("a", "b", "c")
$words = @("Hello", "World")
$words -join " " # "Hello World"
# Substrings
$text.Substring(0, 5) # "Power"
$text.Substring(5) # "Shell"
# Length
$text.Length # 10
String Formatting
PowerShell offers multiple formatting options:
$name = "Alice"
$age = 30
# String interpolation (inside double quotes)
"Name: $name, Age: $age"
# Format operator -f
"Name: {0}, Age: {1}" -f $name, $age
# Named placeholders (PowerShell 5+)
"Name: {name}, Age: {age}" -f @{name=$name; age=$age}
# Format with alignment and padding
"{0,-10} {1,5}" -f "Name", "Age"
# Name Age
# Format numbers
"{0:N2}" -f 1234.5678 # 1,234.57 (2 decimals)
"{0:C}" -f 1234.56 # $1,234.56 (currency)
"{0:P}" -f 0.25 # 25.00% (percent)
# Format dates
$date = Get-Date
"{0:yyyy-MM-dd}" -f $date # 2025-06-15
"{0:HH:mm:ss}" -f $date # 14:30:45
Working with Numbers
PowerShell handles multiple numeric types automatically. Understanding when to use each type helps avoid precision issues and performance problems.
Integer Types
# Regular integers (Int32)
$count = 42
$negative = -100
# Large integers (Int64/long)
$bigNumber = 9999999999
# When to use [long]:
[long]$hugeValue = 5000000000 # Larger than Int32 max
# Byte (0 to 255)
[byte]$smallNumber = 200
Floating-Point Types
# Double (default for decimals)
$pi = 3.14159
$temperature = -40.5
# Decimal (for precise calculations like money)
[decimal]$price = 19.99
[decimal]$tax = 0.08
$total = $price * (1 + $tax) # Precise calculation
Important: Use [decimal] for financial calculations. Regular floating-point ([double]) can have rounding errors due to binary representation.
Numeric Suffixes
PowerShell understands size suffixes:
1KB # 1024 bytes
1MB # 1048576 bytes (1024 * 1024)
1GB # 1073741824 bytes
1TB # 1099511627776 bytes
1PB # 1125899906842624 bytes
# Use in calculations
$fileSize = 5GB
$available = 100GB
if ($fileSize -lt $available) {
"Enough space"
}
# Convert to other units
$bytes = 5GB
$megabytes = $bytes / 1MB # 5120
Mathematical Operations
# Basic arithmetic
10 + 5 # 15
10 - 5 # 5
10 * 5 # 50
10 / 5 # 2
10 % 3 # 1 (modulo/remainder)
# Increment/decrement
$x = 5
$x++ # $x is now 6
$x-- # $x is now 5
$x += 10 # $x is now 15
$x -= 5 # $x is now 10
$x *= 2 # $x is now 20
$x /= 4 # $x is now 5
# Power
[Math]::Pow(2, 8) # 256 (2^8)
# Rounding
[Math]::Round(3.7) # 4
[Math]::Round(3.14159, 2) # 3.14
[Math]::Floor(3.7) # 3
[Math]::Ceiling(3.1) # 4
# Absolute value
[Math]::Abs(-42) # 42
# Min/Max
[Math]::Min(5, 10) # 5
[Math]::Max(5, 10) # 10
# Square root
[Math]::Sqrt(16) # 4
Boolean Values and Null
Boolean Logic
PowerShell has two boolean values: $true and $false:
$isActive = $true
$isDeleted = $false
# Boolean operations
$a = $true
$b = $false
$a -and $b # False
$a -or $b # True
-not $a # False
!$a # False (alternate syntax)
Truthiness: What Counts as True or False?
PowerShell evaluates various values as true or false in conditional contexts:
# False values:
$false
0
"" # Empty string
$null
@() # Empty array
# True values:
$true
1, -1, 42 # Any non-zero number
"hello" # Any non-empty string
@(1) # Non-empty array
# Testing in conditions
if ($value) {
"Truthy"
}
Working with Null
$null represents the absence of a value:
# Explicit null
$nothing = $null
# Uninitialized variables are null
$undeclared
# Returns nothing (null)
# Check for null
if ($null -eq $myVar) {
"Variable is null"
}
# Null coalescing (PowerShell 7+)
$result = $possiblyNull ?? "default value"
# Null-conditional operators (PowerShell 7+)
$length = $possiblyNull?.Length # Returns $null if $possiblyNull is null
Written by the ShellRAG Team
The ShellRAG editorial team writes practical, beginner-friendly PowerShell tutorials with tested code examples and real-world use cases. Every article is technically reviewed for accuracy and updated regularly.
Learn more about us →