PowerShell Replace Text in String: Complete Examples

PowerShell Replace Text in String: Complete Examples

PowerShell Tips Editor 4 min read
PowerShell Replace Text in String: Complete Examples

Text replacement shows up everywhere in real PowerShell work: patching config files before deployment, normalizing log entries, rewriting URL patterns in bulk HTML files. PowerShell offers two distinct approaches — the -replace operator and the .Replace() method — and they behave differently in ways that catch people off guard. This guide covers both, explains when to use regex capture groups, and shows you how to replace text in PowerShell strings across single values and entire files.

Quick Answer / TL;DR

Use -replace for pattern-based or case-insensitive replacement. Use .Replace() for simple, case-sensitive literal swaps:

'Hello World' -replace 'world', 'PowerShell'   # Hello PowerShell (case-insensitive)
'Hello World'.Replace('World', 'PowerShell')    # Hello PowerShell (case-sensitive)

Using the -replace Operator

The -replace operator takes a pattern and a replacement string. The pattern is a .NET regular expression — which makes it powerful but means literal dots, brackets, and other regex metacharacters must be escaped:

$text = 'Server: 192.168.1.100'

# Simple literal replacement
$text -replace '192.168.1.100', '10.0.0.50'

# Replace all spaces with underscores
'Hello World Again' -replace ' ', '_'

# Remove all digits
'Report_2026_Q1' -replace '\d', ''
Server: 10.0.0.50
Hello_World_Again
Report__Q

The -replace operator replaces all non-overlapping matches, not just the first one. It is also case-insensitive by default — 'Hello' -replace 'hello', 'Hi' works even though the cases don’t match.

Case-Insensitive Replace

-replace is already case-insensitive. If you specifically need case-sensitive matching, use -creplace:

$input = 'Apple apple APPLE'

# Default -replace: case-insensitive, replaces all
$input -replace 'apple', 'fruit'

# -creplace: case-sensitive, only matches exact case
$input -creplace 'apple', 'fruit'
fruit fruit fruit
Apple fruit APPLE

String .Replace() Method

The .Replace() .NET method is simpler and faster for literal string replacement, but it is always case-sensitive:

$path = 'C:\OldProject\src\main.ps1'

# Replace part of a path
$newPath = $path.Replace('OldProject', 'NewProject')
$newPath

# Chain multiple replacements
'  hello   world  '.Trim().Replace(' ', '-')
C:\NewProject\src\main.ps1
hello-world

Use .Replace() when you want a literal string swap, certainty about case sensitivity, and no regex involvement. Use -replace when you need patterns, case-insensitive matching, or capture groups.

Replace with Regex Capture Groups

Capture groups let you reference parts of the matched pattern in the replacement string using $1, $2, etc.:

# Reformat a date from MM/DD/YYYY to YYYY-MM-DD
$date = '05/04/2026'
$date -replace '(\d{2})/(\d{2})/(\d{4})', '$3-$1-$2'

# Wrap all email addresses in angle brackets
$log = 'Contact: [email protected] for support'
$log -replace '([\w.]+@[\w.]+)', '<$1>'

# Named capture groups for clarity
$name = 'Smith, John'
$name -replace '(?<last>[\w]+), (?<first>[\w]+)', '${first} ${last}'
2026-05-04
Contact: <[email protected]> for support
John Smith

Replace Text in a File

To replace text throughout a file, read it with Get-Content -Raw, apply -replace, and write it back with Set-Content:

$filePath = 'C:\Configs\appsettings.json'

# Read, replace, write back
$content = Get-Content $filePath -Raw
$content = $content -replace 'staging\.example\.com', 'production.example.com'
Set-Content -Path $filePath -Value $content -Encoding UTF8

Note: staging\.example\.com uses \. to match a literal dot. Without the backslash, . in regex means “any character,” which would cause unintended replacements.

Bulk Replace Across Multiple Files

$searchPattern   = 'OldDatabaseName'
$replaceWith     = 'NewDatabaseName'
$targetDirectory = 'C:\Scripts'

Get-ChildItem -Path $targetDirectory -Filter '*.ps1' -Recurse | ForEach-Object {
    $content = Get-Content $_.FullName -Raw
    if ($content -match $searchPattern) {
        $newContent = $content -replace $searchPattern, $replaceWith
        Set-Content -Path $_.FullName -Value $newContent -Encoding UTF8
        Write-Output "Updated: $($_.Name)"
    }
}
Updated: deploy.ps1
Updated: db-connect.ps1

Common Errors and Fixes

  • -replace uses regex — literal dots need escaping: '192.168.1.1' -replace '192.168.1.1', 'x' will match 192X168Y1Z1 too because . matches any character. For a literal dot, escape it: '192\.168\.1\.1'. Alternatively, use [regex]::Escape('192.168.1.1') to auto-escape a pattern.
  • .Replace() is case-sensitive, -replace is not: If you use 'Hello'.Replace('hello', 'Hi'), nothing is replaced because the cases don’t match. Either match the case exactly, or switch to -replace which is case-insensitive by default.

Related Cmdlets / See Also

Wrapping Up

Use -replace for pattern-based, case-insensitive, or multi-match replacement. Use .Replace() for fast, literal, case-sensitive swaps. Remember that -replace treats its first argument as a regex — escape literal dots and brackets. For file replacement, combine Get-Content -Raw with Set-Content. Your next step: apply bulk replacement to a folder of config files using the pattern shown above.

Send-Item -To