Pass Range to Function Parameter

I had one of those thoughts, where you must know how something is handled in PowerShell, as soon as you possibly can. Maybe it happens to you, too. Unfortunately for me, it happen just before I decided to go to bed a few days ago, which kept me awake a bit longer than expected.

The question was this: Can I pass a range operator to a PowerShell function as a parameter? As you may know, a range operator alone isn’t worth much, so essentially the question was, Can I pass two numbers and range operator to a PowerShell function as a parameter?

Let’s start with an example of the range operator (..). It’s two dots between two numbers, and it essentially says, “provide me every number in this range.” The below example uses the numbers 1 through 10. Once executed, it returns the numbers 1, 2, 3, 4, etc., all the way up to 10.

[PS7.2.0][C:\] 1..10
1
2
3
4
5
6
7
8
9
10
[PS7.2.0][C:\]

A couple of things: One, the range operator returns an array, and two, as of PowerShell version 6, it works with letters, or characters, as well. Be sure to use single quotes around your string values, or it’ll think you are passing in command names, which will not work.

[PS7.2.0][C:\] (1..10).GetType()

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

[PS7.2.0][C:\] 'a'..'e'
a
b
c
d
e
[PS7.2.0][C:\] 

Let’s review this function first. This is my New-RangeOption function. It requires that two integers be supplied. One for the RangeFirstNumber parameter and one for the RangeLastNumber parameter. The idea here is that we don’t believe a range can be supplied to a function, as a parameter, and we must create it ourselves inside of our function. We do more than just that, however. As I was just testing, we display each number and then we display the type of each parameter value. They are cast as integers, so that really wasn’t necessary. Additionally, we create the range (add the operator between the two integers), display the results, and return the type of the range, as well. This should make sense when you see the below results.

function New-RangeOption {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory)]
        [int]$RangeFirstNumber,

        [Parameter(Mandatory)]
        [int]$RangeLastNumber
    )
    $RangeFirstNumber;  $RangeLastNumber
    $RangeFirstNumber.GetType(); $RangeLastNumber.GetType()

    $InFunctionRange = $RangeFirstNumber..$RangeLastNumber
    $InFunctionRange
    $InFunctionRange.GetType()
}
New-RangeOption -RangeFirstNumber 1 -RangeLastNumber 10
1
10

IsPublic IsSerial Name                                     BaseType        
-------- -------- ----                                     --------        
True     True     Int32                                    System.ValueType
True     True     Int32                                    System.ValueType
1
2
3
4
5
6
7
8
9
10
True     True     Object[]                                 System.Array

This option works, but we can do better. This, below example, has only a single parameter, Range. We send in our range, which includes the two numeric values and the range operator. It outputs the range — all the numbers — the type, and the count, as in the count of the number of members in the array. It’s 10, one for each value from 1 to 10.

function New-BetterRangeOption {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory)]
        [array]$Range
    )

    $Range
    $Range.GetType()
    $Range.Count
}
New-BetterRangeOption -Range (1..10)
1
2
3
4
5
6
7
8
9
10

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

There is an important thing to notice here, and that’s the group operator — the parentheses around 1..10. It is used to pass in the digits with the range operator. Without this operator, it would’ve been a mess — let’s see.

New-BetterRangeOption -Range 1..10
1..10

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

In this last output, it doesn’t display the actual digits within the range. While it still thinks it’s an array, it’s an array that contains 1..10 as a single, string member. That’s it though; curiosity satisfied. We can pass in a range, using the range operator (and the group operator), to our functions. Now, I only need a reason to do it.

Leave a Reply

Your email address will not be published. Required fields are marked *