Classes in PowerShell

I’ve noticed that a lot of admins learning PowerShell tend to use global variables and pass things around to functions, if they use functions at all. Sometimes all you need are classes to make things cleaner and easier to manage. Classes can be intimidating to newer developers or folks who only write occasionally for admin purposes. I hope I can make them less intimidating.

The first nice thing about classes is that making changes becomes less of a hassle, especially in large programs. Now if you want to change how a score is calculated in a game you just add the math to the class with no need to change code elsewhere. You can do that with functions also but classes are cleaner. Now the real power. If you decide to allow multiple players in your game at a later date you can just instantiate new players as I show in the example below. Try tracking multiple users with functions and globals.

The example code below contains two simple classes, one for keeping score and another showing a calculator. This code can be saved and ran on any platform. I am working in Linux mostly. For a bigger example see my post on creating a restful server in PowerShell.

class Score {
    [string]$Name = "System"
    [int]$total = 0 # init our total.
 
    AddScore([int]$arg) {
        $this.total += $arg
    }
 
    DecScore([int]$arg) {
        $this.total -= $arg
    }
    PrintScore() {
        Write-Host "$($this.name)'s Score: $($this.total)"
    }
}
 
 
class Calc {
    [int]$total = 0  # init our total.
 
    Add ($arg) { $this.total = $this.total + $arg }
   
    Sub ($arg) { $this.total = $this.total - $arg }
 
    Mult ($arg) { $this.total = $this.total * $arg}
 
    Div ($arg) {
        try {
            $this.total = $this.total / $arg
        } catch [Exception] {
            "Bad parameters: total = {0} and arg = {1}" -f $this.total, $arg
        }
    }
 
    Clear() { $this.total = 0 }
 
    PrintTotal() {
        Write-Host "Calc: " $this.total
    }
}
 
 
# =============================
# Instantiate our Score keeper.
# =============================
 
$sysScore = New-Object Score
 
$sysScore.AddScore(10)
$sysScore.DecScore(5)
 
$sysScore.PrintScore()
 
$sysScore.AddScore(10)
 
$sysScore.PrintScore()
 
<# I can keep score in multiple instances 
independently in the same script. Let's add a
second player and name him Bob who is playing 
against the computer. #>
 
$bobsScore = New-Object Score
$bobsScore.name = "Mr. Bob"
 
$bobsScore.AddScore(5)
$bobsScore.DecScore(1)
 
$bobsScore.PrintScore()
 
$bobsScore.AddScore(30)
 
$bobsScore.PrintScore()
Write-Host "Bob wins!"
 
# =============================
# Instantiate our calculator.
# =============================
 
$myCalc = New-Object Calc
 
$myCalc.Add(5)
$myCalc.Add(45)
$myCalc.Sub(5)
 
$myCalc.PrintTotal()
 
$myCalc.Clear()
 
$myCalc.total = 5
$myCalc.Mult(5)
 
$myCalc.PrintTotal()
 
$myCalc.Div(5)