Why the different behavior? Is it just an oversight, or is there some intentional behavior I am not understanding?

Because many years ago, someone decided that's how ArrayList should behave!

Add() returns the index at which the argument was inserted into the list, which may indeed be useful and makes sense.

With AddRange() on the other hand, it's not immediately clear why it should return anything, and if yes, what? The index of the first item in the input arguments? The last? Or should it return a variable-sized array with all the insert indices? That would be awkward! So whoever implemented ArrayList decided not to return anything at all.

In C# or VB.NET, for which ArrayList was initially designed, "polluting the pipeline" doesn't really exist as a concept, the runtime would simply omit copying the return value back to the caller if someone invokes .Add() without assigning to a variable.

The [void] here isn't required, but I wonder if it's just best practice to have it, depending of course on the answer above. Or am I missing something there too?

No, it's completely unnecessary. AddRange() is not magically one day gonna change to output anything.


If you don't ever need to know the insert index, use a [System.Collections.Generic.List[psobject]] instead:

$list = [System.Collections.Generic.List[psobject]]::new()

# this won't return anything, no need for `[void]`
$list.Add(123)

If for some reason you must use an ArrayList, you can "silence" it by overriding the Add() method:

function New-SilentArrayList {
  # Create a new ArrayList
  $newList = [System.Collections.ArrayList]::new()

  # Create a new `Add()` method, then return the list
  $newAdd  = @{
    InputObject = $newList
    MemberType = 'ScriptMethod' 
    Name = 'Add'
    Value = {param(this.AddRange(@($obj))}
  }
  Write-Output $( 
    Add-Member @newAdd -Force -PassThru
  ) -NoEnumerate
}

Now your ArrayList's Add() will never make a peep again!

PS C:\> $list = New-SilentArrayList
PS C:\> $list.Add(123)
PS C:\> $list
123
Answer from Mathias R. Jessen on Stack Overflow
🌐
Wordpress
powershelldevtools.wordpress.com › category › powershell-code › items-addrange
Items.AddRange – PowerShell In GUI Blog
$comboBox1.AutoCompleteCustomSource.Add("System.Windows.Forms"); $comboBox1.AutoCompleteCustomSource.AddRange(("System.Data", "Microsoft")); $comboBox1.AutoCompleteMode = [System.Windows.Forms.AutoCompleteMode]::SuggestAppend; $comboBox1.AutoCompleteSource = [System.Windows.Forms.AutoCompleteSource]::CustomSource;
Top answer
1 of 2
3

Why the different behavior? Is it just an oversight, or is there some intentional behavior I am not understanding?

Because many years ago, someone decided that's how ArrayList should behave!

Add() returns the index at which the argument was inserted into the list, which may indeed be useful and makes sense.

With AddRange() on the other hand, it's not immediately clear why it should return anything, and if yes, what? The index of the first item in the input arguments? The last? Or should it return a variable-sized array with all the insert indices? That would be awkward! So whoever implemented ArrayList decided not to return anything at all.

In C# or VB.NET, for which ArrayList was initially designed, "polluting the pipeline" doesn't really exist as a concept, the runtime would simply omit copying the return value back to the caller if someone invokes .Add() without assigning to a variable.

The [void] here isn't required, but I wonder if it's just best practice to have it, depending of course on the answer above. Or am I missing something there too?

No, it's completely unnecessary. AddRange() is not magically one day gonna change to output anything.


If you don't ever need to know the insert index, use a [System.Collections.Generic.List[psobject]] instead:

$list = [System.Collections.Generic.List[psobject]]::new()

# this won't return anything, no need for `[void]`
$list.Add(123)

If for some reason you must use an ArrayList, you can "silence" it by overriding the Add() method:

function New-SilentArrayList {
  # Create a new ArrayList
  $newList = [System.Collections.ArrayList]::new()

  # Create a new `Add()` method, then return the list
  $newAdd  = @{
    InputObject = $newList
    MemberType = 'ScriptMethod' 
    Name = 'Add'
    Value = {param(this.AddRange(@($obj))}
  }
  Write-Output $( 
    Add-Member @newAdd -Force -PassThru
  ) -NoEnumerate
}

Now your ArrayList's Add() will never make a peep again!

PS C:\> $list = New-SilentArrayList
PS C:\> $list.Add(123)
PS C:\> $list
123
2 of 2
1

Apparently I didn't quiet understand where you where heading to.
"Add pollutes the pipeline", at a second thought is a correct statement but .Net methods like $variable.Add('String') do not use the PowerShell pipeline by itself (until the moment you output the array using the Write-Output command which is the default command if you do not assign it to a variable).

The Write-Output cmdlet is typically used in scripts to display strings and other objects on the console. However, because the default behavior is to display the objects at the end of a pipeline, it is generally not necessary to use the cmdlet.

The point is that Add method of ArrayList returns a [Int32] "The ArrayList index at which the value has been added" and the AddRange doesn't return anything. Meaning if you don't assign the results to something else (which includes $Null = $test.Add('Single')) it will indeed be output to the PowerShell Pipeline.
Instead you might also consider to use the Add method of the List class which also doesn't return anything, see also: ArrayList vs List<> in C#.
But in general, I recommend to use native PowerShell commands that do use the Pipeline
(I can't give you a good example as it is not clear what output you expect but I noticed another question you removed and from that question, I presume that this Why should I avoid using the increase assignment operator (+=) to create a collection answer might help you further)

🌐
SAPIEN Technologies
sapien.com › community forums › community scripting answers › powershell guis
addrange method doesnt seem to support single items - Page 2 - SAPIEN Forums
April 30, 2015 - $obj = @(New-Object PsObject -Property @{ Name = 'John'; Age = 12 }) $listbox1.Items.AddRange($obj) $listbox1.DisplayMember='Name' $obj += New-Object PsObject -Property @{ Name = 'Mary'; Age = 72 } $obj += New-Object PsObject -Property @{ Name = 'Tom'; Age = 22 } $listbox2.Items.AddRange($obj) $listbox2.DisplayMember='Name' Study the attached file and see how AddRange works. ... Lembasts wrote:I should have known. It's the old powershell "scalar" issue.
🌐
Reddit
reddit.com › r/powershell › lists and functions
r/PowerShell on Reddit: Lists and Functions
August 10, 2021 -

I'm trying to call a function that will return a list of AD users. Here's what I have so far:

using namespace System.Collections.Generic;

function foo {
    $list = [List[object]]::new()
    $list.Add($(Get-ADUser -filter 'name -eq "bob"'))
    , $list
}

$userlist = [List[object]]::new()
$userlist.Add($(foo))

Edit: fixed the code I had. It wasn't correct, although I am still getting the error

Cannot find an overload for "Add" and the argument count: "1".

Edit 2: Changed .Add to .AddRange and added conversion per u/y_Sensei. I may or may not need more caffeine, so hopefully I didn't botch anything

using namespace System.Collections.Generic;

function foo {
    $list = [List[hashtable]]::new()
    $list.AddRange([List[hashtable]]@($(Get-ADUser -filter 'name -eq "bob"')))
    , $list
}
$userlist = [List[hashtable]]::new()
$userlist.AddRange([List[hashtable]]@($(foo)))

🌐
Vexx32
vexx32.github.io › 2020 › 02 › 15 › Building-Arrays-Collections
Building Arrays and Collections in PowerShell
$List = [System.Collections.Generic.List[object]]@(1..5) $List.AddRange(5..10) # Note - for strongly-typed lists you will need to cast the array you're adding to the relevant array type explicitly: $List = [System.Collections.Generic.List[int]]@(1..5) $List.AddRange([int[]](5..10)) Taking all the above into account, we can establish some broad recommendations when handling collections of items in PowerShell.
🌐
PowerShell Test-Path
powershellfaqs.com › powershell-append-to-array
PowerShell Append to Array [With Examples]
January 27, 2024 - $newItems = 6, 7, 8 [array]$arrayList.AddRange($newItems) Note: Appending to arrays in PowerShell using the += operator is simple but not always efficient, especially for large arrays. This is because each time you append an item using +=, PowerShell creates a new array with the additional item, then replaces the old array with the new one.
🌐
Java2Blog
java2blog.com › home › powershell › powershell array › powershell add array to array
PowerShell Add Array to Array [5 Ways] - Java2Blog
May 27, 2023 - The AddRange() is used to add the elements of $array1 to $newArray, and the InsertRange() is used to insert the elements of $array2 after the elements of $array1. Finally, the contents of the $newArray variable are printed to the console.
Find elsewhere
🌐
PowerShell Forums
forums.powershell.org › t › array-method-question › 25279
Array method question - PowerShell Forums
January 7, 2025 - I have a script where I initialise an array thus: $global:SearchResults = [System.Collections.Generic.List[object]]::new() Then through the script I wanted accumulate search results by doing: $global:SearchResults.addrange(@($CurrentSearch)) The weird thing is that the first time the above line is executed, it correctly adds the objects to the global variable.
🌐
Reddit
reddit.com › r/powershell › which method is faster? $variable.add() or +=
r/PowerShell on Reddit: Which method is faster? $variable.Add() or +=
April 8, 2022 -

Context: I am using runspaces to speed up larger permission reports. This is the last addition to the array/list so whether it becomes fixed or not is not important. I am just worried about speed mostly and efficiency next.

Data can be 5 objects total up to 9 million objects (because who deletes old data?)

.Add Method:

ForEach ($t in $Threads) {
     Foreach ($Perm in ($t.Runspace.EndInvoke($t.Invoker))) {
          $ThreadResults.Add($Perm)
     }
     $t.Runspace.Dispose()
}

+= Method:

$ThreadResults += ForEach ($t in $Threads) {
     $t.Runspace.EndInvoke($t.Invoker)
     $t.Runspace.Dispose()
}
🌐
Learning in the Open
learningintheopen.org › category › technical › microsoft › powershell › collections › system-collections-arraylist-powershell-collection › addrange-powershell-collection-system-collections-arraylist
AddRange ( PowerShell – Collection – System.Collections.ArrayList ) | Learning in the Open
July 8, 2021 - HomeTechnicalMicrosoftPowerShell ( Microsoft )Collection ( Microsoft - PowerShell )System.Collections.ArrayList ( PowerShell - Collection )AddRange ( PowerShell – Collection – System.Collections.ArrayList )
🌐
Enterprise DNA
blog.enterprisedna.co › powershell-arraylist
Powershell ArrayList: How to Build Better Scripts – Master Data Skills + AI
$Array = 1, 2, 3, 4, 5 $ArrayList = New-Object System.Collections.ArrayList $ArrayList.AddRange($Array) ... When using ArrayLists, it is essential to understand the data types of the items stored within them. You can use the GetType() method in PowerShell to retrieve the data type of an object or element stored in the ArrayList.
🌐
SharePoint Diary
sharepointdiary.com › sharepoint diary › powershell › powershell tutorials › powershell arraylist – a beginners guide!
PowerShell ArrayList - A Beginners Guide! - SharePoint Diary
September 30, 2025 - # Create Arrays $Fruits = @("Banana", "Cherry", "Date") # Add Array List elements from the standard array $ArrayList.AddRange($Fruits)
🌐
GitHub
github.com › NickolajA › PowerShell › blob › master › ConfigMgr › Tools › Set-OSDOULocationPrompt.ps1
PowerShell/ConfigMgr/Tools/Set-OSDOULocationPrompt.ps1 at master · NickolajA/PowerShell
$Form.Controls.AddRange(@($RBOption1, $RBOption2, $ComboBox, $Button, $GBSystem, $GBLocation)) $ComboBox.Items.AddRange($LocationList) $Form.Add_Shown({$Form.Activate()}) [void]$Form.ShowDialog() } · function Set-OULocation { param( [parameter(Mandatory=$true)] $Location ·
Author   NickolajA
🌐
GitHub
github.com › PowerShell › PowerShell › issues › 11984
add -range parameter to switch statement · Issue #11984 · PowerShell/PowerShell
steps to reproduce switch -range (1..10) { (1..3) { Write-Host $_ -ForegroundColor Yellow} (4..7) {Write-Host $_ -ForegroundColor red} (8..10) {Write-Host $_ -ForegroundColor cyan} } with this switch we can use range operator
🌐
SharePoint Diary
sharepointdiary.com › sharepoint diary › powershell › how to add items to an array in powershell?
How to Add Items to an Array in PowerShell? - SharePoint Diary
September 20, 2025 - # Create a new generic list of integers $list = [System.Collections.Generic.List[int]]::new() # Add a Single item $list.Add(10) # Many items $list.AddRange([int[]](20,30,40)) # Insert at a position $list.Insert(0, 5) # now 5, 10,25,20,30,40 # Remove By value (first match) $list.Remove(10) | Out-Null # Remove By index $list.RemoveAt(1) # Clear all $list.Clear() The += operator is incredibly simple and convenient, but it’s crucial to understand what’s happening behind the scenes. When you use +=, PowerShell isn’t just “adding” a new item to the existing array.
🌐
PowerShell Forums
forums.powershell.org › powershell help
Adding arrays to arraylists - PowerShell Help - PowerShell Forums
July 11, 2022 - I have an object which is of type {system.collections.arraylist] To add a single element I can use the Add method but to add an array I have to use the ‘+=’ method. Does anyone have a technical explanation for this as ‘+=’ doesnt seem to be in the microsoft doco below: I am also assuming ...
🌐
Narkive
microsoft.public.windows.powershell.narkive.com › 3qhHEYad › v2-ctp3-how-to-use-a-generic-list-constructor
V2 CTP3: How to use a generic List constructor
Post by Shay Levy [MVP] --- Shay Levy Windows PowerShell MVP http://blogs.microsoft.co.il/blogs/ScriptFanatic PowerShell Toolbar: http://tinyurl.com/PSToolbar CH> I want to use the constructor of System.Collections.Generic.List<T> CH> CH> $list = New-Object System.Collections.Generic.List[int] CH> ([int[]]$array) CH> CH> New-Object : Cannot find an overload for "List`1" and the argument CH> count: "3". CH> At line:1 char:19 CH> + $list = New-Object <<<< System.Collections.Generic.List[int] CH> ([int[]]$array) CH> + CategoryInfo : InvalidOperation: (:) [New-Object], CH> MethodException CH> ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewOb CH> jectCommand CH> CH> $list = New-Object System.Collections.Generic.List[int] CH> $list.AddRange([int[]]$array) CH> CH> Is there any way to do this in one line using the specified CH> constructor?