Array index from first to second last in PowerShell

There might be a situation where you are processing a list, but you don't know the length. Select-object has a -skiplast parameter.

(1,2,3,4,5 | select -skiplast 2)

1
2
3

You just need to calculate the end index, like so:

$array[0..($array.length - 2)]

Do remember to check that you actually have more than two entries in your array first, otherwise you'll find yourself getting duplicates in the result.

An example of such a duplicate would be:

@(1)[0..-1]

Which, from an array of a single 1 gives the following output

1 
1

As mentioned earlier the best solution here: $array[0..($array.length - 2)]

The problem you met with $array[0..-2] can be explained with the nature of "0..-2" expression and the range operator ".." in PowerShell. If you try to evaluate just this part "0..-2" in PowerShell you will see that result will be an array of numbers from 0 to -2.

>> 0..-2
0
-1
-2

And when you're trying to do $array[0..-2] in PowerShell it's the same as if you would do $array[0,-1,-2]. That's why you get results as 1, 5, 4 instead of 1, 2, 3, 4.

It could be kind of counterintuitive at first especially if you have some Python or Ruby background, but you need to take it into account when using PowerShell.


Robert Westerlund answer is excellent. This answer I just saw on the Everything you wanted to know about arrays page and wanted to try it out. I like it because it seems to describe exactly what the goal is, end at one short of the upper bound.

$array[0..($array.GetUpperBound(0) - 1)]
1
2
3
4

I used this variation of your original attempt to uninstall all but the latest version from Get-InstalledModule. It's really short, but not perfect because if there are more than 9 items it still returns just 8, but you can put a larger negative number, though.

$array[-9..-2]
1
2
3
4