In PowerShell, text is represented by the System.String .NET class. Because strings are full .NET objects rather than simple streams of bytes, PowerShell provides direct access to both native object methods and shell-level operators for string interpolation, regular expression matching, dynamic formatting, and multi-line parsing.
The most common operations on strings in PowerShell are explained below.
Create a String
A string can be created by assigning text to a variable. PowerShell supports both single-quoted (') and double-quoted (") string literals.
$message = "Hello World"
Write-Output $messageHello WorldEmpty String
An empty string can be created by assigning an empty value to a variable. To check whether a string is empty, use [string]::IsNullOrEmpty() or compare it against "".
$variable_name = ""if ([string]::IsNullOrEmpty($variable_name)) {
Write-Output "The string is empty"
}Below is a complete example with empty strings:
$a = ""
$b = "Hello"
if ([string]::IsNullOrEmpty($a)) { Write-Output "String A is empty" }
if ([string]::IsNullOrEmpty($b)) { Write-Output "String B is empty" }String A is emptyString Concatenation
There are two primary ways to combine strings: the concatenation operator (+) and string interpolation (using double quotes).
Concatenation with the + Operator
You can combine strings using the arithmetic addition operator (+):
$first = "Power"
$second = "Shell"
$combined = $first + $second
Write-Output $combinedPowerShellYou can also concatenate multiple variables and literals directly:
$Greeting = "Hello, " + $env:USERNAME + "! Welcome to " + $env:COMPUTERNAME + "."
$GreetingHello, Tom! Welcome to WORKSTATION-01.String Interpolation
Interpolation embeds variable values directly inside a double-quoted string, avoiding manual concatenation.
$name = "Tom"
$age = 30
Write-Output "Hello, $name! You are $age years old."Hello, Tom! You are 30 years old.where:
- Variables prefixed with
$inside a double-quoted string are automatically replaced with their values. - For expressions or property access, wrap them in
$(...):"Total: $($price * 2)".
$a = "Hello"
$b = "World"
$d = 123
$c = "$a and $b $d"
Write-Output $cHello and World 123$TargetHost = "sql-prod-01"
Write-Output "Double quotes: Connecting to $TargetHost"
Write-Output 'Single quotes: Connecting to $TargetHost'Double quotes: Connecting to sql-prod-01
Single quotes: Connecting to $TargetHostSubexpression Evaluation $()
When referencing an object property or method inside a double-quoted string, a bare variable reference evaluates only the base object name, leaving the property name as literal text. To force PowerShell to evaluate an entire property path or expression, wrap it in the subexpression operator $():
$Service = Get-Service -Name "wuauserv"
Write-Output "Incorrect: $Service.DisplayName is currently $Service.Status"
Write-Output "Correct: $($Service.DisplayName) is currently $($Service.Status)"where:
$Service.DisplayNameoutside of$()causes PowerShell to call$Service.ToString()and append the literal string.DisplayName.$($Service.DisplayName)forces the parser to resolve the actual property value before embedding it into the string.
Incorrect: System.ServiceProcess.ServiceController.DisplayName is currently System.ServiceProcess.ServiceController.Status
Correct: Windows Update is currently RunningHere-Strings
A here-string is a string literal used to declare multi-line text blocks without needing escape characters for embedded quotation marks. Here-strings start with @" and end with "@ (each on its own line).
Here-String Syntax Rules
- The opening token (
@"or@') must be followed immediately by a newline. No characters or spaces can appear after the quote on the same line. - The closing token (
"@or'@) must sit on its own line at the beginning of the line (column 0), with no preceding whitespace.
@" ... "@(Double-quoted here-string): Supports variable interpolation and escape sequences.@' ... '@(Single-quoted here-string): Completely literal; preserves all characters and whitespace as typed.
$Server = "web-node-01"
$IpAddress = "192.168.1.50"
$ConfigFile = @"
[Interface]
NodeName = $Server
BindingIP = $IpAddress
Environment = Production
GeneratedAt = $(Get-Date -Format "yyyy-MM-dd")
"@
$ConfigFilewhere:
@" ... "@encloses the multi-line block.$Server,$IpAddress, and the$(Get-Date ...)subexpression are evaluated dynamically.
[Interface]
NodeName = web-node-01
BindingIP = 192.168.1.50
Environment = Production
GeneratedAt = 2026-09-27String Length
Unlike Batch Scripting, PowerShell strings expose a built-in .Length property that returns the number of characters.
$str = "Hello World"
Write-Output "String is $($str.Length) characters long"String is 11 characters longString to Integer
A string containing numeric digits can be converted to an integer using a cast ([int]) or the -as operator. This allows arithmetic operations to be performed.
$var = "12345"
$var = [int]$var + 5
Write-Output $var12350You can also use -as for safe conversion that returns $null on failure:
$value = "42"
$number = $value -as [int]
Write-Output ($number + 8)50Common String Methods
Because PowerShell strings are .NET System.String instances, they inherit built-in transformation and inspection methods.
| Method | Description | Example | Result |
|---|---|---|---|
.Substring(start, length) |
Extracts a segment starting at an index | "Production".Substring(0, 4) |
"Prod" |
.Replace(old, new) |
Replaces literal character sequences | "Server01".Replace("01", "99") |
"Server99" |
.Split(char) |
Splits a string into an array of substrings | "A,B,C".Split(",") |
@("A", "B", "C") |
.Trim() |
Strips leading and trailing whitespace | " data ".Trim() |
"data" |
.TrimStart() / .TrimEnd() |
Strips whitespace from the start or end | " data".TrimStart() |
"data" |
.ToUpper() / .ToLower() |
Converts string to uppercase or lowercase | "pwsh".ToUpper() |
"PWSH" |
.Contains(str) |
Returns boolean if substring exists | "DomainAdmin".Contains("Admin") |
$true |
.StartsWith(str) / .EndsWith(str) |
Checks boundary character sequences | "backup.zip".EndsWith(".zip") |
$true |
.Substring(): Left String, Mid String, Right String
Extracts a portion of a string starting at a given index.
$str = "Helloworld"
Write-Output $str
$str = $str.Substring(0, 5)
Write-Output $strHelloworld
Hello$str = "Helloworld"
Write-Output $str
$str = $str.Substring(3, 7)
Write-Output $strHelloworld
loworld$str = "This message needs changed."
Write-Output $str
$str = $str.Substring($str.Length - 8)
Write-Output $strThis message needs changed.
changed..Replace()
Replaces all occurrences of a substring with another string.
$str = "This message needs changed."
Write-Output $str
$str = $str.Replace("needs", "has")
Write-Output $strThis message needs changed.
This message has changed..Remove(): Remove a Substring
Removes a specified number of characters starting at a given index.
$str = "Batch scripts is easy. It is really easy."
Write-Output $str
$str = $str.Replace("is ", "")
Write-Output $strBatch scripts is easy. It is really easy.
Batch scripts easy. It really easy.Remove Both Ends
To remove the first and last character, use .Substring(1, $str.Length - 2).
$str = "Batch scripts is easy. It is really easy"
Write-Output $str
$str = $str.Substring(1, $str.Length - 2)
Write-Output $strBatch scripts is easy. It is really easy
atch scripts is easy. It is really easRemove All Spaces
Use .Replace(" ", "") to strip every space from a string.
$str = "This string has a lot of spaces"
Write-Output $str
$str = $str.Replace(" ", "")
Write-Output $strThis string has a lot of spaces
Thisstringhasalotofspaces.Split()
Splits a string into an array of substrings based on a delimiter.
$result = "apple,banana,cherry".Split(",")
$resultapple
banana
cherry.Trim()
Removes leading and trailing whitespace (or specified characters).
$result = " padded text ".Trim()
Write-Output "[$result]"[padded text]Combined Example: Parsing a Log Line
$RawLog = " 2026-10-24|CRITICAL|Service 'Spooler' terminated unexpectedly. "
$CleanLog = $RawLog.Trim()
$Segments = $CleanLog.Split("|")
$Timestamp = $Segments[0]
$LogLevel = $Segments[1]
$Message = $Segments[2]
[PSCustomObject]@{
Time = $Timestamp
Level = $LogLevel
Summary = $Message.Replace("terminated unexpectedly", "crashed")
}where:
.Trim()removes leading and trailing spaces from$RawLog..Split("|")divides the line into an array of three elements based on the pipe character..Replace()replaces the target substring with"crashed".
Time Level Summary
---- ----- -------
2026-10-24 CRITICAL Service 'Spooler' crashed.Align Right
The -f format operator can align text to the right by adding leading spaces. This is useful for lining up columns of numbers in reports.
$x = 3000
$y = 2
"X={0,8}" -f $x
"Y={0,8}" -f $yX= 3000
Y= 2Pattern Matching and Replacement: -match and -replace
While .Replace() handles literal text replacements, PowerShell provides native operators powered by the .NET Regular Expression (regex) engine: -match and -replace.
The -match Operator and $Matches
The -match operator tests whether a string matches a regular expression pattern, returning $true or $false.
When a match is found, PowerShell automatically populates the $Matches automatic variable with a hashtable containing the matched strings and any captured groups.
"user@example.com" -match "^\w+@\w+\.\w+$"TrueUsing capture groups:
"Order-2026-0091" -match "Order-(\d+)-(\d+)"
$matches[1]
$matches[2]2026
0091where $matches[0] holds the full match; $matches[1], $matches[2], etc. hold capture groups.
Using named captures in a real scenario:
$LogLine = "Error 404: Resource /api/v1/users not found on host web01."
$Pattern = "Error (?<Code>\d{3}): Resource (?<Endpoint>\S+)"
if ($LogLine -match $Pattern) {
[PSCustomObject]@{
Status = "Match Detected"
HttpCode = $Matches['Code']
Path = $Matches['Endpoint']
}
}where:
\d{3}matches three consecutive numeric digits.(?<Code>...)is a named capture group stored under$Matches['Code'].(?<Endpoint>\S+)captures consecutive non-whitespace characters.
Status HttpCode Path
------ -------- ----
Match Detected 404 /api/v1/usersThe -replace Operator
The -replace operator replaces all occurrences matching a regex pattern with a substitution string.
"2026-03-14" -replace "-", "/"2026/03/14Replacing repeated whitespace:
"Node01 Running 10.0.0.5" -replace '\s+', ' 'Node01 Running 10.0.0.5Using regex backreferences ($1, $2) to reorganize matched text:
"Doe, John" -replace '^(\w+),\s*(\w+)$', '$2 $1'John DoeString Formatting with -f
The format operator (-f) provides a structured way to assemble strings using .NET composite formatting. Instead of concatenating multiple variables, you supply an indexed template string on the left and a comma-separated list of values on the right.
Syntax:
"<template with {0}, {1}, ...>" -f $val0, $val1Basic Example
$name = "Jamie"
$score = 92.5
"{0} scored {1:N1}%" -f $name, $scorewhere:
{0}and{1}are placeholders corresponding to the arguments after-f, in order.{1:N1}applies a numeric format specifier (N1), rounding to one decimal place.
Jamie scored 92.5%Common Format Specifiers
| Specifier | Name | Example Input | Pattern | Formatted Result |
|---|---|---|---|---|
{0:N2} |
Number with decimals | 10500.5678 |
"{0:N2}" -f 10500.5678 |
10,500.57 |
{0:D4} |
Zero-padded integer | 42 |
"{0:D4}" -f 42 |
0042 |
{0:P1} |
Percentage | 0.156 |
"{0:P1}" -f 0.156 |
15.6% |
{0:C} |
Currency (locale-based) | 19.99 |
"{0:C}" -f 19.99 |
$19.99 |
{0:X} |
Hexadecimal | 255 |
"{0:X}" -f 255 |
FF |
{0,-10} |
Left-aligned padding | "Node" |
"{0,-10}" -f "Node" |
"Node " |
{0,10} |
Right-aligned padding | "Node" |
"{0,10}" -f "Node" |
" Node" |
Practical Example: Generating Formatted Storage Summaries
The following script gathers system storage metrics, calculates consumption percentages, and formats the output into clean text strings using the -f operator:
$Disks = Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType=3"
foreach ($disk in $Disks) {
$driveId = $disk.DeviceID
$totalGB = $disk.Size / 1GB
$freeGB = $disk.FreeSpace / 1GB
$usedPercent = ($disk.Size - $disk.FreeSpace) / $disk.Size
$reportLine = "Drive {0,-3} | Total: {1,7:N2} GB | Free: {2,7:N2} GB | Used: {3,6:P1}" -f `
$driveId, $totalGB, $freeGB, $usedPercent
Write-Output $reportLine
}where:
Drive {0,-3}left-aligns the drive identifier within a 3-character field.{1,7:N2}formats total storage as a 2-decimal number right-aligned in a 7-character field.{3,6:P1}formats the utilization fraction as a single-decimal percentage right-aligned in a 6-character field.
Execute the script from the console:
pwsh ./format-storage-report.ps1Drive C: | Total: 255.40 GB | Free: 42.15 GB | Used: 83.5%
Drive D: | Total: 1024.00 GB | Free: 512.80 GB | Used: 49.9%