PowerShell: Working with Strings
String manipulation is essential for processing text, parsing output, and building commands dynamically. PowerShell provides powerful string operations for searching, replacing, splitting, joining, and formatting text. This lesson covers everything you need to master strings in PowerShell.
What You'll Learn
- Creating and using strings
- String concatenation and interpolation
- String methods and operators
- Searching and replacing text
- Splitting and joining strings
- Regular expressions in PowerShell
- String formatting
- Practical pentesting scenarios
Creating Strings
Single vs Double Quotes
# Single quotes (literal - no variable expansion)
$name = 'Alice'
Write-Host 'Hello, $name'
# Output: Hello, $name
# Double quotes (variable expansion)
$name = "Alice"
Write-Host "Hello, $name"
# Output: Hello, Alice
Here-Strings
# Single-quoted here-string (literal)
$text = @'
This is line 1
This is line 2
Variables like $name are not expanded
'@
# Double-quoted here-string (variable expansion)
$name = "Alice"
$text = @"
Hello, $name!
This allows multiple lines
and variable expansion
"@
String Concatenation
Using + Operator
# Concatenate strings
$first = "Hello"
$second = "World"
$result = $first + " " + $second
# Output: Hello World
# Concatenate with variables
$greeting = "Hello, " + $name + "!"
Using String Interpolation
# Much cleaner!
$name = "Alice"
$greeting = "Hello, $name!"
# With expressions
$x = 5
$y = 10
"The sum is: $($x + $y)"
# Output: The sum is: 15
Using -f Format Operator
# Format string
$name = "Alice"
$age = 25
"{0} is {1} years old" -f $name, $age
# Output: Alice is 25 years old
# With different order
"{1} is the age of {0}" -f $name, $age
# Output: 25 is the age of Alice
String Properties and Methods
Length Property
$text = "Hello, World!"
$text.Length
# Output: 13
Common String Methods
$text = "Hello, World!"
# Case conversion
$text.ToUpper() # HELLO, WORLD!
$text.ToLower() # hello, world!
# Trim whitespace
" Hello ".Trim() # Hello
" Hello ".TrimStart() # "Hello "
" Hello ".TrimEnd() # " Hello"
# Substring
$text.Substring(0, 5) # Hello
$text.Substring(7) # World!
# Replace
$text.Replace("World", "PowerShell") # Hello, PowerShell!
# Contains
$text.Contains("World") # True
# StartsWith / EndsWith
$text.StartsWith("Hello") # True
$text.EndsWith("!") # True
# Index of
$text.IndexOf("World") # 7
$text.LastIndexOf("o") # 8
# Pad
"Hi".PadLeft(5, '*') # ***Hi
"Hi".PadRight(5, '*') # Hi***
String Operators
-eq, -ne (Equality)
"hello" -eq "hello" # True
"hello" -eq "Hello" # True (case-insensitive by default)
"hello" -ceq "Hello" # False (case-sensitive)
"hello" -ne "world" # True (not equal)
-like, -notlike (Wildcards)
"PowerShell" -like "Power*" # True
"PowerShell" -like "*Shell" # True
"PowerShell" -like "*wer*" # True
"PowerShell" -notlike "Bash*" # True
# ? matches single character
"test" -like "t?st" # True
-match, -notmatch (Regex)
"abc123" -match "\d+" # True (contains digits)
"abc123" -match "^[a-z]+" # True (starts with letters)
"[email protected]" -match "\w+@\w+\.\w+" # True (email pattern)
"PowerShell" -notmatch "\d+" # True (no digits)
-replace (Replace with Regex)
# Simple replace
"Hello World" -replace "World", "PowerShell"
# Output: Hello PowerShell
# Regex replace
"abc123def456" -replace "\d+", "NUM"
# Output: abcNUMdefNUM
# Remove all digits
"abc123def456" -replace "\d+", ""
# Output: abcdef
# Case-insensitive by default
"HELLO" -replace "hello", "Hi"
# Output: Hi
# Case-sensitive replace
"HELLO" -creplace "HELLO", "Hi"
# Output: Hi
Splitting Strings
Split Method
# Split by space
"one two three".Split(" ")
# Output: @("one", "two", "three")
# Split by multiple characters
"one,two;three".Split(",;")
# Output: @("one", "two", "three")
# Split and limit results
"a b c d e".Split(" ", 3)
# Output: @("a", "b", "c d e")
-split Operator
# Simple split
"one two three" -split " "
# Output: @("one", "two", "three")
# Regex split
"one123two456three" -split "\d+"
# Output: @("one", "two", "three")
# Split by newline
$text = @"
Line 1
Line 2
Line 3
"@
$text -split "`n"
# Limit results
"a b c d e" -split " ", 3
# Output: @("a", "b", "c d e")
Joining Strings
-join Operator
# Join array elements
$array = @("one", "two", "three")
$array -join " "
# Output: one two three
$array -join ", "
# Output: one, two, three
$array -join ""
# Output: onetwothree
Join Method
[string]::Join(", ", @("one", "two", "three"))
# Output: one, two, three
String Formatting
-f Format Operator
# Basic formatting
"{0} {1}" -f "Hello", "World"
# Output: Hello World
# Multiple uses of same argument
"{0} {0} {1}" -f "Hello", "World"
# Output: Hello Hello World
# Number formatting
"{0:N2}" -f 1234.5678
# Output: 1,234.57
# Currency
"{0:C}" -f 1234.56
# Output: $1,234.56
# Percentage
"{0:P}" -f 0.75
# Output: 75.00%
# Date formatting
"{0:yyyy-MM-dd}" -f (Get-Date)
# Output: 2025-10-08
# Padding
"{0,10}" -f "Hi" # Right-align in 10 chars
"{0,-10}" -f "Hi" # Left-align in 10 chars
Regular Expressions
Matching
# Check if string matches pattern
"test123" -match "\d+"
# Output: True
# Access matched text
$matches[0]
# Output: 123
# Named capture groups
"John Doe" -match "(?<first>\w+) (?<last>\w+)"
$matches.first # John
$matches.last # Doe
Select-String
# Search in files
Select-String -Path *.txt -Pattern "error"
# Search with regex
Select-String -Path *.log -Pattern "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
# Get matched text only
Select-String -Path file.txt -Pattern "password" | Select-Object -ExpandProperty Line
# Case-sensitive search
Select-String -Path file.txt -Pattern "ERROR" -CaseSensitive
Practical Examples
Example 1: Extract IP Addresses
$text = "Server 192.168.1.1 is down. Try 10.0.0.5 instead."
$ipPattern = "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
[regex]::Matches($text, $ipPattern) | ForEach-Object { $_.Value }
# Output: 192.168.1.1, 10.0.0.5
Example 2: Parse Log File
$logLine = "2025-10-08 14:30:15 ERROR Failed login from 192.168.1.100"
$parts = $logLine -split " ", 5
$date = $parts[0]
$time = $parts[1]
$level = $parts[2]
$message = $parts[3..4] -join " "
Write-Host "Date: $date"
Write-Host "Time: $time"
Write-Host "Level: $level"
Write-Host "Message: $message"
Example 3: Clean and Format Data
$names = @(" alice ", "BOB", " charlie")
$cleaned = $names | ForEach-Object {
$_.Trim().Substring(0,1).ToUpper() + $_.Trim().Substring(1).ToLower()
}
# Output: Alice, Bob, Charlie
Example 4: Build SQL Query
$table = "Users"
$columns = @("Id", "Name", "Email")
$query = "SELECT {0} FROM {1}" -f ($columns -join ", "), $table
# Output: SELECT Id, Name, Email FROM Users
Example 5: Parse Command Output
# Get process info and extract PID
$output = "chrome.exe 12345 Console 1 150,000 K"
if ($output -match "(\d+)\s+Console") {
$pid = $matches[1]
Write-Host "Process ID: $pid"
}
Practical Pentesting Scenarios
Scenario 1: Extract Credentials from Text
$config = Get-Content config.txt -Raw
if ($config -match 'password["\s:=]+([^"\s]+)') {
$password = $matches[1]
Write-Host "Found password: $password"
}
Scenario 2: Parse Nmap Output
$nmapOutput = Get-Content nmap_results.txt
$openPorts = $nmapOutput | Where-Object { $_ -match "(\d+)/tcp\s+open" } | ForEach-Object {
if ($_ -match "(\d+)/tcp") {
$matches[1]
}
}
Write-Host "Open ports: $($openPorts -join ', ')"
Scenario 3: Build Attack Command
$target = "192.168.1.100"
$username = "admin"
$passwordList = "passwords.txt"
$command = "hydra -l {0} -P {1} ssh://{2}" -f $username, $passwordList, $target
Write-Host $command
Scenario 4: Clean and Sort Subdomain List
$subdomains = Get-Content subdomains.txt
$cleaned = $subdomains | ForEach-Object {
$_.Trim().ToLower()
} | Sort-Object -Unique
$cleaned | Out-File subdomains_cleaned.txt
Scenario 5: Extract Email Addresses
$html = Get-Content website.html -Raw
$emailPattern = '\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
[regex]::Matches($html, $emailPattern) | ForEach-Object {
$_.Value
} | Sort-Object -Unique
StringBuilder for Performance
Why StringBuilder?
# Slow (creates new string each time)
$result = ""
1..1000 | ForEach-Object {
$result += "Line $_`n"
}
# Fast (modifies in place)
$sb = New-Object System.Text.StringBuilder
1..1000 | ForEach-Object {
$sb.AppendLine("Line $_") | Out-Null
}
$result = $sb.ToString()
Escape Characters
Common Escapes
`n # Newline
`r # Carriage return
`t # Tab
`0 # Null
`` # Backtick
`" # Double quote
`' # Single quote
Examples:
"Line 1`nLine 2"
# Output:
# Line 1
# Line 2
"Column1`tColumn2`tColumn3"
# Output: Column1 Column2 Column3
"He said, `"Hello!`""
# Output: He said, "Hello!"
Quick Reference
Creation:
$str = "text"
$str = 'literal'
$str = @"..."@ # Here-string
Concatenation:
"Hello " + "World"
"Hello $name"
"{0} {1}" -f "Hello", "World"
Methods:
$str.ToUpper()
$str.ToLower()
$str.Trim()
$str.Substring(start, length)
$str.Replace("old", "new")
$str.Split(" ")
$str.Contains("text")
$str.StartsWith("prefix")
$str.EndsWith("suffix")
Operators:
-eq, -ne # Equal, not equal
-like # Wildcard match
-match # Regex match
-replace # Regex replace
-split # Split string
-join # Join array
Regex:
"text" -match "pattern"
$matches[0] # Matched text
Select-String -Path file.txt -Pattern "pattern"
Formatting:
"{0:N2}" -f 123.456 # Number
"{0:C}" -f 123.45 # Currency
"{0:P}" -f 0.75 # Percentage
"{0:yyyy-MM-dd}" -f (Get-Date) # Date
Common Pitfalls
1. String Comparison Case Sensitivity
# Case-insensitive by default
"hello" -eq "HELLO" # True
# Use -ceq for case-sensitive
"hello" -ceq "HELLO" # False
2. Single vs Double Quotes
$name = "Alice"
'Hello, $name' # Output: Hello, $name
"Hello, $name" # Output: Hello, Alice
3. Forgetting Escape Characters
# Wrong: interpreted as variable
"C:\Users\$name\Desktop"
# Right: escape or use single quotes
"C:\Users\`$name\Desktop"
'C:\Users\$name\Desktop'
Resources
Help
Get-Help about_Operators
Get-Help about_Regular_Expressions
Get-Help about_Comparison_Operators
Online
- Regex101: https://regex101.com/
- RegExr: https://regexr.com/
- Microsoft Learn PowerShell docs: https://learn.microsoft.com/powershell/
Next Steps
- Practice regex with real data
- Master -replace for text processing
- Learn Select-String for file searching
- Use StringBuilder for performance
- Build dynamic commands with string formatting
String manipulation is fundamental to PowerShell. Master these techniques and you'll process text data like a pro!
"PowerShell strings: Where 'Hello, $name' actually says hello."