How to Create a Character Array in PowerShell

To create a character array in PowerShell, call ToCharArray() on a string. It returns a Char[] array with one item for each character, which you can loop through, filter or count:

$chars = 'Seattle'.ToCharArray()

"Type:  $($chars.GetType().Name)"
"Count: $($chars.Count)"
"Items: $($chars -join ' | ')"

Output:

Type:  Char[]
Count: 7
Items: S | e | a | t | t | l | e

Below I compare the other ways to build one, then cover letter ranges, filtering, counting and joining characters back into a string. Every example ran in PowerShell 7.6 and Windows PowerShell 5.1.

Convert a string to an array of characters

ToCharArray() and a [char[]] cast give the same result. You can also cast a list of single letters. -split with an empty pattern looks similar, but it returns strings and adds an empty item at each end:

$city = 'Austin'

$a = $city.ToCharArray()
$b = [char[]]$city
$c = [char[]]@('A', 'u', 's')
$d = $city -split ''

'ToCharArray()   {0,-9} {1} items' -f $a.GetType().Name, $a.Count
'[char[]] cast   {0,-9} {1} items' -f $b.GetType().Name, $b.Count
'[char[]] list   {0,-9} {1} items' -f $c.GetType().Name, $c.Count
"-split ''       {0,-9} {1} items: {2}" -f $d.GetType().Name, $d.Count, (($d | ForEach-Object { "'$_'" }) -join ',')

Output:

ToCharArray()   Char[]    6 items
[char[]] cast   Char[]    6 items
[char[]] list   Char[]    3 items
-split ''       String[]  8 items: '','A','u','s','t','i','n',''
PowerShell convert a string to a char array with ToCharArray, char cast and split
ToCharArray and [char[]] return 6 characters, while -split ” returns 8 strings (PowerShell 7)

Use ToCharArray() or [char[]] unless you specifically need strings. Microsoft documents the method under String.ToCharArray.

You don’t always need an array

A string can already be indexed like an array. Each position returns a single [char], and a range of positions returns several:

$state = 'Texas'

"First character:  $($state[0])"
"Last character:   $($state[-1])"
"Type of `$state[0]: $($state[0].GetType().Name)"
"Characters 1-3:   $($state[1..3] -join '')"

Output:

First character:  T
Last character:   s
Type of $state[0]: Char
Characters 1-3:   exa

Negative numbers count from the end, so [-1] is the last character. Getting a substring covers longer pieces of text.

Create a character array from a range

Cast a range of character codes to [char[]]. Codes 65 to 70 are A to F. For digits, take the codes of ‘0’ and ‘9’ and build the range between them:

$upper = [char[]](65..70)
"Letters from codes: $($upper -join ' ')"

$digits = [char[]]('0'[0]..'9'[0])
"Digits from codes:  $($digits -join ' ')"

Output:

Letters from codes: A B C D E F
Digits from codes:  0 1 2 3 4 5 6 7 8 9

Letter ranges work only in PowerShell 7

PowerShell 7 can make a range straight from two letters. Windows PowerShell 5.1 can’t, and fails trying to convert the letters to numbers:

$letters = 'a'..'f'
"Letters with 'a'..'f': $($letters -join ' ') ($($letters[0].GetType().Name))"

Output:

Letters with 'a'..'f': a b c d e f (Char)
try { $letters = 'a'..'f'; $letters -join ' ' }
catch { "Failed. Windows PowerShell 5.1 can't make a range from letters" }

Output:

Failed. Windows PowerShell 5.1 can't make a range from letters
PowerShell letter range fails in Windows PowerShell 5.1
‘a’..’f’ fails in Windows PowerShell 5.1, so use character codes there

Use the [char[]](65..70) form in scripts that must run in both versions.

Join characters back into a string

-join with nothing on the left glues the characters together. [string]::new() does the same, and [array]::Reverse lets you flip the order first:

$chars = 'Denver'.ToCharArray()

"-join:              $(-join $chars)"
"[string]::new():    $([string]::new($chars))"
[array]::Reverse($chars)
"Reversed:           $(-join $chars)"

Output:

-join:              Denver
[string]::new():    Denver
Reversed:           revneD

[array]::Reverse changes the array in place and returns nothing, so call it on its own line. Converting an array to a string covers separators.

Filter characters by type

The [char] type has tests like IsDigit, IsLetter and IsUpper. Use them with Where-Object to keep only the characters you want:

$orderId = 'TX-2026-A58213'
$chars = $orderId.ToCharArray()

"Digits only:   $(-join ($chars | Where-Object { [char]::IsDigit($_) }))"
"Letters only:  $(-join ($chars | Where-Object { [char]::IsLetter($_) }))"
"Upper case:    $(($chars | Where-Object { [char]::IsUpper($_) }).Count) letters"

Output:

Digits only:   202658213
Letters only:  TXA
Upper case:    3 letters
PowerShell filter a char array to digits or letters
Digits, letters and the count of capitals, pulled out of an order ID (PowerShell 7)

Microsoft lists every test, like IsWhiteSpace and IsPunctuation, in the Char reference.

Count how often each character appears

Group-Object counts the characters for you. Add -CaseSensitive so M and m are counted separately:

'Mississippi'.ToCharArray() |
    Group-Object -CaseSensitive |
    Sort-Object -Property Count, Name -Descending |
    ForEach-Object { '{0}: {1}' -f $_.Name, $_.Count }

Output:

s: 4
i: 4
p: 2
M: 1

Sort by Count to see the most common characters first.

Comparing characters ignores case

Like strings, characters compare without case using -eq. Use -ceq when case matters:

$c = 'Boston'[0]

"[char]'B' -eq 'b'  : $($c -eq 'b')"
"[char]'B' -ceq 'b' : $($c -ceq 'b')"
"'B' -eq [char]'B'  : $('B' -eq $c)"

Output:

[char]'B' -eq 'b'  : True
[char]'B' -ceq 'b' : False
'B' -eq [char]'B'  : True

Microsoft covers the range operator and the others in about_Operators.

Frequently Asked Questions

How do I convert a string to a character array in PowerShell?

Use 'Seattle'.ToCharArray() or [char[]]'Seattle'. Both return a Char[] array.

How do I create an array of letters from A to Z?

Use [char[]](65..90), which works in every version. In PowerShell 7, 'A'..'Z' also works.

How do I convert a character array back to a string?

Use -join $chars or [string]::new($chars).

Why does -split ” give me extra empty items?

It splits before the first and after the last character, which leaves an empty string at each end. Use ToCharArray() instead.

How do I get only the digits from a string?

Filter the characters: -join ($text.ToCharArray() | Where-Object { [char]::IsDigit($_) }).

More string and array guides: