Arrays are a fundamental data structure in most scripting and programming languages because they enable you to store, retrieve and manipulate a collection of items of various data types. Understanding arrays will enhance your ability to automate tasks using PowerShell.
An array is a data structure that can hold more than one value at a time. Think of it as a collection or a list of items of the same or different data types. Arrays are used in many scripting and programming languages, including Windows PowerShell.
Let’s delve into how to create and use an array in PowerShell.

Like other programming languages, arrays provide a simple way to store a list of items in PowerShell. 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 ArrayLists come in. The ArrayList is one of the most useful collection types in PowerShell. It provides a dynamic array that can grow and shrink as needed. ArrayLists make it easy to add, remove, sort, and update items in the collection.
In this post, you will learn how to:
- Create ArrayLists in PowerShell
- Add, insert, and remove items from an ArrayList
- Resize ArrayLists dynamically
- Sort and reverse ArrayLists
- Access items by index
- Concatenate multiple ArrayLists
- Convert between ArrayList and arrays
- Search for items in an ArrayList
In this comprehensive guide, we will delve into the depths of the PowerShell ArrayList, from creation to manipulation, uncovering its features and benefits, troubleshooting common errors, and sharing tips to optimize your script performance.
PowerShell provides a variety of data structures and collections for working with data in your scripts. Here are some common collection types in PowerShell:
3. Lists: Lists are similar to arrays but are more flexible because they dynamically resize as you add or remove elements. You can create lists using the `System.Collections.Generic.List` class.
$myQueue = New-Object System.Collections.Queue
$myQueue.Enqueue(“Task 1”)
$myQueue.Enqueue(“Task 2”)
$myStack = New-Object System.Collections.Stack
$myStack.Push(“Item 1”)
$myStack.Push(“Item 2”)
6. ArrayLists: `System.Collections.ArrayList` is similar to a generic list but allows you to store objects of various types in the same list.
$myArrayList = New-Object System.Collections.ArrayList
$myArrayList.Add(“String”)
$myArrayList.Add(123)
7. Dictionaries (Generic): PowerShell 7 introduced generic dictionaries, which are strongly typed and offer better performance when compared to hash tables.
8. Sorted Lists: Sorted lists maintain their elements in ascending order based on the keys. You can use `System.Collections.SortedList` for this purpose.
$mySortedList = New-Object System.Collections.SortedList
$mySortedList.Add(“B”, “Banana”)
$mySortedList.Add(“A”, “Apple”)
These are some of the commonly used collection types in PowerShell. Depending on your specific requirements, you can choose the appropriate collection type to store and manipulate your data efficiently in your PowerShell scripts.
It sounds like what you are looking for is a Hashtable. Hashtables work on a Key = Value basis, so you would choose or generate a key that you can reference later to retrieve the desired value. For example, let us say that you have Event1 saved in $Event1 and Event2 saved in $Event2. You could then form a hashtable like this:
$Events = @{ 'Event1' = $Event1 'Event2' = $Event2
}Then later you can recall a specific event by referencing the key like this:
$Events['Event1']Or, to just get the ThreatID of Event2 you could do this:
$Events['Event2'].ThreatIDThe keys can be anything, but remember that you need to have some way to reference that thing, so often times strings are the easiest way to do it.
Edit: In response to how you would add the same keys from multiple events to the same hashtable, the answer is you wouldn’t. The point is to have a unique identifier for the key, and the entire event as the value. There’s a couple ways to do that. The first way is to determine a unique value that each event has (in this example I will use DetectionID which is a unique identifier for each threat detection as noted here). You could do:
# Create empty hashtable
$Events =@{}
# Iterate through results, and add each event to the hashtable by DetectionID
Get-MpThreatDetection | Where-Object {$_.InitialDetectionTime -ge $time} | ForEach-Object{ $Events.Add($_.DetectionID, $_)
}Then later you can reference any event by the DetectionID. Like this:
PS C:\Windows\System32> $Events['009c9051-71cc-479f-ae8f-1bff94ad1e3b'].ThreatID
2147593794Alternatively you could just capture all events in a simple array, and then reference events by their index. That would look more like this:
PS C:\Windows\System32> $Events = Get-MpThreatDetection | Where-Object {$_.InitialDetectionTime -ge $time}
PS C:\Windows\System32> $Events[0].initialdetectiontime
23/08/2023 21:31:04
PS C:\Windows\System32> $Events[1].Resources
file:_D:\KeyGen\keygen.exeI am trying to register the PropertyChanged event for an Observable Collection in PowerShell, but no dice. This works just fine for the CollectionChanged event.
Register-ObjectEvent -InputObject $MyObservableCollection -EventName CollectionChanged -Action {Write-Host "Collection changed!"}`Whereas this does not work:
Register-ObjectEvent -InputObject $MyObservableCollection -EventName PropertyChanged -Action {Write-Host "Property changed!"}`Register-ObjectEvent : Cannot register for the specified event. An
event with the name ‘PropertyChanged’ does not exist.
asked Aug 19, 2023 at 8:41
Looks like you need to create a class that support the Property changed, so you could do something like this:
$PersonClass = @'
using System.ComponentModel;
public class Person : INotifyPropertyChanged
{ public event PropertyChangedEventHandler PropertyChanged; private string _Name; public string Name { get { return _Name; } set { _Name = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Name")); } } private string _Age; public string Age { get { return _Age; } set { _Age = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Age")); } } private string _Country; public string Country { get { return _Country; } set { _Country = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Country")); } }
}
'@
Add-Type -TypeDefinition $PersonClass -Language 'CSharp'
$NewPerson = [Person]::New()
$MyObservableCollection = New-Object -TypeName System.Collections.ObjectModel.ObservableCollection[Person]
Register-ObjectEvent -InputObject $NewPerson -EventName PropertyChanged -Action {Write-Host "PropertyChanged on item"}
Register-ObjectEvent -InputObject $MyObservableCollection -EventName CollectionChanged -Action {Write-Host "Item added or removed"}
$MyObservableCollection.Add($NewPerson)
$NewPerson.Name = 'Joe Bloggs'Here we are creating a Person class which stores the properties of a person like Name, Age and country, each with a PopertyChangedEventHandler. Once you have that its then creating an observable arraylist so you can add/remove individual Persons from the list (which will trigger the CollectionChanged event).
answered Aug 19, 2023 at 9:54
1 silver badge7 bronze badges
In the digital age, data privacy and security have become paramount. As Windows 10 has grown in popularity, so too have concerns about its data collection features. For IT professionals and Managed Service Providers (MSPs), understanding and controlling these features is crucial. This article delves into a PowerShell script designed to enable or disable Windows 10’s data collection capabilities.
Background
The Script
#Requires -Version 5.1
<#
.SYNOPSIS Enables or Disabled Windows 10 Linguistic Data Collection, Advertising ID, and Telemetry
.DESCRIPTION Enables or Disabled Windows 10 Linguistic Data Collection, Advertising ID, and Telemetry
.EXAMPLE No Params needed to Disable Windows 10 Linguistic Data Collection, Advertising ID, and Telemetry
.EXAMPLE -Enable Enables Linguistic Data Collection, Advertising ID, and Telemetry
.EXAMPLE PS C:> Set-Windows10KeyLogger.ps1 Disables Windows 10 Linguistic Data Collection, Advertising ID, and Telemetry
.EXAMPLE PS C:> Set-Windows10KeyLogger.ps1 -Enable Enables Windows 10 Linguistic Data Collection, Advertising ID, and Telemetry
.OUTPUTS None
.NOTES Minimum OS Architecture Supported: Windows 10 Release Notes: Initial Release
By using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at https://www.ninjaone.com/terms-of-use. Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms. Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party. Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library or website belonging to or under the control of any other software provider. Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations. Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks. Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script. EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).
.COMPONENT OSSecurity
#>
[CmdletBinding()]
param ( [Parameter()] [Switch] $Enable
)
begin { function Test-IsElevated { $id = [System.Security.Principal.WindowsIdentity]::GetCurrent() $p = New-Object System.Security.Principal.WindowsPrincipal($id) if ($p.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)) { Write-Output $true } else { Write-Output $false } } function Set-ItemProp { param ( $Path, $Name, $Value, [ValidateSet('DWord', 'QWord', 'String', 'ExpandedString', 'Binary', 'MultiString', 'Unknown')] $PropertyType = 'DWord' ) New-Item -Path $Path -Force | Out-Null if ((Get-ItemProperty -Path $Path -Name $Name -ErrorAction SilentlyContinue)) { Set-ItemProperty -Path $Path -Name $Name -Value $Value -Force -Confirm:$false | Out-Null } else { New-ItemProperty -Path $Path -Name $Name -Value $Value -PropertyType $PropertyType -Force -Confirm:$false | Out-Null } } $Type = "DWORD"
}
process { if (-not (Test-IsElevated)) { Write-Error -Message "Access Denied. Please run with Administrator privileges." exit 1 } $Value = if ($PSBoundParameters.ContainsKey("Enable") -and $Enable) { 1 }else { 0 } try { @( # Linguistic Data Collection [PSCustomObject]@{ Path = "HKLM:SOFTWAREMicrosoftWindowsCurrentVersionPoliciesTextInput" Name = "AllowLinguisticDataCollection" } # Advertising ID [PSCustomObject]@{ Path = "HKLM:SOFTWAREMicrosoftWindowsCurrentVersionAdvertisingInfo" Name = "Enabled" } # Telemetry [PSCustomObject]@{ Path = "HKLM:SOFTWAREPoliciesMicrosoftWindowsDataCollection" Name = "AllowTelemetry" } ) | ForEach-Object { Set-ItemProp -Path $_.Path -Name $_.Name -Value $Value -PropertyType $Type Write-Host "$($_.Path)$($_.Name) set to $(Get-ItemPropertyValue -Path $_.Path -Name $_.Name)" } if ($PSBoundParameters.ContainsKey("Enable") -and $Enable) { Write-Host "Enabling DiagTrack Services" Get-Service -Name DiagTrack | Set-Service -StartupType Automatic | Start-Service } else { Write-Host "Disabling DiagTrack Services" Get-Service -Name DiagTrack | Set-Service -StartupType Disabled | Stop-Service } Write-Host "DiagTrack Service status: $(Get-Service -Name DiagTrack | Select-Object -Property Status -ExpandProperty Status)" Write-Host "DiagTrack Service is set to: $(Get-Service -Name dmwappushservice | Select-Object -Property StartType -ExpandProperty StartType)" if ($PSBoundParameters.ContainsKey("Enable") -and $Enable) { Get-Service -Name dmwappushservice | Set-Service -StartupType Manual } else { Get-Service -Name dmwappushservice | Set-Service -StartupType Disabled | Stop-Service } Write-Host "dmwappushservice Service status: $(Get-Service -Name dmwappushservice | Select-Object -Property Status -ExpandProperty Status)" Write-Host "dmwappushservice Service is set to: $(Get-Service -Name dmwappushservice | Select-Object -Property StartType -ExpandProperty StartType)" $tasks = "SmartScreenSpecific", "ProgramDataUpdater", "Microsoft Compatibility Appraiser", "AitAgent", "Proxy", "Consolidator", "KernelCeipTask", "BthSQM", "CreateObjectTask", "WinSAT", #"Microsoft-Windows-DiskDiagnosticDataCollector", # This is disabled by default "GatherNetworkInfo", "FamilySafetyMonitor", "FamilySafetyRefresh", "SQM data sender", "OfficeTelemetryAgentFallBack", "OfficeTelemetryAgentLogOn" if ($PSBoundParameters.ContainsKey("Enable") -and $Enable) { Write-Host "Enabling telemetry scheduled tasks" $tasks | ForEach-Object { Write-Host "Enabling $_ Scheduled Task" # Note: ErrorAction set to SilentlyContinue so as to skip over any missing tasks. Enable-ScheduledTask will still error if it can't be enabled. Get-ScheduledTask -TaskName $_ -ErrorAction SilentlyContinue | Enable-ScheduledTask $State = Get-ScheduledTask -TaskName $_ -ErrorAction SilentlyContinue | Select-Object State -ExpandProperty State Write-Host "Scheduled Task: $_ is $State" } } else { Write-Host "Disabling telemetry scheduled tasks" $tasks | ForEach-Object { Write-Host "Disabling $_ Scheduled Task" # Note: ErrorAction set to SilentlyContinue so as to skip over any missing tasks. Disable-ScheduledTask will still error if it can't be disabled. Get-ScheduledTask -TaskName $_ -ErrorAction SilentlyContinue | Disable-ScheduledTask $State = Get-ScheduledTask -TaskName $_ -ErrorAction SilentlyContinue | Select-Object State -ExpandProperty State Write-Host "Scheduled Task: $_ is $State" } } } catch { Write-Error $_ exit 1 } gpupdate.exe /force exit 0
}
end {}Access 300+ scripts in the NinjaOne Dojo
Detailed Breakdown
The script is a PowerShell cmdlet that toggles Windows 10’s linguistic data collection, advertising ID, and telemetry. Here’s a step-by-step breakdown:
- Prerequisites: The script requires PowerShell version 5.1.
- Parameters: The script accepts an optional -Enable switch. If provided, it enables the data collection features; otherwise, it disables them.
- Functions:
- Test-IsElevated: Checks if the script is running with administrator privileges.
- Set-ItemProp: Sets or creates a registry key value.
- Process:
- First, the script checks for administrator privileges. If not present, it exits.
- It then determines whether to enable or disable the features based on the -Enable switch.
- The script modifies specific registry keys corresponding to the linguistic data collection, advertising ID, and telemetry.
- It also manages the DiagTrack and dmwappushservice services, which are related to telemetry.
- Finally, it toggles various telemetry-related scheduled tasks.
- Execution: The script concludes by forcing a group policy update.
Potential Use Cases
Imagine an MSP managing IT for a healthcare provider. Due to HIPAA regulations, they need to ensure minimal data leakage. Using this script, the MSP can quickly disable all data collection features on all Windows 10 machines in the network, ensuring compliance and enhancing patient data privacy.
Comparisons
While there are GUI-based tools and manual methods to toggle these settings, this script offers a more efficient, repeatable, and scalable solution. Manual methods can be time-consuming and prone to errors, especially across multiple machines. GUI tools might not offer the granularity or automation capabilities that a PowerShell script does.
FAQs
- Can I run this script on older Windows versions?
No, this script is designed specifically for Windows 10. - Do I need administrator privileges to run the script?
Yes, the script requires administrator rights to modify registry keys and manage services.
Implications
Using this script can significantly enhance data privacy, especially in sectors with strict regulations. However, disabling some features might limit certain functionalities or feedback mechanisms in Windows 10. IT professionals should weigh the benefits against potential limitations.
Recommendations
- Always backup registry settings before making changes.
- Test the script in a controlled environment before deploying it widely.
- Regularly review and update scripts to accommodate any changes in future Windows 10 updates.
Final Thoughts
For IT professionals and MSPs, tools like NinjaOne can be invaluable in managing and monitoring IT environments. When combined with scripts like the one discussed, they can ensure a secure, compliant, and efficient IT infrastructure. As Windows 10 data collection features evolve, having a robust toolset and knowledge base will be essential for success.
Access and Retrieve Elements
To get the number of elements in ArrayList:
To retrieve an element by index:
$item1 = $Arraylist[0] $item2 = $Arraylist[1]
You can access elements just like a standard PowerShell array.
To retrieve the last element:
$LastItem = $ArrayList[-1]
Loop Through ArrayList with Foreach
To process all elements in ArrayList, use Foreach:
ForEach ($Element in $ArrayList) { # Do something with $Element Write-Output $Element
}This iterates through each element sequentially. You can also use a for loop with Count:
For($i=0; $i -lt $Arraylist.Count; $i++) { # Do something with $element $element = $arraylist[$i] Write-host $Element
}Here is another form:
$ArrayList | ForEach-Object { Write-Host $_
}Creating an Empty Array
$array3 = @() $array3.GetType()

Clearing an Array
There is no defined way to delete an array, but there are several ways to get rid of the contents of an array (clear it). One is to assign the variable $null to the array:
$array7 = $null $array7
Here is another way to clear an array:
$array = @("element1", "element2", "element3")
$array = @()Here is how to clear an ArrayList:
$arrayList = New-Object System.Collections.ArrayList
$arrayList.Add("element1")
$arrayList.Add("element2")
$arrayList.Clear()Creating a Multidimensional Array (Matrix)
By nesting arrays using commas, you can create a structured arrangement of data in rows or columns. Here we create a 3×3 matrix:
Removing an Item from an Array
Now let’s use an ArrayList to remove an item from an array. First let’s create an array.
$array5 = "one", "two", "three", "four", "five" $array5.gettype()
Now we will add it to an ArrayList so we can easily modify it.
[System.Collections.ArrayList]$ArrayList1 = $array5 $ArrayList1.GetType()
We will then use the .Remove command.
$ArrayList1.Remove("three")
Creating an Array with Just One Element
If you put just one value in a variable, then PowerShell will not create an array. To confirm this, let’s use two scripts and output their data types.
First, we will create an array in PowerShell with five elements:
$array = @(1, 2, 3, 4, 5) $array1.GetType()
Now let’s try to use a similar script to create an array with just one element:
$array1 = 1 $array1.GetType()
As you can see from the output below, PowerShell created an array (System.Array) for the first example script but not the second.
This behavior is particularly concerning if you want to create an array by retrieving objects by executing a particular command, since you do not know in advance how many objects will be returned in the results.
To get around this issue, you can use the , (comma) operator. If a comma is used as a binary operator, then a normal array is created; if it is used as a unary operator, the array has just one element.
For example, here is how we can get an array consisting of one element:
$array1 = ,1 $array1.GetType()
We can confirm the creation of the array with the output shown below:
Real-world applications of PowerShell ArrayList
PowerShell ArrayList can be used in a variety of real-world scenarios, such as:
- Log file processing: ArrayList can be used to store and process log file data, allowing you to filter, sort, and analyze log entries efficiently.
- Inventory management: PowerShell ArrayList can be utilized to store and manage inventory data, such as computer names, IP addresses, and hardware details.
- Data processing: ArrayList can be employed in data processing tasks, such as parsing CSV files, processing XML data, or handling JSON objects.
- Script optimization: As mentioned earlier, using ArrayList can help improve the performance of your PowerShell scripts, making it a valuable tool for script optimization tasks.
- Storing ordered collections like lists of servers, users, etc., that change frequently
- Collecting output from loops and pipelines before exporting to CSV
Creating a Strongly Typed Array
By default, the elements of an array can have different data types. But you can also create arrays that accept only values of a single designated type. Trying to add a value of a different type will produce an error. Here is how to create the most common strongly typed arrays:
[int[]]$intArray = 1, 2, 3
[string[]]$strArray = "one", "two", "three"
[datetime[]]$dateArray = (Get-Date), (Get-Date).AddDays(1)
Common errors and troubleshooting in PowerShell ArrayList
As you work with PowerShell ArrayList, you may encounter some common errors or issues. In this section, we will discuss some of these errors and provide tips for troubleshooting and resolving them.
- Index out of range: This error occurs when you try to access or modify an element at an index that does not exist in the ArrayList. To avoid this error, always ensure that the index you are using is within the bounds of the ArrayList. You can use the
Countproperty to get the number of elements in the ArrayList. - InvalidCastException: This error occurs when you try to convert an element in the ArrayList to an incompatible data type. To fix this error, ensure that you are using the correct data type for the element in question or use the appropriate conversion methods provided by PowerShell and the .NET Framework.
- Adding elements of different data types: While it is possible to store elements of different data types in an ArrayList, doing so can lead to unexpected behavior and performance issues. To avoid this, try to use a consistent data type for all elements in the ArrayList or consider using a different collection type, such as a Hashtable or a custom object.
Creating an ArrayList in PowerShell
$arrayList = New-Object -TypeName System.Collections.ArrayList
This initializes an empty ArrayList. Alternatively, you can use type accelerators to create a new array list variable:
$ArrayList = [System.Collections.ArrayList]::new()
Initialize ArrayList with a capacity: When creating an ArrayList, it’s a good idea to initialize it with a capacity close to the expected number of elements. This can help reduce the number of memory allocations and improve the performance of your script. For example, if you expect your ArrayList to have approximately 100 elements, you can create it like this:
$ArrayList = New-Object -TypeName System.Collections.ArrayList -ArgumentList 100
$ArrayList = [System.Collections.ArrayList]@("Banana", "Cherry", "Apple","Orange")Both methods will create a new ArrayList object, which you can then use to store and manipulate data in your PowerShell script.

Unlike the default array, the ArrayList can contain a mix of data types. E.g., let’s say you want to create an “Employee” ArrayList with Employee Number, Employee Name, and Date of Join values:
$Employee = New-Object System.Collections.ArrayList
$Employee.Add(001)
$Employee.Add("Steve Johnson")
$Employee.Add([DateTime]"01/01/2021")Modifying ArrayList elements in PowerShell
Once you have an ArrayList in your PowerShell script, there are several methods available to manipulate and modify its elements. To change the value of an element in an ArrayList, you can use the set_Item() method or the array index notation. For example, to update the first element, you can use:
$ArrayList.set_Item(0, "Updated Element") #Another way $ArrayList[0] = "Updated Element".
We will explore more advanced manipulation techniques, such as sorting, reversing, and searching, in a later section of this article.
Converting PowerShell ArrayList to string
$string = $arrayList -join ', '
Or, using the String.Join() method:
$string = [System.String]::Join(', ', $arrayList)Both methods will create a new string containing the elements of the ArrayList, separated by the specified delimiter (a comma and a space in this case).
Join Multiple ArrayLists
To combine multiple ArrayLists:
$arraylist1 = [System.Collections.ArrayList]@(1, 2, 3) $arraylist2 = [System.Collections.ArrayList]@(4, 5, 6) $result = $arraylist1.Clone() $result.AddRange($arraylist2)
Clone() makes a copy before appending $arraylist2 to avoid modifying the original.
Filter ArrayList
You can filter elements in ArrayList using the Where method:
#Create a Array List with values: 1 to 10
$Values = 1..10
$ArrayList = New-Object -TypeName System.Collections.ArrayList
$ArrayList.AddRange($Values)
#Filter Array List
$Arraylist = $ArrayList.Where{$_ -ge 5}Alternatively, You can use the Where-Object cmdlet to Filter Array elements:
#Filter ArrayList
$MyArraylist = $ArrayList | Where-Object {$_ -ge 5}Using the Join Operator and the Split Operator
In PowerShell, the join operator is used to append an array of strings into a single string, optionally using a specified delimiter. Here is an example without a delimiter.
$array = "Power", "Shell" $joined = $array -join "" # Output: "PowerShell"
Here is what it would be with a delimiter:
The split operator essentially does the opposite of the join operator, as shown in the example below:
$string = "apple,banana,grape" $fruits = $string -split ","
Creating an ArrayList
For large arrays or frequent additions, use of += can be a performance concern, since every time use it, a new array is created, the old elements are copied over and the new element is added to the end. In those cases, you may want to use an ArrayList.
The size of an ArrayList is mutable, so you can add or remove items without having to recreate the entire collection. Like a standard array, an ArrayList can hold items of different data types.
Here is the cmdlet to create an ArrayList:
$array3 = New-Object System.Collections.ArrayList
Accessing Items using the Array Index
As with most programming languages, each individual item in a PowerShell array can be accessed by an index. The index of an array starts at zero, so in an array of three items, the first item is at index 0, the second is at index 1, and the third is at index 2.
To access items using the array index, you need to provide the index in square brackets after the array variable. Below is an example showing how to create an array show the second element:
$colors = "Red", "Green", "Blue", "Yellow" $secondColor = $colors[1] Write-Output $secondColor
You can access items from the end of an array by using a negative index. -1 refers to the last item, -2 refers to the second from the last item, etc.
Adding to an Array
The size of an array in PowerShell is immutable once it is defined. However, the operator += enables you to create a new array by appending items to an existing array — essentially creating a new combined array.
$array = @(1, 2, 3) $array += 4
PowerShell Import CSV to ArrayList
You can import a CSV file into an ArrayList using Import-Csv and a ForEach loop.
$csvData = Import-Csv -Path 'C:\Temp\Fruits.csv'
$ArrayList = New-Object System.Collections.ArrayList
ForEach ($row in $csvData) { $ArrayList.Add($row)
}Sorting, reversing, and searching PowerShell ArrayLists
PowerShell ArrayList provides several methods for manipulating and processing data, such as sorting, reversing, and searching.
$ArrayList.Sort() $ArrayList.Reverse()
This code will first sort the ArrayList in ascending order and then reverse the order to get the elements in descending order. The Sort-Object cmdlet also can be used for sorting elements in the array:
$SortedArrayList = $ArrayList | Sort-Object

if ($ArrayList.Contains("apple")) { Write-Host "ArrayList contains 'apple'"
}This code will check if the ArrayList contains the element “apple” and print a message if it does.
Reversing an Array
Here is an example of how to reverse the order of the elements in an array:
$numbers = 1..5 [Array]::Reverse($numbers)
Filtering an Array
We can use the Where-Object cmdlet to retrieve only the even numbers from an array:
$numbers = 1,2,3,4,5,6
$evenNumbers = $numbers | Where-Object { $_ % 2 -eq 0 }
$evenNumbers
Alternatively, we can use the .Where() method, which it does not require a pipeline:
$numbers = 1,2,3,4,5,6
$evenNumbers = $numbers.Where({ $_ % 2 -eq 0 })
$evenNumbersComparing, Grouping, Selecting and Sorting Arrays
Other useful PowerShell cmdlets for working with arrays include:
- Compare-Object — Compares two arrays and returns the differences.
- Group-Object — Groups array elements based on property values.
- Select-Object — Selects specified properties of an object or set of objects, and can also be used to select a specific number of elements from an array.
- Sort-Object — Used to sort arrays that contain only one data type, as shown below:
$array = @(3, 1, 4, 2) $sortedArray = $array | Sort-Object
Adding elements to PowerShell ArrayList
Once your ArrayList is created, Adding elements to a PowerShell ArrayList is easy, with the help of the built-in Add() method. This method allows you to add a single element to the end of the ArrayList:
Alternatively, you can use the AddRange() method to ArrayList with a set of initial values.
$Fruits = @("Banana", "Cherry", "Date")
$ArrayList.AddRange($Fruits)$initialValues = 1..5 $arrayList = New-Object -TypeName System.Collections.ArrayList $arrayList.AddRange($initialValues)
Here is another way to add multiple elements to an array list with the help of a Loop:
#Create a Array List
$ArrayList = New-Object System.Collections.ArrayList
#Add Elements to Array List
@(0..100).ForEach({$ArrayList.Add($_)})Additionally, the Insert() method can be used to insert an element at a specific index within the ArrayList:
$arrayList.Insert(0, "Plums")
This code will insert “Plums” at the beginning of the ArrayList (index 0). Keep in mind that the index is zero-based, meaning that the first element has an index of 0, the second element has an index of 1, and so on.
You can use the GetType() method to retrieve the data type of an element stored in the ArrayList. E.g.,
$ArrayList[0].GetType().Name
Checking Whether an Array Contains a Particular Value
If you want to see if any of the elements in an array contains a particular value, use the Contains method. This code will show whether an array contains either a 2 or a 12:
$array7 = 1,2,5,8,3,4,5 $array7.Contains(2) $array7.Contains(12)
Using the Replace Operator
The replace operator is used to replace one string with another. Here is the cmdlet structure:
<originalString> -replace <patternToFind>, <replacementString>
Here is an example that will replace “Hello World” with “PowerShell”:
$string = "Hello World" $newString = $string -replace "World", "PowerShell"
Looping through an Array
$array8 = @("Earth","Mercury","Venus","Jupiter","Saturn","Mars", "Neptune", "Pluto")
foreach ($array in $array8) {
"$array = " + $array.length
}The result will look like this:
Creating an Array of Objects
By default, each item in an array is an object, rather than another data type like string or integer. Here is an example of how to create an array of objects by explicitly adding objects:
$people = @(
[PSCustomObject]@{Name='Alice'; Age=30},
[PSCustomObject]@{Name='Bob'; Age=25}Understanding ArrayList and its Benefits in PowerShell

Understanding how to work with ArrayLists unlocks more flexible scripting capabilities. The ArrayList is a generic List collection type found in the System.Collections.ArrayList class. You can store ordered collections of any object type, like strings, numbers, custom objects, etc. Unlike the traditional PowerShell array, ArrayList can grow and shrink dynamically, making it ideal for situations where the number of elements is not known in advance or needs to change over time.
The benefits of using an ArrayList in PowerShell are numerous:
- Dynamic size: As mentioned earlier, ArrayList can grow and shrink dynamically, unlike the traditional array in PowerShell. This means you can easily add or remove elements without worrying about resizing the array or losing data.
- Improved performance: ArrayList provides better performance compared to the traditional array, especially when dealing with large volumes of data. This is because ArrayList uses a more efficient method of storing and retrieving data, which reduces the time and resources required to process your scripts.
- Compatibility: ArrayList is compatible with other PowerShell objects and can be easily converted to different data types, such as strings or arrays. This makes it a versatile choice for working with various data sources and formats.
- Rich built-in methods: ArrayList provides several built-in methods for manipulating and processing data. These methods include adding elements, removing elements, sorting, and searching, among others.
PowerShell ArrayList vs. Array: Key differences
- ArrayList is a dynamic collection of objects that can grow and shrink dynamically, while Array is a static collection of objects with a fixed size. This means that once an Array is created, its size cannot be changed.
- ArrayList provides better performance compared to Array when dealing with large volumes of data or when the number of elements is not known in advance. This is because ArrayList uses a more efficient method of storing and retrieving data, which reduces the time and resources required to process your scripts.
- PowerShell Arrays are strongly typed (meaning they can only store elements of a specific type). In contrast, ArrayLists can store values of any data type.
- On the other hand, Array offers better performance when dealing with a small number of elements or when the size of the collection is fixed. This is because Array uses a more straightforward method of storing and retrieving data, which can be faster than ArrayList in some cases.
When choosing between PowerShell Array List and Array, consider the size and nature of your data, as well as the performance requirements of your script. Here is another post on using arrays in PowerShell: How to use Arrays in PowerShell?
Export ArrayList to CSV
Let’s say you have an ArrayList like this:
$ArrayList = New-Object System.Collections.ArrayList
$ArrayList.Add("Apple")
$ArrayList.Add("Banana")
$ArrayList.Add("Cherry")The challenge here is that this ArrayList contains simple string data, and Export-Csv expects objects with properties. To resolve this, you could create a custom object array from these simple data types, like:
#Convert ArrayList to Object array
$Objects = $ArrayList | ForEach-Object { [PSCustomObject]@{Fruit = $_} }
#Export Array to CSV
$Objects | Export-Csv -Path "C:\Temp\Fruits.csv" -NoTypeInformationChecking the Length of an Array
To return the number of elements in array, use the .length parameter:
$array6 = 1,2,3,4,5,6 echo $array6.Length
Now Netwrix Can Help
Netwrix GroupID empowers you to:
- Automate user provisioning and deprovisioning from your HR information system (HRIS) to Active Directory, Entra ID and SCIM-enabled applications, thereby enabling new employees to quickly be productive and slashing the risk of adversaries taking over stale identities.
- Automatically update directory groups based on changes like an employee’s promotion or shift to another role, as recorded in your HRIS. This automation keeps access rights updated in near real time as required for security and compliance, while saving your IT team time.
- Delegate group and user management to the people who know who should have access to what. Simple workflows enable line-of-business owners to review their groups and approve or deny user access requests, reducing the risk of having over-privileged groups and users in your directory.
- Keep the directory clean and easier to manage with automated user creation, expiration and deletion.
- Maintain and prove compliance with regulations and standards with deep insight, effective automation and clear reporting on groups and members.
Convert Between ArrayList and Arrays
You can easily convert between ArrayList and standard PowerShell arrays:
Convert ArrayList to array
To convert an ArrayList to an array, use the typecasting as:
$Array = [array]$ArrayList
You can also use the ToArray() method:
$array = $arraylist.ToArray()
How about the reverse? To convert an existing array to ArrayList, use:
$arraylist = [System.Collections.ArrayList]$array
The array or ArrayList gets cast to the target type automatically.
Printing an Array
The easiest way to display the contents of an array is to simply reference the array variable. The example below shows how to include the text “Element:” before each item in the array:
To write to a .txt file, use the Out-File command:
$var5 | Out-File C:scriptsarray.txt
To export to a .csv file, use the Export-Csv command:
$var6 | Export-Csv -Path C:scriptsarray.csv
Using a Pipeline
The pipeline is used in PowerShell to pass the output of one command as the input to another. When working with arrays, you can use the pipeline to process and manipulate the data in the array and assign the results to a new array or modify the existing one.
Here we will multiply each array item by 2:
$numbers = 1,2,3,4,5
$doubled = $numbers | ForEach-Object { $_ * 2 }
Removing elements from a PowerShell ArrayList
Removing elements from a PowerShell ArrayList is a common operation that can be done using the Remove(), RemoveRange() or RemoveAt() methods. Whether you want to remove a specific element, or multiple elements, or even clear the entire list, there’s a method to help you do just that. Here’s how:
The Remove() method removes the first occurrence of a specified element, while the RemoveAt() method removes the element at a specific index.
$arrayList.Remove("apple")Removing a Range of Elements
The RemoveRange method allows you to remove a range of elements by specifying the starting index and the number of elements to remove parameters:
$ArrayList.RemoveRange(0,2) # This will remove the first two elements
To remove all items from the ArrayList, use the Clear() method:
Clear() empties the entire ArrayList.
Keep in mind that these methods modify the original Array List object, so use them with caution and ensure that you are removing the correct elements.
Slicing an Array
You can create a sub-array by specifying a range, as shown here:
$array = 1,2,3,4,5,6,7,8,9 $subset = $array[3..6]
Conclusion
ArrayLists provide a powerful alternative to standard PowerShell arrays for storing dynamic collections. In this comprehensive guide, we have covered the essentials of PowerShell ArrayList, from creation and manipulation to troubleshooting common errors of this fantastic data structure. We have also explored real-world use cases and provided tips for optimizing script performance. By understanding the features and benefits of ArrayList, you can easily store and manipulate data in a dynamic and efficient way.




