Fun With PowerShell Classes – The Basics

Introduction

In the last few posts we looked at the use of Enums, a technique closely associated with classes. In this post we’ll start looking at classes themselves. We’ll open with some terminology, then look at our first class.

For the next post in this series I plan to do a history lesson on the use of PSCustomObject. Prior to the addition of classes in PowerShell 5.0, this was the technique needed to create your own customized objects. From there we’ll return to the modern area and get into some advanced class techniques.

First let me mention that 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.2, 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 any variable by highlighting it and using F8/F5.

Terminology

If you are familiar with object oriented terminology, then this short overview will be familiar to you. However, many who come into PowerShell scripting do not come from a coding background. It’s worth taking a few paragraphs, then, to explain some common terms that will be used in this and future articles.

A class is code that is used as a blueprint to create an object variable in memory. In fact, all variables in PowerShell are objects, even built in ones like strings or integers. Their classes are already defined and ready to be used in the core PowerShell libraries.

The act of creating a new object from a class is called instantiation. You can instantiate multiple variables from the same class.

In most object oriented discussions, the classic example compares a class to a blueprint for a house. From that single blueprint a home builder can create an entire neighborhood of houses.

Each house has properties that can be set to make the houses different from each other, even though they are built from the same blueprint. House color, trim color, number of cars the garage will hold, are all properties that can be set on a per house basis.

Likewise, a PowerShell class has properties. These are made available through variables, and may be things like first name, last name, address, birth date, number of pets, or any number of other items that would apply to this instance of an object built from your class.

A house blueprint may also have tasks assigned to it. "Get building permit from city", for example, or "paint the trim". In the PowerShell world, a class can also have tasks assigned to it. These are created by using functions.

If you aren’t familiar with functions yet, you need to brush up. You can start with my series Fun With PowerShell Functions, then continue through the next few posts which move into advanced functions and pipelined functions.

When it comes to classes, we call these built in functions methods. A method is designed to act on the data within the function itself.

A simple example, you may have three properties, first name, middle name, and last name. You could create a method (in the form of a function) called full name, which concatenates the three parts of the name together, correctly formatting for times when a middle name is absent.

Methods in a class can return a value, but do not have to. We’ll see examples of both in this article.

Also be aware there are special types of properties and methods that are called static properties and static methods. These are pieces of code that PowerShell can execute from the class itself, without creating an object from that class.

We’ll see examples of how to create and use these in our future post on advanced classes, but I wanted to mention them as PowerShell classes have a static function we’ll need to use in order to instantiate new objects.

This short intro just hits the tip of the iceberg when it comes to object oriented methodology, entire books have been written on the subject. Hopefully it provides enough information to get you started.

So now that we’re all on the same page when it comes to terminology, let’s go create a class.

A Very Simple Class

This first example will be very simple. Take a look, then we will go over its parts.

class Twitterer
{
  # Create a property
  [string]$TwitterHandle

}

We begin the definition with the keyword class, followed by what we wish to name our class. In my previous articles on enums we used Twitter data as an example, so let’s stick to that.

After the name of the class we need an opening squiggly brace, and a closing one at the end. In PowerShell squiggly braces are used to define a scrpt block. You’ve seen these before, functions, foreach, if statements and more all use script blocks. Classes are no different, everything in the script block is the class definition.

With classes, as with most script blocks, it’s not necessary to put the opening squiggly brace on the next line, many use class Twitter { on a single line. I just feel having the squiggly braces vertically aligned makes things easier to read.

Within the class I have defined a single property, $TwitterHandle. Before the name of the variable I have indicated the variable type in brackets, [string]. Unlike regular PowerShell, all properties must be strongly typed.

Let’s create, or instantiate, a new variable from our class (after highlighting the class definition and using F8 or F5 to get it into memory).

$twit = [Twitterer]::new()

This syntax may look a bit odd, so let me explain. When we created our class we defined a single property. Anytime we define a class, though, PowerShell adds extra properties and methods behind the scenes.

One of those methods is new. New is a static method that can be called without the need to instantiate a new object, which is fortunate as it is the way we get new objects from our class.

To call a static method, we use the name of the class in brackets, followed by two colons, then the name of the static method. In PowerShell, to call a method you always have to use parenthesis after the name of the method even if it takes no parameters. This is unlike a regular function in PowerShell.

Finally, we assign our newly instantiated object to the variable $twit.

We can now access the properties (and methods) in our object by using what is formally known as dot notation. If you’ve done any PowerShell coding then you’ve likely used it a million times by now without realizing it had a formal name.

You simply use the name of our object, a period, then the name of the property, as in $twit.TwitterHandle. Of course if we run this right now, we won’t get anything back. This is because our variable is empty when the class is created. So let’s assign it a value.

$twit.TwitterHandle = 'ArcaneCode'
$twit.TwitterHandle

Result:

ArcaneCode

It’s that easy, we can use it like any other variable. Note one thing, when we created the property we used the $ in front of the variable. But outside the class when we reference it as a property the $ is omitted.

Default Values for Properties

There will be many times when you write a class in which you want to have some, or perhaps all, of its properties already populated with values. This will make it easier for your end user, especially for properties where the majority of the time the user can get by with the default value.

Creating a default value is simple, when you create the property you simply assign it a value.

class Twitterer
{
  # Create a property
  [string]$TwitterHandle

  # Create a property and set a default value
  [string]$Name = 'Robert C. Cain'
}

Here a second property, Name, has been added. After its declaration I simply assigned it a name (mine in this case) just like I would assign any value to a variable.

Now let’s create a new instance and examine the value in our Name property.

$twit = [Twitterer]::new()
$twit.Name

Result:

Robert C. Cain

Of course just because we’ve provided a default value doesn’t mean we can’t change it.

$twit.Name = 'Mr. Code'
$twit.Name

Result:

Mr. Code

Our First Method

Now that we’ve added properties, it’s time to add a little functionality with our first method. A class method in PowerShell works just like a function, only without the need for the function keyword. For this example, we’ll add a new method that takes the value in the $TwitterHandle property and return the URL to that handles Twitter page.

class Twitterer
{
  # Create a property
  [string]$TwitterHandle

  # Create a property and set a default value
  [string]$Name = 'Robert C. Cain'

  # Function that returns a string
  [string] TwitterURL()
  {
    $url = "https://twitter.com/$($this.TwitterHandle)"
    return $url
  }

}

The URL to a users Twitter account is simple, it is just twitter.com followed by the users twitter handle. Now, you might think you could just use $TwitterHandle to create this, but not so.

We need to let PowerShell know to use the TwitterHandle for this particular object. That’s where the $this variable comes into play.

$this is a built in variable which simply means "the current object I am running this code in". Using $this, I can reference any property or other method within this instance of my class.

I also want to point out that after the name of our method we added parenthesis. This is an indicator to PowerShell we are defining a method and not a property. In this case we are not passing in any values to our method, so they are empty. It is possible though to pass values in, which we’ll see in a future post.

Finally, note that my function, just like properties, is strongly typed. Since my URL is in the form of a string, I used [string] to indicate the data type being returned by this function.

$twit = [Twitterer]::new()
$twit.TwitterHandle = 'ArcaneCode'
$myTwitter = $twit.TwitterURL()
$myTwitter

Result:

https://twitter.com/ArcaneCode

No Return

In my previous example, our method returned a value. There will be cases though when you simply want your method to do something, and not return any values. For those times, we can use the return type of void.

class Twitterer
{
  # Create a property
  [string]$TwitterHandle

  # Create a property and set a default value
  [string]$Name = 'Robert C. Cain'

  # Function that returns a string
  [string] TwitterURL()
  {
    $url = "https://twitter.com/$($this.TwitterHandle)"
    return $url
  }

  # Function that has no return value
  [void] OpenTwitter()
  {
    Start-Process $this.TwitterURL()
  }

}

I’ve added a new method, OpenTwitter. Before it I used [void] to let Twitter know this particular method won’t be returning any data.

Within the function I call the PowerShell cmdlet Start-Process. This cmdlet will take the value passed into it and attempt to run the application that corresponds to it. For example, if I had passed in the file name to an Excel spreadsheet, PowerShell would have attempted to launch Microsoft Excel and open that file.

In this case we’re passing in a URL, so PowerShell will launch your default browser and open the Twitter webpage for that user.

Also note we used the $this built in variable to call the TwitterURL method for this current instance of our object, here $twit.

To run it we only need to call our method.

$twit = [Twitterer]::new()
$twit.TwitterHandle = 'ArcaneCode'
$twit.OpenTwitter()

If all went well your web browser should open to the Twitter page for the associated user held in the $TwitterHandle variable.

Conclusion

In this opening article we covered some of the basics of using classes in PowerShell. Even with this limited information you should be able to start creating useful classes. In future articles we’ll dive deeper into using classes in PowerShell.

I want to mention, as I write this in December 2021, that my posts for the rest of the year will diverge as I want to give a little gift and share some of my favorite things I’ve found on the internet this year. I’ll pick this series back up in January of 2022.

The demos in this series of blog posts 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.