Fun With PowerShell Arrays

Introduction

In this article, we’ll look at the different ways to use Arrays in PowerShell. We’ll cover the basics, then move onto more advanced topics.

For all of the examples, we’ll display the code, then under it the result of our code. In this article I’ll be using PowerShell Core, 7.1.3, and VSCode. The examples should work in PowerShell 5.1 in the PowerShell IDE, although they’ve not been tested there.

To run a snippet of code highlight the lines you want to execute, then in VSCode press F8 or in the IDE F5. You can display the contents of an array variable (or any variable) by highlighting it and using F8/F5.

A quick note for my non-native English speaking friends, I use the term aka a few times. AKA is shortcut for “also known as“, it’s just a quick way to say “a is another word for b”.

Array Basics

The formal array to declare an array is to use @() around the contents, assigning it to a variable.

$array = @('Robert', 'Cain')
$array

Result:
Robert
Cain

Note that in the output, each item (aka element) in the array is displayed on a single line.

There is a little easier way to create an array, you can omit the @() . If you are passing in more than one item, separated by a comma, PowerShell converts it to an array.

$array = 'Robert', 'Cain'

If you have a long list of items, you can break the list over multiple lines. As long as a comma is the last thing on the line PowerShell will assume the rest of the array contents continue on the next line.

$array = 'Robert',
         'Cain'

You can access individual items in the array by using what is called positional notation. After the name of the array, use square brackets [] and inside put a number that indicates the position in the array.

Numbering begins at zero and goes to the maximum number of elements. (Well, technically the max number of elements minus one, but more on that in a moment.) If you try to use a number greater than the maximum number of elements, you will get an error.

$array = 'Robert', 'Cain'
$array[0]

Result:
Robert

$array[1]

Result:
Cain

Of course you can use variables in place of the numeric values for positional notation.

$x = 1
$array[$x]

Result:
Cain

So how do you know how many items are in an array? The array variable type has a Count property that can tell you that.

$array.Count

Result:
2

There is also a property called Length, which returns the same thing. They can be used interchangeably, most people however use the Count property.

One thing to be careful of with Count, is that it returns the number of items in the array. But arrays start with position 0 (zero), so the last item in an array will be Count - 1, not Count.

$array[$array.Count - 1]

Result:
Cain

PowerShell does provide a shortcut to get the last element. You can pass in a -1 (negative one) into the position, and it will get the last item.

$array[ -1 ]

Result:
Cain

Fun Tricks with Positional Notation

There are a few fun tricks you can do with positional notation. So far, we’ve only used a single value in the square brackets to get a single value from the array.

Did you know you can pass in multiple numbers and get back multiple elements from the array in one command?

$array = 'Zero', 'One', 'Two', 'Three',
         'Four', 'Five', 'Six', 'Seven'
$array[2, 4, 6]

Result:
Two
Four
Six

If you pass in the same number twice, you’ll get that array item back twice in the results.



$array = 'Zero', 'One', 'Two', 'Three',
         'Four', 'Five', 'Six', 'Seven'
$array[2, 4, 2]

Result:
Two
Four
Two

Finally, you can use PowerShell’s range operator to return a series of values.



$array = 'Zero', 'One', 'Two', 'Three',
         'Four', 'Five', 'Six', 'Seven'
$array[1..4]

Result:
'One'
'Two'
'Three'
'Four'

Adding Items to an Array

Adding items is pretty easy, you can use the += (plus equal) to add a new item into the array. In this example, we’ll add two new items, then display the new array, and finally the count of items.

$array = 'Robert', 'Cain'

$array += 'Arcane'
$array += 'Code'
$array

$array.Count

Result:
Robert
Cain
Arcane
Code
4

Here you can see are my original two items, followed by the new ones we just added. Finally the count, 4, is displayed.

Updating an Array Element

What if we want to update a value in the array? Turns out that is as easy as adding a new one. Simply address the item to replace with positional notation, then assign a new value.

$array[0] = 'Mr.'
$array

Result:
Mr.
Cain
Arcane
Code

Empty Arrays

When you need to create an empty array, you use the formal array declaration syntax we saw in the first example, only you put nothing in it.

$empty = @()
$empty

Result:
(Nothing is displayed because the array is empty)

So why would you need an empty array?

Let’s say you were looping over a collection of some type, and were building a new array to output. It might be a collection (aka array) of files, or records return from a SQL Server query.

You would create the empty array, enter the loop, extract and format the information you want then add it to the empty array using the += syntax.

Iterating Over Arrays

There are a few methods we can use to iterate, or loop over the contents of our arrays. The most common, and one I use the most, is a foreach loop.

foreach($item in $array)
{
  "The current item is $item"
}

Result:
The current item is Mr.
The current item is Cain
The current item is Arcane
The current item is Code

The next option is to pipe our array into the ForEach-Object cmdlet, passing a script block to the cmdlet with our instructions.

$array | ForEach-Object { "Current Value: $PSItem"}

Result:
Current Value: Mr.
Current Value: Cain
Current Value: Arcane
Current Value: Code

The variable $PSItem is a built in PowerShell variable, meant to represent the current item in a loop.

Finally, an Array datatype has a ForEach method built right in. You call the method, then as you did with the ForEach-Object cmdlet pass in a script block with the instructions.

$array.ForEach({ "Current Value: $_"})

Result:
Current Value: Mr.
Current Value: Cain
Current Value: Arcane
Current Value: Code

In this example we used the variable $_ to represent the current item. The $_ was the original way to create a placeholder, later PowerShell added the $PSItem variable. $PSItem was introduced way back in version 3, so unless you are on a really really REALLY old version of PowerShell, you can use $_ and $PSItem interchangeably.

Erasing the Contents of an Array

Clearing out the contents of an array is easy, just call the array’s Clear method.

$array.Clear()
$array

Result:
(Nothing is displayed because the array is empty)

Mixed Data Types

Unlike a lot of other languages, the values going into an array can be a mix of data types. In the example below I’m going to load an array with some strings, integers, and a floating point type.

$array = 'Arcane', 'Code', 33, 42,
         'Alabama', 3.14, 'In the Morning'
$array

Result:
Arcane
Code
33
42
Alabama
3.14
In the Morning

Removing Items From Arrays

We now move to a topic that doesn’t have a happy answer. You cannot remove an item from an array. That said, you could create a brand new array, filtering out the unwanted elements.

In this example, we pipe our array into the Where-Object cmdlet. We pass in a script block, in which we say only pass out items where the value of the current item is not equal ( -ne ) to the state of Alabama. After that we display the results.

Note too we are using another built in line continuation feature of PowerShell. If the pipe symbol, a | , is the last thing on the line PowerShell assumes what is on the next line is a continuation of the line above. (I like to indent the second line to the right of my equal sign, but it’s not required.)



$array = 'Arcane', 'Code', 33, 42,
         'Alabama', 3.14, 'In the Morning'
$newArray = $array |
            Where-Object { $PSItem -ne 'Alabama' }
$newArray

Result:
Arcane
Code
33
42
3.14
In the Morning

As you can see, the state of Alabama is no longer in our list.

Fun Operators – In and Compare

There are other operators in PowerShell that can let us do fun things with arrays.

First, what if we need to know if an item is already in the array? There’s actually two methods to handle that. In the first, we’ll see if the item is in the array.

$array = 'Arcane', 'Code', 33, 42,
         'Alabama', 3.14, 'In the Morning'
'Arcane' -in $array

Result:
True

In the second method we’ll use the contains operator.

$array -contains 'Code'

Result:
True

More Fun Operators – Join

What if you wanted to convert all of the elements in the array into a single string? To handle that we have the join operator.

After the join, you pass in a character to use to separate each element. You also have the option to pass in an empty string if you don’t want anything separating your results.

In the last example, you’ll see that you can pass in more than one character to separate the results.

$array = 1, 3, 5, 7, 9
$result = $array -join ' '
$result

Result: 1 3 5 7 9

$array = 1, 3, 5, 7, 9
$result = $array -join '-'
$result

Result: 1-3-5-7-9

$array = 1, 3, 5, 7, 9
$result = $array -join ','
$result

Result: 1,3,5,7,9

$array = 1, 3, 5, 7, 9
$result = $array -join ''
$result

Result: 13579

$result = $array -join ', '
$result

Result: 1, 3, 5, 7, 9

Even More Fun Operators – Replace, Match, Split

There are three more operators we’ll cover here. The first is Replace, which will search through the array and replace one string with another.

$servers = 'HOLD-001', 'HOLD-002', 'SQL-001', 'SQL-002'
$newServers = $servers -replace 'HOLD', 'TEST'
$newServers

Result:
TEST-001
TEST-002
SQL-001
SQL-002

You might use this to develop a script to run against your servers. When designing the script you might use a string like HOLD-001, HOLD-002, etc where HOLD is just a place holder.

At runtime you pass a parameter into your script such as DVLP (development), TEST, or PROD (production) so you can use the same script in multiple environments.

The next operator we’ll look at is match. Match can be used as a filter. Let’s take a look at this example:

$servers = 'SRV-001', 'SRV-002', 'SQL-001', 'SQL-002'
$newServers = $servers -match 'SQL'
$newServers

Result:
SQL-001
SQL-002

As you can see, only servers with SQL in the name were returned. This might be useful if you had a full list of all servers you wanted to iterate over, but in certain sections of your script you only wanted to do things to your SQL Servers.

The final operator to look at is split. You can use split to further divide the elements in your array into smaller parts.

In this example we’ll reuse our list of servers, but split the items based on a dash (or hyphen).

$servers = 'SRV-001', 'SRV-002', 'SQL-001', 'SQL-002'
$newServers = $servers -split '-'
$newServers

Result:
SRV
001
SRV
002
SQL
001
SQL
002

Here you can see each server name was split into two parts, each part becoming a new element in our output array. Also note that the character we split on, the dash, is discarded from the result set.

Iterating Over an Array of Objects

Just like arrays of simple items like strings and integers, you can also loop over an array of objects.

Here, we’ll get a list of files in my temp directory using the Get-ChildItem cmdlet. We’ll also use the empty array technique you saw earlier. A foreach loop will be used to go over each file object in the array and format a string with some of its properties, then add that string to our empty $newFiles array.

Set-Location "C:\Temp"
$files = Get-ChildItem
$newFiles = @()
foreach($file in $files)
{
  $newFiles += "$($file.Name) is $($file.Length) in size"
}
$newFiles

Result:
2019-ARRL-FieldDay-Rules-RevA.pdf is 111434 in size
ARRL-FIELD-DAY.adi is 76110 in size
azuredatastudio-windows-user-setup-1.13.1.exe is 91789368 in size
curl-7.74.0.zip is 6068670 in size
standard-notes-3.6.14-win.exe is 105761936 in size
SysinternalsSuite.zip is 41889407 in size

Within my loop $file represents the current item in my $files array. Inside I access the properties of my file object. I could, for example, have used if ($file.Length -gt 1) and done something useful.

In this case I’m using string interpolation to display the value of a property. Note that because I want it to access the property, within the string I have to wrap it in $(), such as $($file.Name).

This forces PowerShell to first evaluate what is inside the $(), then return that into the string.

Conclusion

This post turned out longer than I’d intended, but there are so many fun things you can do with a PowerShell Array it was hard to stop at just a few.

With luck you’ll have found some new techniques you can employ with arrays in your own PowerShell scripts.

The demos in this course came from my Pluralsight course PowerShell 7 Quick Start for Developers on Linux, macOS and Windows, one of many PowerShell courses I have on Pluralsight. All of my courses are linked on my About Me page.

If you don’t have a Pluralsight subscription, just go to my list of courses on Pluralsight. At the top is a Try For Free button you can use to get a free 10 day subscription to Pluralsight, with which you can watch my courses, or any other course on the site.

Fun With PowerShell String Formatting

Introduction

In last Monday’s blog post, Fun With PowerShell Strings, I covered a lot of the basics around PowerShell Strings. One thing we didn’t get into though was some of the special formatting commands you can use with PowerShell.

Specifically, this can control the output when we embed a numeric value inside a string. Passing in special formatting instructions will make it easy to display values with commas, as currency, or even as hexidecimal.

For all of the examples, we’ll display the code, then under it the result of our code. In this article I’ll be using PowerShell Core, 7.1.3, and VSCode. The examples should work in PowerShell 5.1 in the PowerShell IDE, although they’ve not been tested there.

To run a snippet of code highlight the lines you want to execute, then in VSCode press F8 or in the IDE F5. You can display the contents of an array variable (or any variable) by highlighting it and using F8/F5.

How it Works

PowerShell supports the C# / C / C++ style of string formatting. Let’s take a look at this example.

[string]::Format("There are {0} items.", $items)

Inside our string we have {0}. This is a placeholder, when a C style language sees this it will look for the first variable after the string and put that into placeholder 0.

PowerShell of course always wants to make life easier on us, so we can use this much simpler format.

"There are {0} items." -f $items

In PowerShell we have our string, including the placeholder. After it we have a -f to let PowerShell know the following items will be copied into the placeholders. In this case, the value in $items will be inserted into the {0} placeholder.

It’s not necessary to use a variable, we could have just hardcoded a value.

"There are {0} items." -f 33

What if we had multiple items? Well we’d just use multiple placeholders (all on one line).

"There are {0} items in the location {1}." -f $items, $loc

In this example, $items will go into the {0} and the value in $loc will get inserted into placeholder {1}.

You can even repeat a placeholder.

"There's {0} items in {1}. {0} is a lot of items!" -f $items, $loc

Now, if you’ve read my previous post you’re probably thinking “wait, wouldn’t string interpolation make all these unnecessary?”

And in these examples you are correct, with string interpolation you could have used the much easier to read syntax.

"There are $items items."

So why use the placeholder style? Well it turns out the placeholder syntax includes some extra syntax which will allow you to format values passed in. Let’s take a look at some examples.

Number

In the placeholder, after the placeholder position ( 0 in these examples ) you can put a colon : , then a letter that indicates the formatting style. Then another number which indicates the decimal places to retain.

"N0 {0:N0} formatted" -f 12345678.119    

Result:
N0 12,345,678 formatted

In this example, after the colon we have the letter N. This lets PowerShell know we want this to be formatted as a numeric value, and to include commas to separate the numbers.

In this example after the letter N we have another number, a 0. This indicates how many decimal places to retain in the output.

Here’s another example where we’ll include two decimal places.

"N2 {0:N2} formatted" -f 12345678.119

Result:
N2 12,345,678.12 formatted

As you can see, it follows the normal rules for rounding up the output. The next to the last last number, 1, was rounded up to 2 since the number after it was a 9.

Often we want to display numbers as right aligned, so the last digit will line up in our output. This means we want to display a number of spaces in front of it. PowerShell includes a feature for this too.

"N0 {0,8:N0} formatted" -f 123.119

Result:
N0      123 formatted

After the place holder we have a comma then a number ( here 0,8 ). This tells PowerShell we want the value for this placeholder to be eight characters in width.

In the output, PowerShell saw the final value, 123, was three characters wide. So it subtracted three from eight and put five spaces in front of the 123 so the entire output became eight characters in width.

A common question is “what if the output is longer than the width passed in?”. For example, you used 0,3 but your input to the placeholder was a value of 123456? In that case PowerShell will still format it as 123,456 but will not add any spaces before the number. This could result in some misaligned output in your display, but at least the accurate value will still be shown.

Currency

Using the C format instruction, PowerShell can display the results in currency format. It will use the default currency symbol for your computer’s language / location. Since I’m in the United States it will use a dollar sign.

"C0 {0:C0} formatted" -f 12345678.1234
"C2 {0:C2} formatted" -f 12345678.1234
"C2 {0,20:C2} formatted" -f 12345678.1234

Result:
C0 $12,345,678 formatted
C2 $12,345,678.12 formatted
C2       $12,345,678.12 formatted

Currency acts very similar to the Number format, the only real difference is the addition of your location’s currency symbol in the formatted output.

Percentage

PowerShell also has the ability to display values in a percentage format.

"P0 {0:P0} formatted" -f 0.1234
"P2 {0:P2} formatted" -f 0.1234
"P2 {0,8:P2} formatted" -f 0.1234

Result:
P0 12% formatted
P2 12.34% formatted
P2   12.34% formatted

Make sure to notice that PowerShell will take the decimal amount and automatically convert the percentage for you. Thus, if you want to display 12%, you have to pass in 0.12.

Hex

Next up on the list is Hexadecimal notation. PowerShell supports two methods for doing Hex values. In the first, it will take a standard number (base 10) and convert it to hexadecimal then display it.

"X0 0x{0:X0} formatted" -f 1234

Result:
X0 0x4D2 formatted

In this case we passed in the number 1234. PowerShell converted it to hex then displayed it.

What if the value were already in hex format though, and we just wanted to display it? In PowerShell, we indicate a number is in hex by placing a 0x in front of it. So we just pass in our number with 0x in front to the string.

"X0 0x{0:X0} formatted" -f 0x4D2

Result:
X0 0x4D2 formatted

When PowerShell saw the 0x on the front of 0x4D2, it knew this value was already in hex format and didn’t try to convert it, it simply displayed our value.

Decimal

The name of the next formatter we’ll look at is Decimal. It’s a bit misnamed though, because it’s really just for formatting integer based numbers. As a matter of fact, if you try use with a non integer value, such as 33.42, it will error out.

Let’s look at the most basic form of Decimal.

"D0 {0:D0} formatted"   -f 123

Result:
D0 123 formatted

Pretty simple, it just displays the value. So you can guess D is the formatter for decimal, but what is D0? The number after the D indicates how many spaces we want to zero pad to.

In other words, we want the string to be a certain number of characters long, so the number indicates that length. It will then put zeros to the left to pad it out. Let’s look at this example to make it clear.

"D8 {0:D8} formatted"   -f 123

Result:
D8 00000123 formatted

In this case, the D8 indicated we wanted eight characters in decimal formatting. PowerShell converted 123 to a string that was three characters long, so it put five zero’s in front to make the total length eight.

You can also add the placeholder comma value formatting to make a value a certain width wide. In these two examples, the first will act like a Number format. The second though will let you use leading zeros, but still set the total space.

"D0 {0,9:D0} formatted" -f 123
"D0 {0,9:D6} formatted" -f 123

Result:
D0       123 formatted
D0   0000123 formatted

In the first example, it made the output nine characters wide by placing six spaces in front of the 123. In the second example, it first made the 123 six characters by placing 000 on front, resulting in 000123.

It then took the resulting 000123 and made that nine wide by placing three spaces in front. As you can see, PowerShell is very flexible when formatting this way.

A reminder, as stated earlier Decimal is only for integers. If I were to try using -f 123.1 as an input it would error out.

Custom Date Formatting

In addition to the other formats, PowerShell provides the ability to create custom date outputs. You do so using these characters, note they are case sensitive.

M / MMOne or Two character month number
d / ddOne or two character day of the month number.
yy / yyyyTwo or four digit year number.
h / hhOne or two digit hour of the day in 12 hour format
H / HHOne or two digit hour of the day in 24 hour format
m / mmOne or two digit minute of the hour
s / ssOne or two digit second of the minute

Let’s see these used in a series of examples.

"Today is {0:M/d/yy}."                 -f $(Get-Date)
"Today is {0,10:MM/dd/yyyy}."          -f $(Get-Date)
"Today is {0,10:dd/MM/yyyy}."          -f $(Get-Date)
"Today is {0,10:yyyyMMdd}."            -f $(Get-Date)
"Today is {0,10:MM/dd/yyyy hh:mm:ss}." -f $(Get-Date)
"Today is {0,10:MM/dd/yyyy HH:mm:ss}." -f $(Get-Date)

Result:
Today is 7/18/21.
Today is 07/18/2021.
Today is 18/07/2021.
Today is   20210718.
Today is 07/18/2021 04:59:56.
Today is 07/18/2021 16:59:56.

In all of these, I passed in the current date (as I’m writing this) using Get-Date, but any date based variable would have worked.

In the output I’ve arranged the date parts in a variety of common manners. You can use these or create your own custom formats. For example you may wish to use a dash instead of a slash to separate the date parts.

Custom Number Formatting

Let’s say you lived in London, where the pound was your default currency. But you are part of a multinational company and need to produce output to send to your coworkers in the United States. You don’t want to have to change your computer to a US language just to get the $ symbol.

You can fix this by using custom formatting. In these examples, when it sees a character such as the $ it will just keep it in the output. When it sees #, (a pound sign followed by a comma) it will know to use commas in the output.

When it sees just a # sign it will put a number there if it has one, otherwise a space, and when it sees 0 it will put a number from the passed in data, or a zero if there is no number there. These examples will clarify it.

Note each one is on it’s own line, WordPress is wrapping the -f part to the next line for space reasons. Additionally, in this and other examples I’ve chosen to add spaces to line up the demos for readability, this isn’t a requirement and you can format however you need.

"Custom 0, 25 $ #,##0.0000  = {0,25:$ #,##0.0000} " -f 123456789.012000005
"Custom 0, 25 $ #,##0.0000  = {0,25:$ #,##0.00} "   -f 123456789.012000005
"Custom 0, 25 $ ##0.0000    = {0,25:$ ##0.00} "     -f 123456789.012000005

Result:
Custom 0, 25 $ #,##0.0000  =        $ 123,456,789.0120
Custom 0, 25 $ #,##0.0000  =          $ 123,456,789.01
Custom 0, 25 $ ##0.0000    =            $ 123456789.01

Using Formatting with Variables

It’s possible to create a formatted value, then assign that to a variable. Let’s take a look at this slightly more complex example.

$vTday = "{0,8:N0}" -f 134567
$vYest = "{0,8:N0}" -f 23546

$tday = "{0:MM/dd/yyyy}" -f $(Get-Date)
$yest = "{0:MM/dd/yyyy}" -f $((Get-Date).AddDays(-1))

$output = "Visitors to ArcaneCode.com`r`n"
$output += "$tday had $vTday visitors`r`n"
$output += "$yest had $vYest visitors"
$output

Result:
Visitors to ArcaneCode.com
07/18/2021 had  134,567 visitors
07/17/2021 had   23,546 visitors

The first two lines you’ve seen a few times by now. I’m simply taking a number, formatting it with commas and making it eight spaces wide.

The next line you’ve seen as well, I take the current date, format to MM/dd/yyyy format and assign to $tday.

The $yest line is slightly more complex, but only because I’m doing some date math. The (Get-Date) will get the current date, but create a date object from it. Essentially I have a date variable type but without a variable name.

Because I have a date datatype I can employ a method of the date datatype, AddDays. This will let me add a number of days to the date, or if you pass in a negative value subtract days. Thus AddDays(-1) will give me yesterday’s date. I then have to wrap it all in $() so PowerShell will evaluate the entire expression before passing it back to the placeholder.

Finally I’m using the += operand to concatenate several strings together for a nice output. Note the formatted dates, and how the visitors number right aligns nicely.

Conclusion

While string interpolation makes creating output strings easy, knowing how to use placeholders can make creating formatted output even easier, allowing you to create output with numeric values that align neatly, or creating custom date formatting.

The demos in this course came from my Pluralsight course PowerShell 7 Quick Start for Developers on Linux, macOS and Windows, one of many PowerShell courses I have on Pluralsight. All of my courses are linked on my About Me page.

If you don’t have a Pluralsight subscription, just go to https://pluralsight.com. At the top is a Try For Free button you can use to get a free 10 day subscription to Pluralsight, with which you can watch my courses, or any other course on the site. Once there just search for my name, Robert Cain, to see all the courses I have.

Introduction to the SQL Server Mobile Report Publisher – Now Live on Pluralsight

My latest Pluralsight course, Introduction to the SQL Server Mobile Report Publisher, just went live!

The Mobile Report Publisher is a powerful, under-appreciated tool that lets you quickly and easily create reports for not just the web, but for a variety of platforms such as Apple’s iOS and Google Android.

In this course, Introduction to the SQL Server Mobile Report Publisher, you’ll learn to quickly and easily create dashboards for the web, as well as mobile devices such as phones and tablets.

First, you’ll explore how to use the Report Publisher designer to create the layout of the dashboard.

Next, you’ll see how to create datasets and bind them to the dashboard.

Finally, you’ll learn advanced features such as filters to limit the data on the dashboard, as well as drillthroughs to launch a detailed report or web page.

When you’re finished with this course, you’ll have the skills and knowledge of the Mobile Report Publisher needed to create dashboards on multiple platforms.

What’s that you say? You don’t have a subscription but want to watch my course? Hey, no problem. Pluralsight has a 10 day free trial. Just go to https://www.pluralsight.com/pricing/free-trial and sign up!

Fun With PowerShell Strings

Introduction

PowerShell has some of the best, most flexible string handling of any language I’ve used. In this post we’ll look at some string basics, then some of the features that make it special.

Note in these demos I’m using PowerShell Core 7.1.3 and VSCode. Everything here should also work in the PowerShell 5.1 and the PowerShell IDE.

Basic Strings in PowerShell

Strings in PowerShell can be denoted with either single quote marks or double quote marks.

"This is a string"
'This is a string too!'

If you want to see the result, simply highlight the strings and press either F8 in VSCode, or F5 in the PowerShell IDE.

This is a string
This is a string too!

Multiline Strings, aka Here Strings

PowerShell has the ability to create a multiline string, also known as a “here” string. To create a here string, use an @ sign, followed by a quotation mark (either single or double) then hit Enter.

On the next lines, enter the value for your string. Finally hit Enter, then on the next line put the closing quotation mark then another @ sign.

This is important, the closing quotation mark and @ sign must be the first two characters on the line. If you attempt to indent them in any way the technique will not work!

$heretext = @"
Some text here
Some more here
     a bit more

a blank line above
"@

$heretext

Some text here
Some more here
     a bit more

a blank line above

Again, this works with single or double quotes. So what’s a common use?

One common thing I use it for is SQL queries. Here’s an example in a traditional language.

$sql = 'SELECT col1' `
     + '     , col2' `
     + '     , col3' `
     + '  FROM someTable ' `
     + ' WHERE col1 = ''a value'' '

Note the single ` (back tick) mark at the end of each line. This is the line continuation character in PowerShell.

As you can see, each line has to be connected with + signs. Now let’s contrast it with a here string version.

$sql = @'
SELECT col1
     , col2
     , col3
  FROM someTable
 WHERE col1 = 'a value'
'@

This is not only much more readable, but easier to work with. You can develop your SQL query in SQL Server Management Studio, or Azure Data Studio, then simply cut and paste it into PowerShell.

Another thing to notice, you can embed single or double quotes within a here string, and PowerShell will ignore them as denoting another string.

Embedded Quote Marks

If you need to embed a quotation mark in a string, you can simply double them up.

"ArcaneCode said ""PowerShell is awesome!"" and the crowd applauded."

ArcaneCode said "PowerShell is awesome!" and the crowd applauded.

This technique works with single quote marks as well. For example one’s used in common words such as shouldn’t.

'You shouldn''t miss the blog posts at arcanecode.com'

You shouldn't miss the blog posts at arcanecode.com

String Interpolation

You may be wondering what the difference between single and double quotes is. Double quotes allow you to use something called string interpolation. String interpolation will take any variables embedded in the string and expand them before returning the string.

Here’s a simple example. First we get the number of items in the current folder. Then we copy the current folder location into another variable. Finally we create a string with these variables in it, surrounding the string in double quote marks.

$items = (Get-ChildItem).Count 

$loc = Get-Location

"There are $items items are in the folder $loc."

There are 3 items are in the folder C:\PSCore-QuickStart.

As you can see in the result (the bottom line) it has taken the value in $items, a 3, and expanded it in the return result.

Likewise, it has taken the value in $loc and expanded it to the name of the current folder.

Now see the result if single quote marks had been used.

$items = (Get-ChildItem).Count 

$loc = Get-Location

'There are $items items are in the folder $loc.'

There are $items items are in the folder $loc.

With single quotes, the string interpolation engine does not kick in.

As a rule of thumb then, only use double quotes if you have to have interpolation. Otherwise use single quotes so you don’t incur the (admittedly minimal) amount of time for the string interpolation engine to needlessly process the string.

Escape Characters

PowerShell also has the concept of escape characters. These are special characters you can embed in the string that provide additional formatting instructions.

Note that escape characters only work inside double quote marked strings. If you use single quotes for your strings, it will just display the escape character.

There are four that are the most commonly used. Tab, Carriage Return, Line Feed, and escaping the $ (dollar sign) so it may be used.

Escape characters are preceded by a back tick ` then the character. Let’s look at the tab, which is a `t.

"`tThis is tabbed in"

        This is tabbed in

The next is the carriage return line feed sequence, which is `r`n.

"Here is some text`r`nAnd some more text`r`n`r`nA blank line before this"

Here is some text
And some more text

A blank line before this

You would most commonly use this when looping over data and building a new output string.

The final escape character we’ll look at allows you to embed a $ character in an double quoted string. Simply use a back tick followed by the dollar sign.

"The `$items variable is $items"

The $items variable is 3

We’ve only covered four here, but note there are many more escape sequences you can use in PowerShell.

Conclusion

In this post you saw all kinds of cool things you can do with PowerShell strings. With this knowledge you can take your PowerShell scripts to the next level, and be able to generate some creative output with your own PowerShell strings.

The demos in this course came from my Pluralsight course PowerShell 7 Quick Start for Developers on Linux, macOS and Windows, one of many PowerShell courses I have on Pluralsight. All of my courses are linked on my About Me page.

If you don’t have a Pluralsight subscription, just go to https://pluralsight.com. At the top is a Try For Free button you can use to get a free 10 day subscription to Pluralsight, with which you can watch my courses, or any other course on the site. Once there just search for my name, Robert Cain, to see all the courses I have.

Fun with PowerShell Get-Random

Introduction

Many people know about PowerShell’s Get-Random cmdlet. Using it you can generate a random value. For example:

Get-Random

Will output a value such as:

64031951

But did you know there’s other features of Get-Random?

Numeric Ranges

With Get-Random you can lock down the return result to a specific range. You can specify a minimum value as well as a maximum.

Get-Random -Minimum 100 -Maximum 200

122

You can run it numerous times and the return value will always be between 100 and 200.

You don’t have to use both the minimum and maximum values, you can just use one or the other.

While be default it returns an unsigned 32 bit integer, you can also use it to return a random floating point value.

Get-Random -Minimum 10.5 -Maximum 20.9

11.9004625960255

Get-Random and Arrays

You can also use Get-Random with Arrays. Let’s say you have an array of integer values. You can pipe it through Get-Random and it will pick one value from the array for you.

$array = 1, 3, 5, 7, 9
$array | Get-Random

7

The cool thing about this is it works with any array. Let’s say you have an array of states, and want to pick a state at random.

$array = (
  'Alabama', 'Alaska', 'Arizona',
  'Arkansas', 'California', 'Colorado',
  'Connecticut', 'Delaware', 'Florida',
  'Georgia', 'Hawaii', 'Idaho',
  'Illinois', 'Indiana', 'Iowa'
)
$array | Get-Random

Florida

This also works with arrays that hold a collection of objects. Let’s get a collection of file objects from our C:\Temp folder and let it pick one for us.

$files = Get-ChildItem -Path "C:\Temp"
$files | Get-Random

    Directory: C:\Temp

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----           1/14/2021  2:31 PM                curl-7.74.0

Getting More Than One Random Item

Get-Random also has a -Count parameter which you can use to get multiple values back. Let’s use our state example, and let it return five states.

$array = (
  'Alabama', 'Alaska', 'Arizona',
  'Arkansas', 'California', 'Colorado',
  'Connecticut', 'Delaware', 'Florida',
  'Georgia', 'Hawaii', 'Idaho',
  'Illinois', 'Indiana', 'Iowa'
)
$array | Get-Random -Count 5

Idaho
Alaska
California
Delaware
Colorado

This works with any type of array, or just random integers.

Get-Random -Count 3

1981714362
1664558041
1474367023

SetSeed

Get-Random has one more parameter, -SetSeed. You can pass in a value, and when you do Get-Random will always return the same result for that seed.

Get-Random -SetSeed 100

1881691673

No matter how many times you run Get-Random, as long as you use the same seed value, it will always return a result of 1881691673. This also works with other types of arrays such as the array of states we used earlier.

$array = (
  'Alabama', 'Alaska', 'Arizona',
  'Arkansas', 'California', 'Colorado',
  'Connecticut', 'Delaware', 'Florida',
  'Georgia', 'Hawaii', 'Idaho',
  'Illinois', 'Indiana', 'Iowa'
)
$array | Get-Random -SetSeed 33

Illinois

Again, run this as much as you want and with the same SetSeed value it will always return the same state, in this case Illinois.

So why use SetSeed? One main use it testing. You want to create a set of reusable tests, for example using Pester, and want to validate you always get the same value back from your array.

Conclusion

In this post we saw how to use Get-Random for a variety of purposes. Hopefully you’ll find it as useful as I do!

I have many PowerShell related courses on Pluralsight. All of my courses are linked on my About Me page.

If you don’t have a Pluralsight subscription, just go to https://pluralsight.com. At the top is a Try For Free button you can use to get a free 10 day subscription to Pluralsight, with which you can watch my courses, or any other course on the site. Once there just search for my name, Robert Cain, to see all the courses I have.