How to Trim Strings in PowerShell

To trim a string in PowerShell, call .Trim() to remove spaces from both ends, or .TrimStart() and .TrimEnd() for one side only:

$name = '   Alice Johnson   '

"Trim():      [$($name.Trim())]"
"TrimStart(): [$($name.TrimStart())]"
"TrimEnd():   [$($name.TrimEnd())]"
"Tabs and line breaks go too: [$("`tAlice Johnson`r`n".Trim())]"

Output:

Trim():      [Alice Johnson]
TrimStart(): [Alice Johnson   ]
TrimEnd():   [   Alice Johnson]
Tabs and line breaks go too: [Alice Johnson]

Below I cover trimming specific characters, the first or last few characters, and text before or after a character. I ran every example in PowerShell 7.6 and Windows PowerShell 5.1, and I point out the one place they differ.

Trim specific characters

Pass the characters you want removed. Trim keeps removing them from the ends until it reaches a different character:

$sku  = '---TX-1042---'
$path = 'C:\Reports\2026\'
$code = '000078701'

"Trim('-'):       $($sku.Trim('-'))"
"TrimEnd('\'):    $($path.TrimEnd('\'))"
"TrimStart('0'):  $($code.TrimStart('0'))"
"Trim(' ', '-'):  $('  --TX-1042--  '.Trim(' ', '-'))"

Output:

Trim('-'):       TX-1042
TrimEnd('\'):    C:\Reports\2026
TrimStart('0'):  78701
Trim(' ', '-'):  TX-1042
PowerShell Trim, TrimStart and TrimEnd with specific characters
Dashes, a trailing backslash and leading zeros removed (PowerShell 7)

TrimStart(‘0’) is handy for IDs that were padded with zeros, and TrimEnd(‘\’) cleans up folder paths before you join them.

Trim works on characters, not words

TrimEnd(‘.csv’) doesn’t remove the text “.csv”. It removes any of the characters ., c, s and v from the end, which eats letters from the file name:

'orders.csv'.TrimEnd('.csv')
'reports.csv'.TrimEnd('.csv')
'reports.csv' -replace '\.csv$', ''

Output:

order
report
reports

To remove a suffix, anchor it with -replace, as in the last line. Removing characters from a string has more examples.

Remove extra spaces inside a string

Trim only touches the ends. To collapse runs of spaces inside the text, replace \s+ with a single space:

$address = '  1600   Pennsylvania    Ave  '

"Trim only:       [$($address.Trim())]"
"Trim + collapse: [$(($address -replace '\s+', ' ').Trim())]"

Output:

Trim only:       [1600   Pennsylvania    Ave]
Trim + collapse: [1600 Pennsylvania Ave]

Hidden characters that Trim() misses

Text pasted from web pages or Excel can carry invisible characters. Trim removes the non-breaking space, but not the zero-width space:

$nbsp  = "Austin$([char]0x00A0)"
$zwsp  = "Austin$([char]0x200B)"

"Non-breaking space: length $($nbsp.Length), after Trim() $($nbsp.Trim().Length)"
"Zero-width space:   length $($zwsp.Length), after Trim() $($zwsp.Trim().Length)"
"After -replace:     length $(($zwsp -replace '[\s\u200B\uFEFF]', '').Length)"

Output:

Non-breaking space: length 7, after Trim() 6
Zero-width space:   length 7, after Trim() 7
After -replace:     length 6

The -replace pattern removes whitespace plus the zero-width space (U+200B) and byte order mark (U+FEFF), the two I run into most.

PowerShell 7 hides the problem in comparisons

In my tests, PowerShell 7’s -eq treated the value with a zero-width space as equal to ‘Austin’, while 5.1 didn’t. .Equals() compares exactly in both:

$zwsp = "Austin$([char]0x200B)"

"-eq 'Austin':      $($zwsp -eq 'Austin')"
".Equals('Austin'): $($zwsp.Equals('Austin'))"

Output in PowerShell 7:

-eq 'Austin':      True
.Equals('Austin'): False

Output in Windows PowerShell 5.1:

-eq 'Austin':      False
.Equals('Austin'): False

So a value can pass an -eq check in 7 and still fail as a hashtable key or in another system. Clean imported text before you use it.

Trim every string in an array

Call .Trim() on the array itself. PowerShell runs it on each item and gives back a new array:

$states = '  Texas', 'Ohio  ', ' Utah '

$trimmed = $states.Trim()
$trimmed -join '|'

Output:

Texas|Ohio|Utah

This is also the quickest way to clean a column after splitting a string.

Remove the first or last characters

Remove the first N characters

Substring(4) returns everything from position 4, and Remove(0, 4) deletes the first four. Both drop the INV- prefix here:

$invoice = 'INV-20260928-0042'

$invoice.Substring(4)
$invoice.Remove(0, 4)

Output:

20260928-0042
20260928-0042

Remove the last N characters

Subtract from the length to keep everything except the end. This removes the five-character .xlsx extension:

$file = 'budget-2026.xlsx'

$file.Substring(0, $file.Length - 5)
$file.Remove($file.Length - 5)

Output:

budget-2026
budget-2026

For file names, [IO.Path]::GetFileNameWithoutExtension() is safer because extensions vary in length.

Handle strings shorter than N

Substring throws an error when the string is shorter than the start position. A regex or a Math.Min guard handles short strings:

$id = 'TX'

try { $id.Substring(4) } catch { "Substring(4) failed, 'TX' has only $($id.Length) characters" }
"Regex version: [$($id -replace '^.{0,4}', '')]"
"Safe version:  [$($id.Substring([Math]::Min(4, $id.Length)))]"

Output:

Substring(4) failed, 'TX' has only 2 characters
Regex version: []
Safe version:  []
PowerShell Substring error on a short string and safe alternatives
Substring(4) fails on a two-character string, the other two don’t (Windows PowerShell 5.1)

Microsoft’s Substring reference lists the exceptions it can throw.

Trim before or after a character

To keep the text before a character, split on it and take the first part. To keep the text after it, find it with IndexOf and take the rest:

$email = 'alice.johnson@contoso.com'

"Before @:  $($email.Split('@')[0])"
"After @:   $($email.Substring($email.IndexOf('@') + 1))"

Output:

Before @:  alice.johnson
After @:   contoso.com

IndexOf returns -1 when the character isn’t there, so check before you cut:

$user = 'alice.johnson'
$at   = $user.IndexOf('@')

"IndexOf returns $at when the character isn't there"
if ($at -ge 0) { $user.Substring(0, $at) } else { "No @ found, keeping '$user'" }

Output:

IndexOf returns -1 when the character isn't there
No @ found, keeping 'alice.johnson'

Before or after the last occurrence

Use LastIndexOf to split a path into folder and file name. For key=value text, -split with a limit of 2 keeps any later = signs together:

$path = 'C:\Reports\2026\Q3\sales-summary.csv'

"Folder:  $($path.Substring(0, $path.LastIndexOf('\')))"
"File:    $($path.Substring($path.LastIndexOf('\') + 1))"
"Setting: $(('Server=SQL01;Port=1433' -split '=', 2)[1])"

Output:

Folder:  C:\Reports\2026\Q3
File:    sales-summary.csv
Setting: SQL01;Port=1433
PowerShell trim text before and after the last backslash
LastIndexOf and -split with a limit (PowerShell 7)

The about_Split page explains the limit argument.

Trim a string to a maximum length

To cut text down to a fixed length, for a report column or a file name, use Substring with a length check. This version adds an ellipsis:

function Get-Truncated {
    param([string]$Text, [int]$Max)
    if ($Text.Length -le $Max) { return $Text }
    $Text.Substring(0, $Max - 3) + '...'
}

Get-Truncated -Text 'Quarterly sales summary for the Southwest region' -Max 25
Get-Truncated -Text 'Short title' -Max 25

Output:

Quarterly sales summar...
Short title

The .NET String.Trim documentation covers which characters count as white space.

Frequently Asked Questions

How do I trim spaces from a string in PowerShell?

Call $text.Trim(). It removes spaces, tabs and line breaks from both ends. Use TrimStart() or TrimEnd() for one side.

How do I trim a specific character in PowerShell?

Pass it to Trim: '---TX---'.Trim('-') returns TX. You can pass several characters, like .Trim(' ', '-').

Why does TrimEnd(‘.csv’) remove extra letters?

Trim methods treat the argument as a set of characters, not a word. Use -replace '\.csv$', '' to remove the suffix.

How do I remove the first 4 characters of a string?

Use $text.Substring(4). If the string might be shorter, use $text -replace '^.{0,4}', '' instead.

How do I get the text before a character in PowerShell?

Split on it and take the first part: $email.Split('@')[0]. For the text after it, use $email.Substring($email.IndexOf('@') + 1).

Keep working with strings using these guides: