In computer programming lingo, you will often hear about arrays, which are collections of different types of data. While arrays do exist in PowerShell, there's another type of collection used far more commonly, called, well, collections.

The distinctions between the two are not important in PowerShell - in fact, PowerShell will often just convert the two types of data on the fly without you ever even noticing.

What we'll be doing for this tutorial is creating a collection with information about the computer you are sitting at right now.

So, with that said, let's go ahead and fire up the Windows Terminal (or PowerShell if you're on an older OS) and get down to business!

Collecting some information

There is a built-in command in Windows PowerShell called Get-ComputerInfo which will pull down a wealth of information about a computer. Go ahead and try it out! Enter into your Terminal:

What you will get will resemble this:



        

Obviously, this amount of information is pretty difficult to sort through, but luckily I have some idea of where we're going with this.

You may have noticed that that command took a few moments to run. On older, slower hardware it might have even taken an annoyingly long time. What we want to do, then, is to store all of that data somewhere, and to do that, we're going to create our very first collection. Enter the following command:

Now you'll see that the command still runs, but you do not get the output for it. To see our shiny new collection, just enter into the Windows Terminal:

What the heck is $ doing here?

In PowerShell, you assign variables by having a dollar sign (`$`) followed by what you want your variable to be named. A variable is simply some data you want to save for later use. In the previous example, we are storing the output of the `Get-ComputerInfo` command to our variable for use later on in this tutorial! Variables don't (usually) exist outside of the current terminal window, though, so you have to recreate them after you close your session.

You'll see that it's all the same information, but you can just load it up without re-running the command over again.

But before we move on, let's take in what we are looking at. On every line, the left-hand column contains a Property and the right-hand column contains a Value. In the next section, we'll go over how to use these Properties to fetch specific data.

Sifting through the crud

We truly do not need most of this data to know a good amount of information about our computer. Try out the following commands to try to sort through it:

With these five commands, you'll see that we can now easily scrape information like the OS version, the name of the current user, the name of the computer, the CPU, and the timezone set on the PC.

However, this can be streamlined even further, like so:

On my machine, the output looks like this:



        

Now we're getting to some neatly-organized data! But what is going on with the "|" symbol in there?? That character is called a pipe -- it takes whatever comes before it, and processes it to whatever comes after it. So we are taking the values of the $myComputer collection and handing it over to the Select-Object command for sorting.

Renaming Properties

I think these names aren't particularly helpful, though, so if we want to refer back to this stuff later when actually writing scripts, we might want some more obvious names for this stuff. With some clever re-arranging, we can rename some of these properties. Try this:

What we did here was we created a new Property named "WindowsVersion" and assigned the "OsName" Property's value to it.

What is $_ doing?!

The $_ expression here simply refers to the piped object -- when we aren't modifying any of the data, we can refer to it by just typing $myComputer.OsName, but since we are, we are Piping ( | ) the collection to a Select-Object command to create the custom object. When the collection is piped into another command, $_ functions as a stand-in for it.

Since our single-line command is about to get a bit long, we're going to reformat it a bit. See this article on formatting for more information. So now we can try this:

Which gives me this output:



        

Which, unfortunately, seems to have broken the "CPU" object! Why??

If we refer back to the output of our earlier command, we'll see something interesting. In the CsProcessors field, {Intel Xeon Processor (SierraForest)} is inside curly brackets. What that means is that CsProcessors is ALSO a collection inside the $myComputer collection. Since the Expression is expecting a single object, PowerShell doesn't know how to handle it and generates junk data. Let's go ahead and view the CsProcessors Collection with:

On my machine, I got:



        

So, what we really want here isn't the entire collection, we just want the Name object! So let's try this:

Which will now return the correct value for the CPU Property.



        

Creating a custom Collection

Now we are able to modify our strings, but if we want to refer back to these new values without these gigantic commands, we will want to store them as a collection all their own. So, we can create a new Collection the same way we created this one - by just defining it:

Now we can refer back to our Collection using the names we defined ourselves:

Bonus: Modifying Collections and Basic ForEach-Object Loops

PowerShell allows you to modify some collections, assuming you generate them to be modified. The Select-Object command, sadly, returns a read-only list that cannot be modified.

How can we convert what we already have into a modifiable list, and then how would we add to it? Let's see how we can do that with a ForEach-Object loop, which will go through every object inside of a Collection and perform commands when asked to. There will be a whole other section just for ForEach-Object loops, but they are extremely useful, so we'll just have a basic rundown now.

But first, we need to make sure that we assign the correct Collection type by creating a new Collection like so:

Now that we have correctly defined $computerCollection, we can start adding to it. First, let's take the info we already have and get it re-added to the new Collection:

What's happening here is that we are taking the $customComputerInfo and piping it to the ForEach-Object command. From there, the ForEach-Object then loops through each object in the Collection.

Much like in the renaming example earlier, we are now using the expression $_ to stand in for each object. We are then using the .Add() method to add each one to the new $computerCollection list.

Now, let's say we wanted to add a new value to our list called "Time" and we just wanted to assign the value of the Get-Date command, we could do it like so:

And that's it! Feel free to play around making your own Collections with custom objects and see what you can do.

Conclusion

This tutorial went through a lot of information - but don't worry, there will be a lot of reinforcement on using collections, arrays, and loops to come! But now you should understand at least the following:

  1. How to assign the output of a command to a new variable.
  2. How to pick out a certain property from a collection.
  3. How to rename properties when generating output.
  4. How to create a fully custom collection and add objects to it.