If you know that the value occurs only once in the array, the [array]::IndexOf() method is a pretty good way to go:

$array = 'A','B','C'
$item = 'B'
$ndx = [array]::IndexOf($array, $item)

Besides being terse and to the point, if the array is very large the performance of this approach is quite a bit better than using a PowerShell cmdlet like Where-Object. Still, it will only find the first occurrence of the specified item. But you can use the other overload of IndexOf to find the next occurrence:

$ndx = [array]::IndexOf($array, $item, $ndx+1)

$ndx will be -1 if the item isn't found.

Answer from Keith Hill on Stack Overflow
🌐
Microsoft
devblogs.microsoft.com › dev blogs › scripting blog [archived] › find the index number of a value in a powershell array
Find the Index Number of a Value in a PowerShell Array - Scripting Blog [archived]
December 7, 2011 - These static methods are shown here (they are all well documented on MSDN). PS C:\> [array] | gm -s | select name, definition | ft -a ... To use the indexof static method, I provide an array and a value that I want to find.
🌐
Tech thoughts
powershellone.wordpress.com › 2015 › 08 › 04 › finding-the-index-of-an-object-within-an-array-by-property-value-using-powershell
Finding the index of an object within an array by property value using PowerShell – Tech thoughts
July 25, 2018 - The problem with the $processes array is that it doesn’t have an index property, but fortunately, with PowerShell it’s not a problem at all to add one: $processes = Get-Process | foreach {$i=0} {$_ | Add-Member Index ($i++) -PassThru} $index = ($processes | where {$_.Name -eq "powershell"}).Index $processes[$index]
Discussions

How to find the index of an item in an array?
Hey, Scripting Guy! [explains arrays] ( http://blogs.technet.com/b/heyscriptingguy/archive/2011/12/07/find-the-index-number-of-a-value-in-a-powershell-array.aspx ) better than I can. $array.indexof($element) More on reddit.com
🌐 r/PowerShell
3
10
June 26, 2015
powershell - Array.Find and IndexOf for multiple elements that are exactly the same object - Stack Overflow
Use of a script block (invoked with call operator & and arguments), while not strictly necessary, is used to prevent polluting the enclosing scope with helper variable $i. The foreach statement is faster than the Foreach-Object cmdlet (whose built-in aliases are % and, confusingly, also foreach). Simply (implicitly) outputting $i for each match makes PowerShell collect multiple results in an array. If only one index is found, you'll get ... More on stackoverflow.com
🌐 stackoverflow.com
How to find the index of an element in an array by its value using Powershell - Stack Overflow
I will look up hash tables and get back to you! ... Thanks, Jeroen. That works like a charm while I have reference and value pairs. More generally, do you know of any functions which can return the indices of an element of an array which equals a certain value in Powershell? ... PowerShell is .NET based, so everything arrays in .NET can do, they can do in PowerShell. In particular, since they implement IList, they have the .IndexOf ... More on stackoverflow.com
🌐 stackoverflow.com
How can I find the index of a String array element using the [Array]::FindIndex method in PowerShell? - Stack Overflow
another PowerShell noob question. I have an array of strings that contains the names of businesses and I am writing a script that iterates through the folders of a directory and compares the folder More on stackoverflow.com
🌐 stackoverflow.com
🌐
SharePoint Diary
sharepointdiary.com › sharepoint diary › powershell › powershell tutorials › how to use the indexof method in powershell?
How to Use the IndexOf Method in PowerShell? - SharePoint Diary
October 7, 2025 - The function returns the index of the first occurrence of the specified value. Here is an example of how to use PowerShell Array IndexOf:
Top answer
1 of 3
20

You can do this:

b.Count-1)) | where {_] -eq 'D'}

1
3
6
2 of 3
7

mjolinor's answer is conceptually elegant, but slow with large arrays, presumably due to having to build a parallel array of indices first (which is also memory-inefficient).

It is conceptually similar to the following LINQ-based solution (PSv3+), which is more memory-efficient and about twice as fast, but still slow:

$arr = 'A','D','B','D','C','E','D','F'
[Linq.Enumerable]::Where(
 [Linq.Enumerable]::Range(0, $arr.Length), 
   [Func[int, bool]] { param(arr[$i] -eq 'D' }
)

While any PowerShell looping solution is ultimately slow compared to a compiled language, the following alternative, while more verbose, is still much faster with large arrays:

PS C:\> & { param(val)
         $i = 0
         foreach (arr) { if (val) { $i } ++$i }
        } ('A','D','B','D','C','E','D','F') 'D'
1
3
6

Note:

  • Perhaps surprisingly, this solution is even faster than Matt's solution, which calls [array]::IndexOf() in a loop instead of enumerating all elements.

  • Use of a script block (invoked with call operator & and arguments), while not strictly necessary, is used to prevent polluting the enclosing scope with helper variable $i.

  • The foreach statement is faster than the Foreach-Object cmdlet (whose built-in aliases are % and, confusingly, also foreach).

  • Simply (implicitly) outputting $i for each match makes PowerShell collect multiple results in an array.

    • If only one index is found, you'll get a scalar [int] instance instead; wrap the whole command in @(...) to ensure that you always get an array.
  • While $i by itself outputs the value of $i, ++$i by design does NOT (though you could use (++$i) to achieve that, if needed).

  • Unlike Array.IndexOf(), PowerShell's -eq operator is case-insensitive by default; for case-sensitivity, use -ceq instead.


It's easy to turn the above into a (simple) function (note that the parameters are purposely untyped, for flexibility):

function get-IndicesOf($Array, $Value) {
  $i = 0
  foreach (Array) { 
    if (Value) { $i } 
    ++$i
  }
}
# Sample call
PS C:\> get-IndicesOf ('A','D','B','D','C','E','D','F') 'D'
1
3
6
🌐
CopyProgramming
copyprogramming.com › howto › powershell-get-index-of-item-in-array
PowerShell Get Index of Item in Array: Complete Guide for 2026
December 1, 2025 - The [Array]::IndexOf() static method is the most straightforward and efficient way to find the index of an item in a PowerShell array.
🌐
Collecting Wisdom
collectingwisdom.com › home › powershell: how to find index of specific string in array
PowerShell: How to Find Index of Specific String in Array - Collecting Wisdom
July 18, 2024 - If the string may occur multiple times in the array, then you can use the following syntax to find each index position of the string: (0..($my_array.Count-1)) | where {$my_array[$_] -eq "my_string"} The following examples show how to use each method in practice. Suppose that we create the following array in PowerShell named $my_array that contains the names of various basketball teams:
Find elsewhere
🌐
Reddit
reddit.com › r/powershell › finding array index number
r/PowerShell on Reddit: Finding array index number
May 1, 2012 -

Hey guys I'm new to scripting and I'm wondering if anyone could help me with this. Is there a way to find the index number of a certain entry in an array and store it as a new variable?

Say we have an array called $animals which contains the names of various animals. Like so:

$animals = ('dog', 'cat', 'duck', 'horse')

And the script asks the user to input the name of an animal:

$input = read-host

And then some kind of "if" statement to check if $input is in $animals (I know how to do this part), and if it is it stores the index number of the array entry as $x.

Is this possible?

Top answer
1 of 2
10

The easiest solution here is the following:

$imageArray = Get-ChildItem "C:\Images"
[array]::indexof($imageArray.Name,'image123.jpg')

Explanation:

[array]::IndexOf(array array,System.Object value) searches an array object for an object value. If no match is found, it returns the array lower bound minus 1. Since the array's first index is 0, then it returns the result of 0-1.

Get-ChildItem -Path SomePath returns an array of DirectoryInfo and FileInfo objects. Each of those objects has various properties and values. Just using $imageArray to compare to image123.jpg would be comparing a System.IO.FileInfo object to a String object. PowerShell won't automatically convert a FileInfo object into a string while correctly parsing to find your target value.

When you choose to select a property value of each object in the array, you are returning an array of those property values only. Using $imageArray | Select -Expand Name and $imageArray.Name return an array of Name property values. Name contains a string in your example. This means you are comparing a String to a String when using [array]::IndexOf($imageArray.Name,'image123.jpg').

2 of 2
5

The way that .NET by default compares things is just not as forgiving as PowerShell is!

[array]::IndexOf($array, $reference) will go through the array and return the current index when it encounters an item for which the following is true:

$item.Equals($reference)

... which is NOT necessarily the same as doing

$item -eq $reference

For simple values, like numbers and dates and so on, Equals() works exactly like -eq:

PS C:\> $a = 1
PS C:\> $b = 1
PS C:\> $a.Equals($b)  # $true

... which is the reason your first example works as expected!

For more complex objects though, Equals() works a bit differently. Both values MUST refer to the same object, it's not enough that they have similar or even identical values:

PS C:\> $a = New-Object object
PS C:\> $b = New-Object object
PS C:\> $a.Equals($b)    # $false

In the example above, $a and $b are similar (if not identical) - they're both empty objects - but they are not the same object.

Similarly, if we test with your input values, they aren't the same either:

PS C:\> $a = Get-Item "C:\"
PS C:\> $b = "C:\"
PS C:\> $a.Equals($b)    # $false

One of the reasons they can't be considered the same, as AdminOfThings excellently explains, is type mismatch - but PowerShell's comparison operators can help us here!

You'll notice that this works:

PS C:\> $a = Get-Item "C:\"
PS C:\> $b = "C:\"
PS C:\> $b -eq $a
True

That's because the behavior of -eq depends on the left-hand operand. In the example above, "C:\" is a string, so PowerShell converts $a to a string, and all of a sudden the comparison is more like "C:\".Equals("C:\")!

With this in mind, you could create your own Find-IndexOf function to do $reference -eq $item (or any other comparison mechanism you'd like) with a simple for() loop:

function Find-IndexOf
{
  param(
    [array]$Array,
    [object]$Value
  )

  for($idx = 0; $idx -lt $Array.Length; $idx++){
    if($Value -eq $Array[$idx]){
      return $idx
    }
  }

  return -1
}

Now you'd be able to do:

PS C:\> $array = @('','PowerShell is case-insensitive by default')
PS C:\> $value = 'POWERsheLL iS cASe-InSenSItIVe BY deFAuLt'
PS C:\> Find-IndexOf -Array $array -Value $value
1

Or:

PS C:\> $array = Get-ChildItem C:\images
PS C:\> $value = 'C:\images\image123.png'
PS C:\> Find-IndexOf -Array $array -Value $value
5

Adding comparison against a specific property on each of the array items (like the file's Name in your example), we end up with something like this:

function Find-IndexOf
{
  param(
    [array]$Array,
    [object]$Value,
    [string]$Property
  )

  if($Property){
    for($idx = 0; $idx -lt $Array.Length; $idx++){
      if($Value -eq $Array[$idx].$Property){
        return $idx
      }
    }
  }
  else {
    for($idx = 0; $idx -lt $Array.Length; $idx++){
      if($Value -eq $Array[$idx]){
        return $idx
      }
    }
  }

  return -1
}

Find-IndexOf -Array @(Get-ChildItem C:\images) -Value image123.png -Property Name
🌐
Netwrix
netwrix.com › home › resources › blog › how to use powershell arrays
How to Use PowerShell Arrays | Netwrix
December 13, 2024 - 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) As with most programming languages, each individual item in a PowerShell array can be accessed by an index...
🌐
Narkive
microsoft.public.windows.powershell.narkive.com › kzOdeVyg › get-index-number-of-array-item
Get Index Number of Array Item?
Permalink One could Add-Member ... in Powershell that could be used instead? You could load it into a hash table (associative array) using the index number as the key. Then the array index for any particular element is available as the key. Post by ydroam How can one get the index number of an array ...
🌐
EDUCBA
educba.com › home › data science › data science tutorials › powershell tutorial › array in powershell
Array in PowerShell | Complete Guide to Array in PowerShell with Example
May 14, 2024 - The index of the array usually starts at 0, so to access the first element you must use the index [0]. Typically, only two operations can be on an array, i.e. adding an element to the array or removing an element.
Address   Unit no. 202, Jay Antariksh Bldg, Makwana Road, Marol, Andheri (East),, 400059, Mumbai
🌐
Linux Hint
linuxhint.com › arrays-in-powershell
Arrays in PowerShell
August 7, 2021 - Linux Hint LLC, [email protected] 1210 Kelly Park Circle, Morgan Hill, CA 95037 Privacy Policy and Terms of Use
🌐
Powershellexplained
powershellexplained.com › 2018-10-15-Powershell-arrays-Everything-you-wanted-to-know
Everything you wanted to know about arrays - Powershell
October 15, 2018 - A common programming error is created because arrays start at index 0. An off by one error can be introduced in two very common ways. The first is by mentally thinking you want the 2nd item and using an index of 2 and really getting the third item. Or by thinking that you have 4 items and you want last item, so you will just use the size to access the last item. ... PowerShell is perfectly happy to let you do that and give you exactly what item exists at index 4, $null.
🌐
Reddit
reddit.com › r/powershell › adding an index number to an array
r/PowerShell on Reddit: Adding an Index number to an Array
December 15, 2020 -

Hi All,

I'm trying to figure out how to stream line something.

When I normally get a large result from a query, and I want to return just one that's in the middle of the pool, I end up having to hunt fish in a barrel. So let’s say I store the results of a query into $qResult (500 items). This result set has some specific values in the middle of that group of results. I know I can out-gridview to see and search through the results, and I do in fact, do this. Once I do find the specific result, I want to just output that specific result so I can copy and paste the information for documentation purposes. This is where the hunting begins.

I end up doing something like:

$qResult[200..250]

$qResult[251..300]

Until I can identify the index number of the specific result.

I found a method that lets me add an artificial index number into the array and that's helpful but cumbersome. That method looks something like:

$l=0

`$ampEvents | forEach-Object { New-Object psObject ``

`-Property @{'LN'=$l; ``

`'computer' = $_.computer; ``

`'connector_guid' = $_.connector_guid; ``

`'date' = $_.date; ``

`'detection_id' = $_.detection_id; ``

`'error' = $_.error; ``

`'event_type' = $_.event_type; ``

`'event_type_id' = $_.event_type_id; ``

`'file' = $_.file; ``

`'group_guids' = $_.group_guids; ``

`'id' = $_.id; ``

`'severity' = $_.severity; ``

`'timestamp' = $_.timestamp; ``

`'timestamp_nanoseconds' = $_.timestamp_nanoseconds; ``

`};``

`$l ++ ``

}

I cobbled together this snippet to help make the property assignments but it's still messy:

($ampEvents[0] | gm | ? {$_.MemberType -ne "Method"}).Name

$propList = ($ampEvents[0] | gm | ? {$_.MemberType -ne "Method"}).Name

foreach ($prop in $propList){

$propLine = "'" + $prop + "' = " + '$_.' + $prop + '; \'`

Write-Output $propLine

}

That outputs:

`'computer' = $_.computer; ``

`'connector_guid' = $_.connector_guid; ``

`'date' = $_.date; ``

`'detection_id' = $_.detection_id; ``

`'event_type' = $_.event_type; ``

`'event_type_id' = $_.event_type_id; ``

`'file' = $_.file; ``

`'group_guids' = $_.group_guids; ``

`'id' = $_.id; ``

`'severity' = $_.severity; ``

`'timestamp' = $_.timestamp; ``

`'timestamp_nanoseconds' = $_.timestamp_nanoseconds; ``

I can just copy and paste that into the object properties in the earlier code now.

I was wondering if there is a better way to approach this. I tried this and it was not successful:

$l=0

$objProps = New-Object psObject

$objProps | Add-Member -MemberType NoteProperty -Name "LN" -Value $l

foreach ($prop in $propList){

$objProps | Add-Member -MemberType NoteProperty -Name $prop -Value $('$_.' + $prop)

}

This results in:

$objProps

LN : 0

computer : $_.computer

connector_guid : $_.connector_guid

date : $_.date

detection_id : $_.detection_id

event_type : $_.event_type

event_type_id : $_.event_type_id

file : $_.file

group_guids : $_.group_guids

id : $_.id

severity : $_.severity

timestamp : $_.timestamp

timestamp_nanoseconds : $_.timestamp_nanoseconds

Then I try to re-use that new list:

$l=0

`$ampEvents | forEach-Object { New-Object psObject ``

`-Property @{$objProps}; ``

$l ++ } | Out-Gridview

but I get:

ParserError:

Line |

`2 | -Property @{$objProps}; ``

| ~

| Missing '=' operator after key in hash literal.

Anyone out there got another spin I can take with this?

Thanks in advance!

🌐
O'Reilly
oreilly.com › library › view › mastering-windows-powershell › 9781787126305 › 83c4a866-082f-4df0-8c32-1ffa91a6e329.xhtml
Selecting elements from an array - Mastering Windows PowerShell Scripting - Second Edition [Book]
October 27, 2017 - Selecting elements from an array Individual elements from an array may be selected using an index. The index counts from 0 to the end of the array. The first and second elements... - Selection from Mastering Windows PowerShell Scripting - Second Edition [Book]
Authors   Chris DentBrenton J.W. Blawat
Published   2017
Pages   440