Tag Archives: Range Operator

There is a Difference: Arrays Versus Hash Tables

After reading a short post on the PowerShell subreddit recently, I was compelled to write a quick post here about arrays and hash tables. The concepts are similar, but the two are different, meaning that — interruption! There have now been two posts where the OP didn’t know one versus the other. It is basic stuff, sure, but it is important stuff.

Anyway, talking about one when you mean the other isn’t going to be okay any longer — it really never was. While someone mentioned the incorrect usage in the thread, writing, for me, still felt necessary and potentially beneficial.

Instead of writing my own definitions, let’s use Microsoft’s. We’ll begin with an array: “Data structures designed to store collections of items.“ If you think of a variable, back when you learned about those the first time, you probably learn how to store a single value in your variable. Okay good. This time we’re going to store multiple values in a single variable. That is what this data structure provides.

We are beginning with a simple variable that contains a simple, single value. Not much to it.

[PS7.2.0][C:\] $SingleValue = 'One thing'
[PS7.2.0][C:\] $SingleValue
One thing
[PS7.2.0][C:\] $SingleValue.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

Now, let’s work with arrays. We’re still going to use a single variable, we’re just going to load it up with a different data structure that’s going to let us store multiple values in it. We actually don’t have to do much to make this happen, so here we go.

In this example, we’re creating a variable named $Array01. We’re storing the numeric values of 1, 2, and 3 inside the variable as an array.

[PS7.2.0][C:\] $Array01 = 1,2,3
[PS7.2.0][C:\] $Array01
1
2
3
[PS7.2.0][C:\] $Array01.GetType()

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

Well, that was easy. This next example is the same as above, however, it includes @() around our numeric values. This operator — the array sub-expression operator — takes whatever is inside it and makes it into an array.

[PS7.2.0][C:\] $Array02 = @(4,5,6)
[PS7.2.0][C:\] $Array02
4
5
6
[PS7.2.0][C:\] $Array02.GetType()

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

The array sub-expression operator will even make an array of nothing.

[PS7.2.0][C:\] $Array03 = @()
[PS7.2.0][C:\] $Array03
[PS7.2.0][C:\] $Array03.GetType()

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

Here is one you probably do not see often. The comma in front of the 7 will indicate to PowerShell to create an array that contains a single value, which we will prove when we start returning the count of our various arrays.

[PS7.2.0][C:\] $Array04 = ,7
[PS7.2.0][C:\] $Array04
7
[PS7.2.0][C:\] $Array04.GetType()

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

[PS7.2.0][C:\] $Array04.Count
1
[PS7.2.0][C:\] $Array03.Count
0
[PS7.2.0][C:\] $Array02.Count
3
[PS7.2.0][C:\] $Array01.Count
3

Do you get it? It is a data structure designed to accommodate multiple values. You did not see it here yet, but arrays can hold strings (words or sentences), just as easily as numbers. You can even mix them in the same array and store them in a single variable.

This array, stored in the $Array05 variable contains five different colors.

[PS7.2.0][C:\] $Array05 = 'black','red','green','blue','brown'
[PS7.2.0][C:\] $Array05
black
red
green
blue
brown

Each item in an array can be referenced by an index — a number that represents its location. It is a positional place in line. The first element, or item in the array — black in our case — is in index zero. This is because arrays are always zero-based. This means red would be in index 1, green in index 2, blue in 3, and brown in 4. Zero through four is five, as in five total elements, or values, in our array. Let’s verify.

[PS7.2.0][C:\] $Array05[0]
black
[PS7.2.0][C:\] $Array05[1]
red
[PS7.2.0][C:\] $Array05[2]
green
[PS7.2.0][C:\] $Array05[3]
blue
[PS7.2.0][C:\] $Array05[4]
brown
[PS7.2.0][C:\]

Let’s try some other things! While not often used in my day-to-day, we can perform arithmetic on the indexes. We can even use the range operator (..) and go forward and backward through our elements. What else… Oh, let’s try some negative indexes numbers, too. Those work in reverse from the end of the array to the beginning.

[PS7.2.0][C:\] $Array05[3-3]
black
[PS7.2.0][C:\] $Array05[2+1]
blue
[PS7.2.0][C:\] $Array05[0..4]
black
red
green
blue
brown
[PS7.2.0][C:\] $Array05[4..0]
brown
blue
green
red
black
[PS7.2.0][C:\] $Array05[-1]
brown
[PS7.2.0][C:\] $Array05[-2]
blue
[PS7.2.0][C:\] $Array05[-3]
green
[PS7.2.0][C:\] $Array05[-4]
red
[PS7.2.0][C:\] $Array05[-5]
black

Hash tables have a good number of similarities to arrays, and perhaps that is the reason why there is some confusion. Microsoft even uses the word array to describe them: “A hash table, also known as a dictionary or associative array, is a compact data structure that stores one or more key/value pairs.” I don’t use the words associative array often enough, but I should; I like it.

To the person on Reddit that called hash tables, hashmaps, and just maps: No. I believe that term is a carryover from maybe Java. In my experience, I have not heard it in the PowerShell community.

Anyway, arrays and associative arrays are both data structures. They can both hold multiple values, and they can both be stored in a single variable. The difference is keys and values. Arrays hold single items in each index, while a hash table holds a key-value pair in each.

Before we fill this up, let’s create an empty hash table. Notice the difference between this and the array. If it is used for an array, the operator will always be an instant giveaway: @() is for arrays, and @{} is for hash tables. Notice my liberal use of the GetType() method in this post; it’ll help you make object determinations, so you can always know which you’re working with, without having to view, or see, the data stored in the data structure.

[PS7.2.0][C:\] $Hash01 = @{}
[PS7.2.0][C:\] $Hash01
[PS7.2.0][C:\] $Hash01.Count
0
[PS7.2.0][C:\] $Hash01.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Hashtable                                System.Object

Now, let’s populate a hash table… in VS Code. Somethings I would just rather not demonstrate in the console.

$Hash02 = @{
    Dad = 'David'
    Mom = 'Betty'
    Daughter = 'Janice'
    Son = 'Bryan'
}
$Hash02
Name                           Value
----                           -----
Son                            Bryan
Dad                            David
Mom                            Betty
Daughter                       Janice

This also could have been written in a couple of other ways.

$Hash02 = @{
    Dad = 'David'; Mom = 'Betty'; Daughter = 'Janice'; Son = 'Bryan'
}
$Hash02 = @{
    Dad      = 'David'
    Mom      = 'Betty'
    Daughter = 'Janice'
    Son      = 'Bryan'
}

While hash tables have indexes, they’re non-numeric. Actually, I am not even sure I like the term index when working with hash tables. I suggest we call it what they are: keys. Maybe you noticed, but the order in which we created our hash table was not the order in which it was returned. A numeric value here would not help us anyway. Instead, we’re going to use the keys as our indexes to return our values.

$Hash02['Dad']
David
$Hash02['Daughter']
Janice

There is a good possibility that you are probably going to want to loop through and display all the values in your hash table. It’s a little out of place, but we’ll do that with one of our arrays here, too. Using the GetEnumerator() method allows us to get to the key and value, values out of our hash table. In this first, hash table example we are using the key and associated value in a string. This requires the use of the subexpression operator ($()), so that we can display our values within the string.

foreach ($Person in $Hash02.GetEnumerator()) {
    "The $($Person.Key) is $($Person.Value)."
}

The Son is Bryan
The Dad is David
The Mom is Betty
The Daughter is Janice

We are using the subexpression operator in the string created by looping over our array, too.

$Array05 = 'black','red','green','blue','brown'
foreach ($Color in $Array05) {
	"Is your favorite color $($Color)?"
}
Is your favorite color black?
Is your favorite color red?
Is your favorite color green?
Is your favorite color blue?
Is your favorite color brown?

This has been a lengthy post — who knew this would happen!? There is one last thing I want to mention, and that is about creating an ordered hash table, or dictionary. We tend to use the dictionary term when we order a hash table.

$Hash03 = [ordered]@{
    Monday    = 'Chipotle'
    Tuesday   = 'Pizza'
    Wednesday = 'Mahi Mahi'
    Thursday  = 'Ravioli'
    Friday    = 'Orange Chicken'
}
$Hash03

Name                           Value
----                           -----
Monday                         Chipotle
Tuesday                        Pizza
Wednesday                      Mahi Mahi
Thursday                       Ravioli
Friday                         Orange Chicken

Because this is ordered, we can use numeric indexes again. Keep in mind, however, that doing this is only going to return the values and not the keys, as well. It may even momentarily confuse you into thinking this is an array, not a hash table, or an associative array. Maybe stick to using a foreach at this point. Do not forget the GetType() method to ensure you know your data structures.

$Hash03[0..4]
Chipotle      
Pizza
Mahi Mahi     
Ravioli       
Orange Chicken

$Hash03.GetType()
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------     
True     True     OrderedDictionary                        System.Object

Okay, I am stopping here. There’s plenty to know about these two data structures, and at this point, it is more than I’m willing to share. Even so, this should provide a decent breakdown to go along with the Microsoft documentation and other information that’s available to consume on this topic. Know what you are talking about.

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.

Fourth Grade Multiplication Tables

I remember math class… in fourth grade. It was the year we learned multiplication. Day after day, for so many consecutive days, we’d have to write our “times tables.” Zero though 10, over and over again. Good thing, I suppose, as I still know them today. The combination of knowing PowerShell and my daughter learning her “times tables” now, got me thinking: How quickly could I “write” my “times tables” today? It turns out it takes around 5 milliseconds.

If you’ve been reading along recently you may have seen what we’ll do today, done before. We need multiple loops. One loop, our outer loop, will cycle through the numbers 0 through 10. For each of those, we’ll have an inner loop multiply 0 through 10 to the current outer loop number. You know, we’ll do zero, so zero times zero, zero times one, and so on, until we hit 10, at which point we’ll move on from zero to one (one times zero, one times one, one times two, etc.). Let’s begin with the outer loop.

foreach ($outernumber in 0..10) {
	$outernumber
}
0
1
2
3
4
5
6
7
8
9
10

Now, let’s do the inner loop. Again, this is going to repeat zero through 10 inside each inner loop, for each outer loop. If this is hard to follow, be sure to take a look at the soon-to-be upcoming example where we’ll highlight both outer and inner loops.

foreach ($outernumber in 0..10) {
	foreach ($innernumber in 0..10) {
		$innernumber
	}
}
0
1
2
3
4
5
6
7
8
9
10
0
1
2
3
4
5
6
7
8
9
10
0
1
2
3
4
5
6
7
8
9
10
0
1
2
3
4
5
6
7
8
9
10
0
1
2
3
4
5
6
7
8
9
10
0
1
2
3
4
5
6
7
8
9
10
0
1
2
3
4
5
6
7
8
9
10
0
1
2
3
4
5
6
7
8
9
10
0
1
2
3
4
5
6
7
8
9
10
0
1
2
3
4
5
6
7
8
9
10
0
1
2
3
4
5
6
7
8
9
10

This is the same example as we saw above; however, we’ve included the value of the outer loop in our output. Each outer loop value has two dashes (--) in front of it.

foreach ($outernumber in 0..10) {
	"-- $outernumber"
	foreach ($innernumber in 0..10) {
		$innernumber
	}
}
-- 0
0
1
2
3
4
5
6
7
8
9
10
-- 1
0
1
2
3
4
5
6
7
8
9
10
-- 2
0
1
2
3
4
5
6
7
8
9
10
-- 3
0
1
2
3
4
5
6
7
8
9
10
-- 4
0
1
2
3
4
5
6
7
8
9
10
-- 5
0
1
2
3
4
5
6
7
8
9
10
-- 6
0
1
2
3
4
5
6
7
8
9
10
-- 7
0
1
2
3
4
5
6
7
8
9
10
-- 8
0
1
2
3
4
5
6
7
8
9
10
-- 9
0
1
2
3
4
5
6
7
8
9
10
-- 10
0
1
2
3
4
5
6
7
8
9
10

And since this post is lengthy in long examples, let’s add another before we actually get to the results we came for. Our outer loop number is on the left side of the multiplication symbol, and our inner loop number is on the right side.

foreach ($outernumber in 0..10) {
	foreach ($innernumber in 0..10) {
		"$outernumber x $innernumber ="
	}
}
0 x 0 =
0 x 1 =
0 x 2 =
0 x 3 =
0 x 4 =
0 x 5 =
0 x 6 = 
0 x 7 = 
0 x 8 = 
0 x 9 = 
0 x 10 =
1 x 0 = 
1 x 1 = 
1 x 2 = 
1 x 3 = 
1 x 4 = 
1 x 5 = 
1 x 6 = 
1 x 7 = 
1 x 8 = 
1 x 9 = 
1 x 10 =
2 x 0 = 
2 x 1 = 
2 x 2 = 
2 x 3 = 
2 x 4 = 
2 x 5 = 
2 x 6 = 
2 x 7 = 
2 x 8 = 
2 x 9 = 
2 x 10 =
3 x 0 = 
3 x 1 = 
3 x 2 = 
3 x 3 = 
3 x 4 = 
3 x 5 = 
3 x 6 = 
3 x 7 = 
3 x 8 =
3 x 9 =
3 x 10 =
4 x 0 =
4 x 1 =
4 x 2 =
4 x 3 =
4 x 4 =
4 x 5 =
4 x 6 =
4 x 7 =
4 x 8 =
4 x 9 =
4 x 10 =
5 x 0 =
5 x 1 =
5 x 2 =
5 x 3 =
5 x 4 =
5 x 5 =
5 x 6 =
5 x 7 =
5 x 8 =
5 x 9 =
5 x 10 =
6 x 0 =
6 x 1 =
6 x 2 =
6 x 3 =
6 x 4 =
6 x 5 =
6 x 6 =
6 x 7 =
6 x 8 =
6 x 9 =
6 x 10 =
7 x 0 =
7 x 1 =
7 x 2 =
7 x 3 =
7 x 4 =
7 x 5 =
7 x 6 =
7 x 7 =
7 x 8 =
7 x 9 =
7 x 10 =
8 x 0 =
8 x 1 =
8 x 2 =
8 x 3 =
8 x 4 =
8 x 5 =
8 x 6 =
8 x 7 =
8 x 8 =
8 x 9 =
8 x 10 =
9 x 0 =
9 x 1 =
9 x 2 =
9 x 3 =
9 x 4 =
9 x 5 =
9 x 6 =
9 x 7 =
9 x 8 =
9 x 9 =
9 x 10 =
10 x 0 =
10 x 1 =
10 x 2 =
10 x 3 =
10 x 4 =
10 x 5 =
10 x 6 =
10 x 7 =
10 x 8 =
10 x 9 =
10 x 10 =

In this example, we’re going to add the multiplication problem to our output. Notice that we are making use of the subexpression operator ($()) in order to embed the results of each expression — or multiplication problem — within our string.

foreach ($outernumber in 0..10) {
	foreach ($innernumber in 0..10) {
		"$outernumber x $innernumber = $($outernumber * $innernumber)"
	}
}
0 x 0 = 0
0 x 1 = 0
0 x 2 = 0
0 x 3 = 0
0 x 4 = 0
0 x 5 = 0
0 x 6 = 0
0 x 7 = 0  
0 x 8 = 0  
0 x 9 = 0  
0 x 10 = 0 
1 x 0 = 0  
1 x 1 = 1  
1 x 2 = 2  
1 x 3 = 3  
1 x 4 = 4  
1 x 5 = 5  
1 x 6 = 6  
1 x 7 = 7  
1 x 8 = 8  
1 x 9 = 9  
1 x 10 = 10
2 x 0 = 0  
2 x 1 = 2  
2 x 2 = 4  
2 x 3 = 6  
2 x 4 = 8  
2 x 5 = 10 
2 x 6 = 12 
2 x 7 = 14 
2 x 8 = 16 
2 x 9 = 18 
2 x 10 = 20
3 x 0 = 0 
3 x 1 = 3 
3 x 2 = 6 
3 x 3 = 9 
3 x 4 = 12
3 x 5 = 15
3 x 6 = 18
3 x 7 = 21
3 x 8 = 24
3 x 9 = 27
3 x 10 = 30
4 x 0 = 0
4 x 1 = 4
4 x 2 = 8
4 x 3 = 12
4 x 4 = 16
4 x 5 = 20
4 x 6 = 24
4 x 7 = 28
4 x 8 = 32
4 x 9 = 36
4 x 10 = 40
5 x 0 = 0
5 x 1 = 5
5 x 2 = 10
5 x 3 = 15
5 x 4 = 20
5 x 5 = 25
5 x 6 = 30
5 x 7 = 35
5 x 8 = 40
5 x 9 = 45
5 x 10 = 50
6 x 0 = 0
6 x 1 = 6
6 x 2 = 12
6 x 3 = 18
6 x 4 = 24
6 x 5 = 30
6 x 6 = 36
6 x 7 = 42
6 x 8 = 48
6 x 9 = 54
6 x 10 = 60
7 x 0 = 0
7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35
7 x 6 = 42
7 x 7 = 49
7 x 8 = 56
7 x 9 = 63
7 x 10 = 70
8 x 0 = 0
8 x 1 = 8
8 x 2 = 16
8 x 3 = 24
8 x 4 = 32
8 x 5 = 40
8 x 6 = 48
8 x 7 = 56
8 x 8 = 64
8 x 9 = 72
8 x 10 = 80
9 x 0 = 0
9 x 1 = 9
9 x 2 = 18
9 x 3 = 27
9 x 4 = 36
9 x 5 = 45
9 x 6 = 54
9 x 7 = 63
9 x 8 = 72
9 x 9 = 81
9 x 10 = 90
10 x 0 = 0
10 x 1 = 10
10 x 2 = 20
10 x 3 = 30
10 x 4 = 40
10 x 5 = 50
10 x 6 = 60
10 x 7 = 70
10 x 8 = 80
10 x 9 = 90
10 x 10 = 100

That was it. Well, there is one thing. Let’s get back to seeing how long this command takes to run.

Measure-Command -Expression {
	foreach ($outernumber in 0..10) {
		foreach ($innernumber in 0..10) {
			"$outernumber x $innernumber = $($outernumber * $innernumber)"
		}
	}
} | Select-Object -Property Milliseconds

Milliseconds
------------
           5

We could put this entire command in a loop too, and test it across ten iterations. This example includes ticks, as well as milliseconds because when this command is run back-to-back, the speed per iteration drastically increases. Have a look. So it has been said, there are 10,000 ticks per millisecond and 1,000 milliseconds per second.

1..10 | ForEach-Object {
	Measure-Command -Expression {
		foreach ($outernumber in 0..10) {
			foreach ($innernumber in 0..10) {
				"$outernumber x $innernumber = $($outernumber * $innernumber)"
			}
		}
	} | Select-Object -Property Milliseconds,Ticks
}

Milliseconds Ticks
------------ -----
           3 39181
           0  7081
           1 14917
           1 10313
           0  2318
           0  2289
           0  2235
           0  2149
           0  2099
           0  2083

Using the Range Operator for Calculating Total Push-Ups

In December of 2014, I decided that my life in 2015 was in need of some push-ups. Instead of just starting with 10 a day, or some other arbitrary number, I thought I would do as many push-ups a day as it was the day in the year. This meant that on day one (January 1, 2015), I would do one push-up and on day two, I would do two push-ups, and so on. Today is the 20th day of the new year, and so I’ll have to do 20 tonight. I wanted to know how many push-ups I will have done by January 31st. Being the Windows PowerShell hobbyist that I am, I enlisted PowerShell to do my calculations for me.

I started with a variable, $EndDay, and the range operator (..). The combination of the two provides me an integer array of the days in January, such as 1..$EndDay (or, 1..31). Using this, I can calculate how many total push-ups I will have done by the end of the day on January 31st. The example below sets up the integer array, as well as the ForEach-Object loop where we’ll do our calculations. Note: I’m using the ForEach-Object alias, foreach.

$EndDay = 31
1..$EndDay | foreach {

}

The first thing we do, below, is include a second variable, $PushUps, that will collect the total number of push-ups for the month. We’ll use the += assignment operator. This operator takes whatever is already in $PushUps, and adds to it. If the current value stored in $PushUps was 1, and we used the += assignment operator like so, $PushUps += 2, then the value in $PushUps would be 3 (1 + 2 is equal to 3). If we used the standard assignment operator (=), then $PushUps would be 2, as 1 would be overwritten.

On the next line, below, we write some information on the screen. We write the current day: that’s the current number from the integer array represented by $_ (as of PowerShell 3.0, $_ can be represented as $PSItem). Then we write out the total number of push-ups completed by that day: $PushUps.

$EndDay = 31
1..$EndDay | foreach {
    $PushUps += $_
    Write-Output -Verbose "Day: $_ / PushUp Total: $PushUps"
}

I noticed that when I reran the code in the ISE, that the value of $PushUps was incorrect on the second run. This is because the variable already exists, and by the end of the first run already contains 496—the number of push-ups I’ll have done by the end of January! Therefore, I added an If statement that removed the $PushUps variable when $_ was equal to $EndDay. This happens on the final run through the foreach.

$EndDay = 31
1..$EndDay| foreach {
    $PushUps += $_
    Write-Output -Verbose "Day: $_ / PushUp Total: $PushUps"
    If ($_ -eq $EndDay) {
        Remove-Variable PushUps
    }
}

If you change the value for $EndDay to 365, you’ll be able to determine that after December 31st (if I can somehow keep this up) I will have done 66,299 total push-ups for the year. It’s hard to imagine that I could do 365 push-ups at once, but then again, it’s hard to imagine I’ll get though the rest of the month. Here’s an image that shows the the full results when we run the function above.

Using the Range Operator for Push-Up Calculations

Thanks for reading, and wish me good luck—I’m going to need it.