Yes, you create an empty array then use it to initialize the variable. Two other ways (System not needed as its namespace is already loaded): [Collections.ArrayList]$list = @() $list = [Collections.ArrayList]::new() New-Object is useful when you need -ComObject, or to dynamically create a type (typename stored as a string that you may not know when writing). It is the 'older' method before powershell had classes built-in. Also, if you create an 'untyped' variable from a cast, you can change its type later on. The first example I posted enforces the type for that variable, it can only be an arraylist. I recommend using the generic types where you can specify the type: [Collections.Generic.List[String]]$list = @() $list = [Collections.Generic.List[Int]]::new() Also save some typing and use a namespace: using namespace System.Collections.Generic [List[String]]$list = @() $list = [List[Int]]::new() And for speed (enumeration access), if the items are unique, try a HashSet: using namespace System.Collections.Generic [HashSet[String]]$list = @() $list = [HashSet[Int]]::new() You should be measuring speed on insertion/removal and access for real world speed tests. And you'll definitely see different results when you go past milestones like 10, 1000, 10000 items (generics are tailored to large datasets). Answer from chris-a5 on reddit.com
🌐
Vexx32
vexx32.github.io › 2020 › 02 › 15 › Building-Arrays-Collections
Building Arrays and Collections in PowerShell
Partially as a result of that, arrays (and more specifically object[]) are the backbone of PowerShell scripting. In the vast majority of cases, you're going to be handling arrays unless you deliberately choose to use another type of collection to handle output.
🌐
Practical 365
practical365.com › home › powershell › practical powershell: crafting collections
Practical PowerShell: Crafting Collections | Practical365
June 3, 2025 - A collection is a set of zero, one, or more objects. Within PowerShell, there are two common collection types: arrays and hash tables. However, you can leverage other collection types because PowerShell is built on the .NET Framework.
Discussions

Two ways of creating a new System.Collections.ArrayList object, what's the difference?
Yes, you create an empty array then use it to initialize the variable. Two other ways (System not needed as its namespace is already loaded): [Collections.ArrayList]$list = @() $list = [Collections.ArrayList]::new() New-Object is useful when you need -ComObject, or to dynamically create a type (typename stored as a string that you may not know when writing). It is the 'older' method before powershell had classes built-in. Also, if you create an 'untyped' variable from a cast, you can change its type later on. The first example I posted enforces the type for that variable, it can only be an arraylist. I recommend using the generic types where you can specify the type: [Collections.Generic.List[String]]$list = @() $list = [Collections.Generic.List[Int]]::new() Also save some typing and use a namespace: using namespace System.Collections.Generic [List[String]]$list = @() $list = [List[Int]]::new() And for speed (enumeration access), if the items are unique, try a HashSet: using namespace System.Collections.Generic [HashSet[String]]$list = @() $list = [HashSet[Int]]::new() You should be measuring speed on insertion/removal and access for real world speed tests. And you'll definitely see different results when you go past milestones like 10, 1000, 10000 items (generics are tailored to large datasets). More on reddit.com
🌐 r/PowerShell
11
27
April 7, 2023
powershell - [System.Collections.Generic.List[string]] as return value - Stack Overflow
2 Custom type in Powershell with Generics Collection as a member More on stackoverflow.com
🌐 stackoverflow.com
arrays - How to write to Powershell collection - Stack Overflow
I want to add output from below command to some sort of array or collection: Get-MpThreatDetection | Where-Object {$_.InitialDetectionTime -ge $time} It could produce output of multiple detections... More on stackoverflow.com
🌐 stackoverflow.com
How to insert a value into a array
i am trying to insert the value into the first index of array tried to use $a.Insert(0,1) but give an error of MethodInvocationException: Exception calling "Insert" with "2" argument(s): "Collection was of a fixed size." i don’t know if this the right mehod or am i pass the wrong overload More on forums.powershell.org
🌐 forums.powershell.org
8
0
June 19, 2024
🌐
Microsoft Learn
learn.microsoft.com › en-us › powershell › scripting › lang-spec › chapter-04
Types - PowerShell | Microsoft Learn
The automatic variable $input is the enumerator for a collection delivered to a function from the pipeline. The automatic variable $switch is the enumerator created for any switch statement. The type of an enumerator is implementation defined; it has the following accessible members: In PowerShell, these members are defined in the interface System.IEnumerator, which is implemented by the types identified below.
🌐
Medium
medium.com › @oakhelloworld › powershell-collection-968226024f38
Powershell: Collection. PowerShell provides a variety of data… | by Oak HelloWorld | Medium
September 28, 2023 - Powershell: Collection PowerShell provides a variety of data structures and collections for working with data in your scripts. Here are some common collection types in PowerShell: 1. Arrays: Arrays …
🌐
Tachytelic
tachytelic.net › home › add items to a powershell array
Add items to a Powershell Array
September 4, 2019 - If you still require a standard PowerShell array you can do: ... Hope this helps. ... $array = [System.Collections.ArrayList]@() #Fill with a list of devices from a function earlier in script $array = get_alldevices #emtpy array $empty = [System.Collections.ArrayList]@()
🌐
Sciencelogic
docs.sciencelogic.com › 12-3-0 › Content › Web_Content_Dev_and_Integration › WMI_and_PowerShell_Dynamic_App_Development › wmi_powershell_collection_objects.htm
WMI and PowerShell Collection Objects
For example, suppose you have defined the following PowerShell request: Get-WmiObject Win32_DiskDrive | Select Partitions, DeviceID, Model, Size, Caption · This request returns the properties Partitions, DeviceID, Model, Size, and Caption. To store the values returned for each of the five properties, you would create five collection objects.
Find elsewhere
🌐
Red Gate Software
red-gate.com › home › powershell one-liners: collections, hashtables, arrays and strings
PowerShell One-Liners: Collections, Hashtables, Arrays and Strings | Simple Talk
January 23, 2019 - This is a multi-part series of PowerShell reference charts. Here you will details of the two fundamental data structures of PowerShell: the collection (array) and the hash table (dictionary), examining everything from creating, accessing, iterating, ordering, and selecting.
🌐
GitHub
github.com › jhochwald › PowerShell-collection
GitHub - jhochwald/PowerShell-collection: PowerShell Scripts, Tools, and Modules
A collection of PowerShell scripts, tooling, and some of my modules.
Starred by 304 users
Forked by 79 users
Languages   PowerShell 100.0% | PowerShell 100.0%
🌐
Reddit
reddit.com › r/powershell › two ways of creating a new system.collections.arraylist object, what's the difference?
r/PowerShell on Reddit: Two ways of creating a new System.Collections.ArrayList object, what's the difference?
April 7, 2023 -

I've come across two ways of creating a new System.Collections.ArrayList object:

$arrA = New-Object System.Collections.ArrayList
$arrB = [System.Collections.ArrayList]@() 

I have two questions:

  1. for arrB, if I'm reading this right, @() is creating an empty array and then it's being cast into [System.Collections.ArrayList]?

  2. Working with the created object is the same for me either way, but are there any differences I may be missing?

I made a quick test and casting was faster, but the difference is only noticeable when creating new arrays reaches the hundreds of thousands to millions (tested on an old A10-7870k). Doesn't really matter when I'm creating one array, but I thought it was mildly interesting.

$max = 100000
$ticksStart = (Get-Date).Ticks
for ($i = 0; $i -lt $max; $i++)
{
	$arrA = New-Object System.Collections.ArrayList
}
$ticksEnd = (Get-Date).Ticks
Write-Host 'arrA (ticks)	: ' ($ticksEnd - $ticksStart)

$ticksStart = (Get-Date).Ticks
for ($i = 0; $i -lt $max; $i++)
{
	$arrB = [System.Collections.ArrayList]@()
}
$ticksEnd = (Get-Date).Ticks
Write-Host  'arrB (ticks)	: ' ($ticksEnd - $ticksStart)
arrA (ticks)	:  64310000
arrB (ticks)	:  3170000
🌐
Microsoft Learn
learn.microsoft.com › en-us › powershell › scripting › learn › deep-dives › everything-about-arrays
Everything you wanted to know about arrays - PowerShell | Microsoft Learn
The foreach loop works well with collections. Using the syntax: foreach ( <variable> in <collection> ) ... I tend to forget about this one but it works well for simple operations. PowerShell allows you to call ForEach() on a collection.
Top answer
1 of 2
12

If you remove the array subexpression @(...) and just precede with a comma. The below code seems to work:

Copyfunction TestReturn {
    $returnList = New-Object System.Collections.Generic.List[string]
    $returnList.Add('Testing, one, two')

    return , $returnList
}

$testList = TestReturn
$testList.GetType().FullName

Note: technically this causes the return of [Object[]] with a single element that's of type [System.Collections.Generic.List[string]]. But again because of the implicit unrolling it sort of tricks PowerShell into typing as desired.

On your later point, the syntax [Type]$Var type constrains the variable. It's basically locking in the type for that variable. As such subsequent calls to .GetType() will return that type.

These issues are due to how PowerShell implicitly unrolls arrays on output. The typical solution, somewhat depending on the typing, is to precede the return with a , or ensure the array on the call side, either by type constraining the variable as shown in your questions, or wrapping or casting the return itself. The latter might look something like:

Copy$testList = [System.Collections.Generic.List[string]]TestReturn
$testList.GetType().FullName

To ensure an array when a scalar return is possible and assuming you haven't preceded the return statement with , , you can use the array subexpression on the call side:

Copy$testList = @( TestReturn )
$testList.GetType().FullName

I believe this answer deals with a similar issue

2 of 2
4

In addition to Steven's very helpful answer, you also have the option to use the [CmdletBinding()] attribute and then just call $PSCmdlet.WriteObject. By default it will preserve the type.

Copyfunction Test-ListOutput {
    [CmdletBinding()]
    Param ()
    Process {
        $List = New-Object -TypeName System.Collections.Generic.List[System.String]
        $List.Add("This is a string")
        $PSCmdlet.WriteObject($List)
    }
}
$List = Test-ListOutput
$List.GetType()
$List.GetType().FullName

For an array, you should specify the type.

Copyfunction Test-ArrayOutput {
    [CmdletBinding()]
    Param ()
    Process {
        [Int32[]]$IntArray = 1..5
        $PSCmdlet.WriteObject($IntArray)
    }
}
$Arr = Test-ArrayOutput
$Arr.GetType()
$Arr.GetType().FullName

By default the behaviour of PSCmdlet.WriteObject() is to not enumerate the collection ($false). If you set the value to $true you can see the behaviour in the Pipeline.

Copyfunction Test-ListOutput {
    [CmdletBinding()]
    Param ()
    Process {
        $List = New-Object -TypeName System.Collections.Generic.List[System.String]
        $List.Add("This is a string")
        $List.Add("This is another string")
        $List.Add("This is the final string")
        $PSCmdlet.WriteObject($List, $true)
    }
}

Test-ListOutput | % { $_.GetType() }

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object
True     True     String                                   System.Object
True     True     String                                   System.Object

(Test-ListOutput).GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array


# No boolean set defaults to $false
function Test-ListOutput {
    [CmdletBinding()]
    Param ()
    Process {
        $List = New-Object -TypeName System.Collections.Generic.List[System.String]
        $List.Add("This is a string")
        $List.Add("This is another string")
        $List.Add("This is the final string")
        $PSCmdlet.WriteObject($List)
    }
}

Test-ListOutput | % { $_.GetType() }

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     List`1                                   System.Object

(Test-ListOutput).GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     List`1                                   System.Object

Just wanted to add some information on what I usually use in functions and how to control the behaviour.

🌐
Stack Overflow
stackoverflow.com › questions › 76964534 › how-to-write-to-powershell-collection
arrays - How to write to Powershell collection - Stack Overflow
I want to add output from below command to some sort of array or collection: Get-MpThreatDetection | Where-Object {$_.InitialDetectionTime -ge $time} It could produce output of multiple detections...
🌐
IDERA
idera.com › home › using efficient lists in powershell
Using Efficient Lists in PowerShell | IDERA
April 22, 2025 - Learn how to handle dynamic lists efficiently in PowerShell using System. Collections.ArrayList and generic lists instead of default object.
🌐
ScriptRunner
scriptrunner.com › resources › powershell-tips › powershell-array-types
Exploring PowerShell Array Types: A Comprehensive Guide
May 22, 2025 - PS> $list = [System.Collections.Generic.List[string]]::new() PS> $list.IsFixedSize False · The example above can now be rewritten to avoid using +=. Keep in mind that this example is meant to illustrate the issue; with just 10 iterations, as shown here, you could likely get away with using +=. However, remember the examples from the previous section where += would hang Windows PowerShell.
🌐
PowerShell Forums
forums.powershell.org › powershell help
How to insert a value into a array - PowerShell Help - PowerShell Forums
June 19, 2024 - i am trying to insert the value into the first index of array tried to use $a.Insert(0,1) but give an error of MethodInvocationException: Exception calling "Insert" with "2" argument(s): "Collection was of a fixed size." i don’t know if this the right mehod or am i pass the wrong overload
🌐
SharePoint Diary
sharepointdiary.com › sharepoint diary › powershell › powershell tutorials › powershell arraylist – a beginners guide!
PowerShell ArrayList - A Beginners Guide! - SharePoint Diary
September 30, 2025 - However, standard PowerShell arrays have limitations – they are fixed-sized and don’t provide many helpful methods to manipulate the array contents. This is where PowerShell ArrayLists come in. The ArrayList is one of the most useful collection types in PowerShell.
🌐
PowerShell Gallery
powershellgallery.com
PowerShell Gallery | Home
The central repository for sharing and acquiring PowerShell code including PowerShell modules, scripts, and DSC resources.
🌐
Jonathanmedd
jonathanmedd.net › 2014 › 01 › adding-and-removing-items-from-a-powershell-array.html
Adding and Removing Items from a PowerShell Array - Jonathan Medd's Blog
Taking your initial array you can convert it to a System.Collections.ObjectModel.Collection`1 like this, which may be easier to remember than using the full type name of either a collection or array list:
🌐
| How
pipe.how › new-array
PowerShell Collections: Array | How
December 19, 2019 - Arrays start at 0, so the first element of a collection is referred to by appending [0]. PowerShell has countless tools to work with arrays and other types of collections, such as loops, the pipeline and all of the different methods that come with the .NET classes.
🌐
Varonis
varonis.com › blog › powershell-array
PowerShell Array Guide: How to Use and Create
June 9, 2022 - As we’ve said above, adding items to arrays can be a hassle. However, there is a different type of collection – ArrayList – that handles this more elegantly.