Fun With PowerShell Classes – Static Properties and Methods

Introduction

Over the last few articles we’ve been covering PowerShell objects. The first article in the series, Fun With PowerShell Classes – The Basics, covered the basics of using of the PowerShell class construct introduced in PowerShell version 5.

If you’ve not read it I’d suggest you do so now as we’ll be building on it in this article, as well as in the next two, as we explore the advanced capabilities of PowerShell classes. In this post we’ll cover the concept of static properties and methods.

Let me mention that for all of the examples we’ll display the code, then under it the result of our code if applicable. 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.

At the end of the line in many code samples you may notice a backtick ` character. This is PowerShell’s line continuation character. The blog formatting has a limited width, so using the line continuation character makes the examples much easier to read. My post Fun With PowerShell Pipelined Functions dedicates a section to the line continuation character if you want to learn more.

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.

Starting Point

Just as a refresher, here is the class we originally developed.

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()
  }

}

We can create a new instance of the class by calling the static new method built into all PowerShell defined classes. Once created we can start assigning values to its properties.

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

With that reminder, let’s start diving in to some advanced features offered by classes.

Static Properties

In a previous post on creating PowerShell objects from C# code, I introduced the concept of static properties and methods. A static property or method is one that can be called without having to create a new instance of an object from the class.

To call a static method or property, use the name of the class in brackets, then two colons, then the name of the property or method you want to call. In fact, you’ve already done this in creating a new instance of a class when you used [Twitterer]::new().

It’s easy to create your own static properties and methods. Let’s create a new version of our class, and name it TwittererRedux. (Redux is a fancy word meaning ‘bring back’.) Then, we’ll add a new static property to it.

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

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

  # Static Properties
  static [string] $Version = '2022.01.07.002'

  # 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()
  }

}

In the properties area we add one new property, Version. At the front we added the keyword static. This, of course, is the indicator this property is available even without creating a new instance of the class.

Having a version number is a fairly common and useful thing to include in a class. Let’s see it in use. First though, make sure you’ve executed the above class definition for TwitterRedux to make sure it is memory.

[TwittererRedux]::Version

Result:

2022.01.07.002

Other examples of things you might wish to manifest as static properties include the author name, contact information, copyright, or perhaps a link to documentation or github where your class is stored.

Let’s turn now to the creation of a static method.

Static Methods

In our original version of the class we have a method called OpenTwitter. This accessed the objects function TwitterURL, which returned the formatted Twitter URL for the users handle, stored in the objects TwitterHandle property. Finally it opened up the Twitter page in the default browser.

It could be useful to have a function that would do something similar, only without having to go to the effort of creating a class, then populating the TwitterHandle property just so we could call this function.

We’ll do so by adding a new, static function to the class.

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

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

  # Static Properties
  static [string] $Version = '2021.01.07.002'

  # 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()
  }

  # Can launch a twitter page without instantiating the class
  static [void] OpenTwitterPage([string] $TwitterHandle)
  {
    # Note here we cannot call the $this.TwitterUrl function
    # because no object exists (hence no $this)
    $url = "http://twitter.com/$($TwitterHandle)"
    Start-Process $url
  }

}

We call the new method similar to the way we accessed our property, when we called the new method to create the class.

[TwittererRedux]::OpenTwitterPage('ArcaneCode')

If your coding went well, your default browser should open to my Twitter page (or whosever you passed in).

Restrictions on Static Properties and Methods

There is one restriction when working with static properties and methods, but it is one you need to know about.

> Static properties and methods must be self contained, and cannot reference other properties and methods of the class.

This makes sense if you think about it a moment. You are only accessing the class definition, i.e. the blue print. Normal properties and methods only exist once an object has been created from a class. While it makes sense, it isn’t intuitively obvious so I wanted to point it out.

A Note on Defining Classes

I just wanted to point out a little "gotcha" when working with classes. Within a single PowerShell script (i.e. PS1 file) you can only define a class once. Normally this is not a big issue.

However, if you are developing a class it’s possible you might want multiple versions of it. For example, at the top of the script you might want your original version.

Under it you might want basically the same code, but you’ve added a new method, or perhaps changed the code to an existing method. You want to do this for testing, so you can compare one version versus the other.

PowerShell, or more precisely VSCode or the PowerShell IDE, will generate an error for the second, third, or more versions in your code warning you it has already been defined.

The fix is pretty simple, you could just comment out all but one of the class definitions, leaving the one you are working with uncommented. Alternatively, you could just create multiple PS1 files and work with different versions in each. VSCode is especially nice for this as it lets you have your PS1 files side by side.

Conclusion

Static properties and methods are not difficult to implement, and can be quite useful. As you create your classes, think about situations where they may benefit from a static property or method.

In the next installment of this series we’ll continue our examination of the PowerShell class type by diving into overloads.

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