PS Classes and Object-Oriented Programming

PowerShell 5.0 introduced native class support, bringing full object-oriented programming (OOP) capabilities to scripts. Classes let complex data structures and behavior be modeled in one place — combining data (properties) and logic (methods) into a single reusable blueprint. This is the foundation of modern, maintainable PowerShell for enterprise applications.

What Is a Class?

A class is a blueprint. An object is a thing built from that blueprint. Multiple objects can be created from the same class, each with their own data.

  Class: Car (blueprint)
  +---------------------------+
  | Properties:               |
  |   Make    (string)        |
  |   Model   (string)        |
  |   Speed   (int)           |
  |                           |
  | Methods:                  |
  |   Accelerate()            |
  |   Brake()                 |
  |   GetInfo()               |
  +---------------------------+
  
  Objects (instances):
  $car1 = [Car]  Make="Toyota", Model="Camry",  Speed=0
  $car2 = [Car]  Make="Honda",  Model="Accord", Speed=0

Defining a Class


class Animal {
    # Properties
    [string] $Name
    [string] $Species
    [int]    $Age

    # Constructor – runs when object is created
    Animal([string]$name, [string]$species, [int]$age) {
        $this.Name    = $name
        $this.Species = $species
        $this.Age     = $age
    }

    # Method
    [string] Speak() {
        return "$($this.Name) says: Hello!"
    }

    # Method
    [string] GetInfo() {
        return "$($this.Name) is a $($this.Species), age $($this.Age)"
    }
}

Creating Objects from a Class


# Create objects
$dog = [Animal]::new("Rex", "Dog", 3)
$cat = [Animal]::new("Whiskers", "Cat", 5)

# Access properties
Write-Host $dog.Name       # Rex
Write-Host $cat.Species    # Cat
Write-Host $cat.Age        # 5

# Call methods
Write-Host $dog.Speak()    # Rex says: Hello!
Write-Host $cat.GetInfo()  # Whiskers is a Cat, age 5

The $this Keyword

Inside a class method, $this refers to the current object (the instance being operated on). It is how a method accesses its own properties.


class Circle {
    [double] $Radius

    Circle([double]$radius) {
        $this.Radius = $radius
    }

    [double] GetArea() {
        return [math]::PI * $this.Radius * $this.Radius
    }

    [double] GetCircumference() {
        return 2 * [math]::PI * $this.Radius
    }
}

$c = [Circle]::new(7)
Write-Host "Area:          $([math]::Round($c.GetArea(), 4))"
Write-Host "Circumference: $([math]::Round($c.GetCircumference(), 4))"

Output:


Area:          153.9380
Circumference: 43.9823

Properties with Validation


class Employee {
    [string]  $Name
    [string]  $Department
    [decimal] $Salary

    Employee([string]$name, [string]$dept, [decimal]$salary) {
        if ($salary -lt 0) { throw "Salary cannot be negative." }
        $this.Name       = $name
        $this.Department = $dept
        $this.Salary     = $salary
    }

    [void] GiveRaise([decimal]$amount) {
        if ($amount -le 0) { throw "Raise amount must be positive." }
        $this.Salary += $amount
        Write-Host "$($this.Name) received a raise. New salary: $($this.Salary)"
    }

    [string] ToString() {
        return "$($this.Name) | $($this.Department) | Salary: $($this.Salary)"
    }
}

$emp = [Employee]::new("Anita Sharma", "Engineering", 75000)
Write-Host $emp.ToString()
$emp.GiveRaise(10000)
Write-Host $emp.ToString()

Output:


Anita Sharma | Engineering | Salary: 75000
Anita Sharma received a raise. New salary: 85000
Anita Sharma | Engineering | Salary: 85000

Inheritance

Inheritance allows a new class to acquire all properties and methods of an existing class and add or override behaviors. The child class inherits from the parent using the colon : syntax.


class Vehicle {
    [string] $Make
    [string] $Model
    [int]    $Year

    Vehicle([string]$make, [string]$model, [int]$year) {
        $this.Make  = $make
        $this.Model = $model
        $this.Year  = $year
    }

    [string] GetBasicInfo() {
        return "$($this.Year) $($this.Make) $($this.Model)"
    }
}

# ElectricCar inherits from Vehicle
class ElectricCar : Vehicle {
    [int]    $BatteryKWh
    [int]    $RangeKM

    ElectricCar([string]$make, [string]$model, [int]$year, [int]$battery, [int]$range)
        : base($make, $model, $year) {
        $this.BatteryKWh = $battery
        $this.RangeKM    = $range
    }

    [string] GetFullInfo() {
        return "$($this.GetBasicInfo()) | Battery: $($this.BatteryKWh) kWh | Range: $($this.RangeKM) km"
    }
}

$tesla = [ElectricCar]::new("Tesla", "Model S", 2026, 100, 600)
Write-Host $tesla.GetBasicInfo()   # Inherited method
Write-Host $tesla.GetFullInfo()    # Child class method

Output:


2026 Tesla Model S
2026 Tesla Model S | Battery: 100 kWh | Range: 600 km

Static Members

Static properties and methods belong to the class itself — not to any individual object. Call them using [ClassName]::MemberName.


class MathHelper {
    static [double] $PI = 3.14159265358979

    static [double] CircleArea([double]$radius) {
        return [MathHelper]::PI * $radius * $radius
    }

    static [double] Hypotenuse([double]$a, [double]$b) {
        return [math]::Sqrt($a * $a + $b * $b)
    }
}

# Use without creating an object
Write-Host "PI = $([MathHelper]::PI)"
Write-Host "Circle area (r=5): $([MathHelper]::CircleArea(5))"
Write-Host "Hypotenuse (3,4):  $([MathHelper]::Hypotenuse(3, 4))"

Output:


PI = 3.14159265358979
Circle area (r=5): 78.5398163397448
Hypotenuse (3,4):  5

Hidden Properties

The hidden keyword marks a property or method so it does not appear in default output or tab completion — useful for internal-use members.


class UserAccount {
    [string] $Username
    hidden [string] $PasswordHash

    UserAccount([string]$username, [string]$password) {
        $this.Username     = $username
        $this.PasswordHash = [System.Convert]::ToBase64String(
            [System.Text.Encoding]::UTF8.GetBytes($password)
        )
    }

    [bool] VerifyPassword([string]$inputPassword) {
        $hash = [System.Convert]::ToBase64String(
            [System.Text.Encoding]::UTF8.GetBytes($inputPassword)
        )
        return $this.PasswordHash -eq $hash
    }
}

$user = [UserAccount]::new("admin", "Secret@123")
Write-Host "Username: $($user.Username)"
Write-Host "Password correct: $($user.VerifyPassword('Secret@123'))"
Write-Host "Password correct: $($user.VerifyPassword('wrongpassword'))"

Output:


Username: admin
Password correct: True
Password correct: False

Enums

Enums define a fixed set of named values. They restrict a property to only valid, readable options.


enum TaskStatus {
    Pending
    InProgress
    Completed
    Cancelled
}

class Task {
    [string]     $Title
    [TaskStatus] $Status

    Task([string]$title) {
        $this.Title  = $title
        $this.Status = [TaskStatus]::Pending
    }

    [void] Start() {
        $this.Status = [TaskStatus]::InProgress
        Write-Host "Task '$($this.Title)' is now In Progress"
    }

    [void] Complete() {
        $this.Status = [TaskStatus]::Completed
        Write-Host "Task '$($this.Title)' is Completed"
    }
}

$t = [Task]::new("Deploy website")
Write-Host "Status: $($t.Status)"
$t.Start()
$t.Complete()

Output:


Status: Pending
Task 'Deploy website' is now In Progress
Task 'Deploy website' is Completed

OOP Concepts Summary

ConceptWhat It MeansPowerShell Feature
EncapsulationBundle data and behavior togetherClass with properties and methods
InheritanceChild class reuses parent classclass Child : Parent
AbstractionHide complexity, expose interfacehidden keyword
PolymorphismOverride parent method in childMethod override in derived class

Summary

PowerShell classes bring full OOP capabilities to scripting. A class defines the blueprint — properties hold data, methods define behavior, and constructors initialize objects. The $this keyword refers to the current object inside methods. Inheritance extends classes with new functionality while reusing existing code. Static members provide class-level utilities without requiring an instance. Hidden properties protect internal data. Enums enforce valid value sets. For complex systems like server management tools, configuration managers, or reporting engines, classes provide the structure needed to keep scripts maintainable and scalable.

Leave a Comment