Tag Archives: .Add()

Add, Concatenate, and a Little More

My desire to know Windows PowerShell from beginning to end isn’t just for me. It’s also for those around me — online, and in real life. I want to be a go-to-guy for all things PowerShell. I’ve found something I really love about the industry right now, and so I want know it well, and share it often. I truly believe that learning the fundamentals of PowerShell make one much more prepared to use the language interactively, as well as inside scripts and functions. I’ve said it before: It’s easy to spot someone that doesn’t know the fundamentals of PowerShell, and is only out to learn as much as is required to complete their current task.

A couple weeks ago a coworker asked me why their conditional wasn’t working (think, the part inside the parentheses in an If statement, for example). While I never saw the code, as the conversation happen over cube walls and by instant message, I suspected they were trying to compare a numeric value with something that wasn’t numeric. It turned out I was right. I determined this, the moment they said they had quotes around their numeric value.

It’s simple. The moment we put numeric values inside quotes — single or otherwise — we are no longer working numbers — we’re working with strings. Take a look at the example below. In the first command, we use addition to add the numeric values 5 and 10, which results in the (numeric) value of 15. In the second command, we concatenate (think, combine or join) — using the same operator (+). When we concatenate the string value of 5 with the string value of 10, we create the (string) value of 510.

PS> 5 + 10
15
PS> '5' + '10'
510

The information I sent to my colleague by IM is listed below. I thought it would best explain the difference between a “numeric value” inside quotes, and one not inside quotes. In this example, 123 is an integer (System.Int32) without quotes around it, and a string (System.String) with quotes around it. A quick note about Select-Object’s -Unique switch parameter: This parameter returns duplicated results once, and only once. Had this not been included, it would have returned the same result for each member of the object (each method, property, etc.).

PS> 123 | Get-Member | Select-Object TypeName -Unique

TypeName
--------
System.Int32

PS> '123' | Get-Member | Select-Object TypeName -Unique

TypeName
--------
System.String

In our first example in this post, we saw what happens when the add two numeric values and what happens when we concatenate two strings. If you think like me, you’re probably wondering what happens when we concatenate a string value to a numeric value, and add a numeric value to a string character. It depends. Take a look at the slightly, modified example below, and then we’ll discuss it.

PS> 5 + '10'
15
PS> '5' + 10
510

Did you figure it out what’s happened in those examples? In the first command, 5 + ’10’, the numeric on the left of the equation, has forced the string on the right side, to switch from a string to a numeric data type. With two numeric values, it then added the two values and returned 15.

The second command, or equation, works much like the first one, except in reverse. The string character 5 on the left, forces the numeric value on the right into being a string and then concatenates the two, which results in 510 again. Whatever is on the left is going to try and change the type of whatever is on the right — when it can. So, when can’t it?

PS> 5 + '1a2b3c'
Cannot convert value "1a2b3c" to type "System.Int32". Error: "Input string was not in a correct format."
...
PS> '1a2b3c' + 10
1a2b3c10

The first command in the example above fails because it cannot convert the string, ‘1a2b3c,’ into a numeric value because it includes non-numeric characters — makes sense to me. Notice that this error helps prove what I said earlier: The data type of value on the left is being used to try and change the data type of the value on the right. The second equation works, because again, we’re simply joining, or concatenating, two values.

PS> 'Have a great ' + 2016 + '!'
Have a great 2016!

In closing, I’d like to add a word about the concatenation operation just above. While the plus sign, or rather, the concatenation operator does what it does well, it’s not used nearly as much as it was in the past for building strings — at least, I don’t see it much anymore. In fact, when I do see it, I almost always assume that what I’m looking at was written long ago and then borrowed. What you’re more likely to see these days, is in the example below.

PS> $Year = 2016 # It's a numeric value (no quotes).
PS> # Use double-quotes (below) to display the variable's value inside the string.
PS> "Have a great $Year!" # No concatenation operators needed!
Have a great 2016!

Thanks for the reading my first post of 2016!

Give a Parameter a Default Value (Part II)

Part I: http://tommymaynard.com/quick-learn-give-a-parameter-a-default-value-2015
Part III: http://tommymaynard.com/quick-learn-give-a-parameter-a-default-value-part-iii-2016

An old co-worker and friend contacted me last week. We hadn’t chatted since the last time I was interviewing for a job — a job I have now (well, pretty close anyway). I remember telling him I wanted a job that allowed me to work with Windows PowerShell. While he probably wasn’t surprised to hear this job did just that, he might have been, to hear I had started this site — a site using my name, and all about PowerShell. It’s a pretty serious commitment to associate your name with a technology, and continue to provide new content.

He mentioned to me that he wasn’t aware of the $PSDefaultParameterValues preference variable until he read this post. No joke, but it’s exciting to know that something I wrote was helpful for him. You see, this isn’t your average intelligence IT Pro, no, this is walking, talking IT genius. You know the kind — one of the ones you’d hire first, if you opened your own consulting business. In fact, during that same first chat, I discovered that he spoke at the Microsoft Higher-Education Conference in October 2014. He’s definitely doing something right.

As last weekend passed, I occasionally thought about that $PSDefaultParameterValues post and decided I should add something more to it, especially since I highlighted what I would consider to be the less used approach for populating this variable. First off, for those that haven’t read the previous post, the $PSDefaultParameterValues variable allows you to specify a default value for a cmdlet’s, or function’s, parameter(s).

For example, if I wanted the Get-Help cmdlet to always include the -ShowWindow parameter, then I can add that default value to the cmdlet like so:

PS C:\> $PSDefaultParameterValues
PS C:\> # Proof the variable is empty.
PS C:\> $PSDefaultParameterValues.Add('Get-Help:ShowWindow',$true)
PS C:\> $PSDefaultParameterValues

Name                           Value
----                           -----
Get-Help:ShowWindow            True

With this value set, every time we use the Get-Help cmdlet, it will include the -ShowWindow parameter, even though I don’t specifically enter it at the time the command is run. In the previous example, we use the .Add() method to add a key-value pair; however, I suspect that most people will actually be more likely to use a hash table to add the cmdlet and parameter, and its new, default parameter value. Here’s the same example as above using the hash table option.

PS C:\> $PSDefaultParameterValue
PS C:\> # Proof the variable is empty.
PS C:\> $PSDefaultParameterValues = @{'Get-Help:ShowWindow' = $true}
PS C:\> $PSDefaultParameterValues

Name                           Value
----                           -----
Get-Help:ShowWindow            True

Now for the reason I led with with .Add() method: If you use the hash table option above, and the variable is already populated, then it’s going to overwrite the value it’s already storing, unless we use the += assignment operator. Follow along in the next few examples under the assumption that $PSDefaultParameterValues, is already populated from the previous example.

PS C:\> $PSDefaultParameterValues

Name                           Value
----                           -----
Get-Help:ShowWindow            True

PS C:\> $PSDefaultParameterValues = @{'Get-ADUser:Server' = 'MyClosestDC'}
PS C:\> $PSDefaultParameterValues

Name                           Value
----                           -----
Get-ADUser:Server              MyClosestDC

In the example above, using the = assignment operator overwrote our Get-Help ShowWindow key-value pair, as it would with any populated variable. The idea here is that we either need to assign all the parameter default values at once (when using a hash table), or use the += assignment operator to append other key-value pairs. Here’s both ways:

PS C:\> $PSDefaultParameterValues
PS C:\> # Proof the variable is empty.
PS C:\> $PSDefaultParameterValues = @{'Get-Help:ShowWindow' = $true;'Get-ADUser:Server' = 'MyClosestDC'}
PS C:\> $PSDefaultParameterValues

Name                           Value
----                           -----
Get-ADUser:Server              MyClosestDC
Get-Help:ShowWindow            True

PS C:\> $PSDefaultParameterValues = $null
PS C:\> $PSDefaultParameterValues
PS C:\> # Proof the variable is empty.
PS C:\> $PSDefaultParameterValues = @{'Get-Help:ShowWindow' = $true}
PS C:\> $PSDefaultParameterValues += @{'Get-ADUser:Server' = 'MyClosestDC'}
PS C:\> $PSDefaultParameterValues

Name                           Value
----                           -----
Get-ADUser:Server              MyClosestDC
Get-Help:ShowWindow            True

That’s all there is to it. If you’re going to use a hash table and assign values to your $PSDefaultParameterValues at different times, then be sure to use the correct assignment operator, or use the .Add() method — it’s up to you. For me, I populate this variable in my profile, so overwriting it, is something in which I’m not concerned. Thanks for reading!