InterviewPitch
PowerShell interview questions

PowerShell Interview Questions with Answers

Most Asked PowerShell Interview Questions for DevOps and Automation Roles

100+ QuestionsDetailed AnswersCode ExamplesUpdated for 2026

Introduction

PowerShell is a cross‑platform automation and configuration management framework, combining a powerful command‑line shell with a full‑featured scripting language. This page compiles the most frequently asked PowerShell interview questions – from basic cmdlets and variables to advanced object‑oriented programming, modules, and automation – essential for DevOps engineers, system administrators, and cloud professionals.

Why PowerShell?

  • Cross‑platform – Windows, Linux, macOS
  • Object‑oriented – works with .NET objects, not text
  • Powerful scripting language with full programming features
  • Integrates with Azure, AWS, and other cloud platforms
  • Essential for Windows administration and DevOps
  • Rich ecosystem with PowerShell Gallery

Most Asked PowerShell Interview Questions

Beginner
1. What is PowerShell?

PowerShell is a cross-platform task automation and configuration management framework from Microsoft, consisting of a command-line shell and scripting language.

  • Object-oriented: Works with .NET objects
  • Scripting language: Full-featured programming language
  • Cross-platform: Windows, Linux, macOS
  • Cmdlets: Verb-Noun naming convention
  • Pipeline: Pass objects between commands
powershell
# Hello World in PowerShell
Write-Host "Hello, World!"
Beginner
2. How to declare variables in PowerShell?

Variables in PowerShell are declared using the $ symbol. They are dynamically typed and can hold any object.

  • Assignment: $x = 10
  • Dollar sign: $variable
  • Constants: Set-Variable -Name PI -Value 3.14159 -Option Constant
  • Global scope: $global:x = 10
  • Local scope: $local:x = 10
powershell
# Variables in PowerShell
$x = 10          # Integer
$y = 3.14        # Float
$name = "PowerShell"  # String
$is_active = $true # Boolean

Write-Host $x
Write-Host $y
Write-Host $name
Write-Host $is_active
Beginner
3. What are the data types in PowerShell?

PowerShell supports various data types through the .NET framework.

  • Integer: int
  • Float: double
  • String: string
  • Boolean: bool
  • Array: array
  • Hashtable: hashtable
  • PSCustomObject: PSCustomObject
  • Null: $null
powershell
# Data Types in PowerShell
# Integer types
$a = 10          # int
$b = 127         # int

# Floating point
$d = 3.14        # double
$e = 2.5         # double

# String
$f = "Hello PowerShell"

# Boolean
$g = $true
$h = $false

# Array
$j = @(1, "hello", 3.14)

# Indexed array
$k = @(1, 2, 3, 4, 5)

# Hashtable (dictionary)
$l = @{
    "name" = "PowerShell"
    "version" = 7.4
}

# PSCustomObject
$person = [PSCustomObject]@{
    Name = "Alice"
    Age = 25
    City = "NYC"
}

# Null
$m = $null

Write-Host $a.GetType()
Write-Host $d.GetType()
Beginner
4. How to define functions in PowerShell?

Functions in PowerShell are defined using the function keyword with Verb-Noun naming convention.

  • Function declaration: function Get-Name { ... }
  • Parameters: param($a, $b)
  • Advanced functions: function Get-User { [CmdletBinding()] param(...) }
  • Filter functions: Use for pipeline processing
  • Script blocks: { param($x) $x * 2 }
powershell
# Functions in PowerShell
# Function declaration
function Add-Numbers {
    param($a, $b)
    return $a + $b
}

# Function with default parameters
function Greet {
    param($name = "Guest")
    return "Hello, $name!"
}

# Advanced function with parameters
function Get-Person {
    param(
        [Parameter(Mandatory=$true)]
        [string]$Name,
        [int]$Age = 0,
        [string]$City = "Unknown"
    )
    return [PSCustomObject]@{
        Name = $Name
        Age = $Age
        City = $City
    }
}

# Filter function (processes pipeline input)
function Get-Evens {
    process {
        if ($_ % 2 -eq 0) {
            return $_
        }
    }
}

# Function with multiple outputs
function Get-Values {
    return @(1, "hello", 3.14)
}

# Using functions
Add-Numbers 5 3
Greet "Alice"
Get-Person -Name "Alice" -Age 25 -City "NYC"
1..10 | Get-Evens
Beginner
5. What are arrays in PowerShell?

Arrays in PowerShell are collections of items that can be of any type.

  • Creation: @(1, 2, 3, 4, 5)
  • Access: $arr[0]
  • Functions: ForEach-Object, Where-Object, Measure-Object
  • Add: $arr += 6
  • Range: 1..10
powershell
# Arrays in PowerShell
$arr = @(1, 2, 3, 4, 5)

# Map - transform each element
$doubled = $arr | ForEach-Object { $_ * 2 }
Write-Host $doubled

# Filter - select elements
$evens = $arr | Where-Object { $_ % 2 -eq 0 }
Write-Host $evens

# Reduce - aggregate
$sum = ($arr | Measure-Object -Sum).Sum
Write-Host $sum

# Array comprehension
$squares = 1..10 | ForEach-Object { $_ * $_ }
Write-Host $squares

# Push and pop
$arr += 6
Write-Host $arr
$arr = $arr[0..($arr.Length-2)]
Write-Host $arr

# Array operations
$a = @(1, 2, 3)
$b = @(4, 5, 6)
$c = for ($i=0; $i -lt $a.Length; $i++) { $a[$i] + $b[$i] }
Write-Host $c
Beginner
6. What are hashtables in PowerShell?

Hashtables in PowerShell are key-value pairs, similar to dictionaries.

  • Creation: @{ name = "Alice"; age = 25 }
  • Access: $dict["name"] or $dict.name
  • Add/Update: $dict["country"] = "USA"
  • Keys/Values: $dict.Keys, $dict.Values
  • Check: $dict.ContainsKey("name")
powershell
# Hashtables (Dictionaries) in PowerShell
# Create hashtable
$person = @{
    Name = "Alice"
    Age = 25
    City = "NYC"
}

# Access values
Write-Host $person["Name"]
Write-Host $person.Age

# Add/update values
$person["Country"] = "USA"
$person.Age = 26

# Get with default
$city = $person["City"] ?? "Unknown"

# Keys and values
$person.Keys
$person.Values

# Iterate over hashtable
foreach ($key in $person.Keys) {
    Write-Host "$key : $($person[$key])"
}

# Delete key
$person.Remove("Country")

# Check if key exists
Write-Host $person.ContainsKey("Name")

# Hashtable from arrays
$keys = 1..5
$values = 1..5 | ForEach-Object { $_ * $_ }
$squares = @{}
for ($i=0; $i -lt $keys.Count; $i++) {
    $squares[$keys[$i]] = $values[$i]
}
$squares
Beginner
7. What are arrays as tuples in PowerShell?

Arrays can be used as tuples to store ordered lists of values.

  • Creation: @(1, "hello", 3.14)
  • Access: $tuple[0]
  • Unpacking: $a, $b, $c = $tuple
  • Named tuples: Use PSCustomObject
  • Concatenation: $t1 + $t2
powershell
# Arrays as Tuples in PowerShell
# Create tuple-like array
$t = @(1, "hello", 3.14, $true)

# Access elements
Write-Host $t[0]
Write-Host $t[1]

# PSCustomObject as named tuple
$person = [PSCustomObject]@{
    Name = "Alice"
    Age = 25
    City = "NYC"
}
Write-Host $person.Name
Write-Host $person.Age

# Array unpacking
$a, $b, $c = 10, 20, 30
Write-Host "$a, $b, $c"

# Function returning multiple values
function Divide {
    param($a, $b)
    $quotient = [math]::Floor($a / $b)
    $remainder = $a % $b
    return @($quotient, $remainder)
}
$quotient, $remainder = Divide 10 3
Write-Host "Quotient: $quotient, Remainder: $remainder"

# Array concatenation
$t1 = @(1, 2, 3)
$t2 = @(4, 5, 6)
$t3 = $t1 + $t2
Write-Host $t3
Beginner
8. What are control flow statements in PowerShell?

PowerShell provides various control flow statements including conditionals and loops.

  • If-else: if ($condition) { ... }
  • Ternary: $condition ? "yes" : "no"
  • Switch: switch ($value) { 1 { "One" } }
  • For loop: for ($i = 1; $i -le 10; $i++)
  • Foreach: foreach ($item in $array) { ... }
powershell
# Control Flow in PowerShell
# If-else statement
$age = 25
if ($age -lt 18) {
    Write-Host "Minor"
} elseif ($age -lt 65) {
    Write-Host "Adult"
} else {
    Write-Host "Senior"
}

# Ternary operator (PowerShell 7.0+)
$status = $age -ge 18 ? "Adult" : "Minor"
Write-Host $status

# Switch statement
$value = 2
switch ($value) {
    0 { Write-Host "Zero" }
    1 { Write-Host "One" }
    2 { Write-Host "Two" }
    default { Write-Host "Other" }
}

# For loop
for ($i = 1; $i -le 5; $i++) {
    Write-Host $i
}

# For loop with array
$fruits = @("apple", "banana", "orange")
foreach ($fruit in $fruits) {
    Write-Host $fruit
}

# While loop
$i = 1
while ($i -le 5) {
    Write-Host $i
    $i++
}

# Break and continue
for ($i = 1; $i -le 10; $i++) {
    if ($i -eq 6) {
        break
    }
    if ($i % 2 -eq 0) {
        continue
    }
    Write-Host $i
}
Beginner
9. How to generate arrays in PowerShell?

PowerShell provides various ways to generate arrays including ranges, pipelines, and loops.

  • Range: 1..10
  • Pipeline: 1..10 | ForEach-Object { $_ * $_ }
  • Filter: 1..20 | Where-Object { $_ % 2 -eq 0 }
  • Function generator: Custom functions
  • Conditional: 1..10 | ForEach-Object { if ($_ % 2 -eq 0) { "even" } }
powershell
# Array Generation in PowerShell
# Using range and ForEach-Object
$squares = 1..10 | ForEach-Object { $_ * $_ }
Write-Host $squares

# Filter with Where-Object
$evens = 1..20 | Where-Object { $_ % 2 -eq 0 }
Write-Host $evens

# Nested loops
$matrix = @()
for ($i = 1; $i -le 3; $i++) {
    for ($j = 1; $j -le 3; $j++) {
        $matrix += @($i, $j)
    }
}
$matrix

# Hashtable generation
$keys = 1..5
$square_dict = @{}
foreach ($key in $keys) {
    $square_dict[$key] = $key * $key
}
$square_dict

# Generator function (using function with yield)
function Get-Squares {
    param($n)
    for ($i = 1; $i -le $n; $i++) {
        $i * $i
    }
}
$sum = 0
Get-Squares 100 | ForEach-Object { $sum += $_ }
Write-Host $sum

# Conditional array
$results = 1..10 | ForEach-Object {
    if ($_ % 2 -eq 0) { "even" } else { "odd" }
}
Write-Host $results
Beginner
10. How to work with strings in PowerShell?

PowerShell provides extensive string manipulation capabilities.

  • Concatenation: $str1 + " " + $str2
  • Interpolation: "Hello $name"
  • Functions: Length, ToUpper, ToLower
  • Substring: $text.Substring(0, 5)
  • Split/Join: -split, -join
powershell
# Strings in PowerShell
# String creation
$str1 = "Hello"
$str2 = 'World'
$str3 = @"
Multi-line
string
"@

# String concatenation
$greeting = $str1 + " " + $str2
Write-Host $greeting

# String interpolation
$name = "PowerShell"
$version = 7.4
Write-Host "Welcome to $name version $version"

# String functions
$text = "Hello, World!"
Write-Host $text.Length
Write-Host $text.ToUpper()
Write-Host $text.ToLower()
Write-Host $text.Replace("World", "PowerShell")

# Substring
Write-Host $text.Substring(0, 5)

# Split and join
$words = "Hello World PowerShell" -split " "
Write-Host $words
$joined = $words -join "-"
Write-Host $joined

# String comparison
Write-Host ("hello" -eq "hello")
Write-Host ("hello" -lt "world")

# String formatting
Write-Host ("Value: {0:F2}" -f 3.14159)
Beginner
11. What are modules in PowerShell?

Modules in PowerShell are containers for code that organize and encapsulate functions, cmdlets, and variables.

  • Definition: Save as .psm1 file
  • Import: Import-Module ModuleName
  • Export: Export-ModuleMember -Function FunctionName
  • Manifest: .psd1 file
  • Script module: .psm1 file
powershell
# Modules in PowerShell
# Creating a module (save as MyMath.psm1)
# function Add-Numbers { param($a, $b) return $a + $b }
# function Subtract-Numbers { param($a, $b) return $a - $b }
# Export-ModuleMember -Function Add-Numbers, Subtract-Numbers

# Using a module
# Import-Module MyMath

# Defining a module with script block
$myMath = @{
    PI = 3.14159
    Add = { param($a, $b) $a + $b }
    Subtract = { param($a, $b) $a - $b }
}

# Using the module
$myMath.Add.Invoke(5, 3)
$myMath.Subtract.Invoke(10, 4)
$myMath.PI

# Creating a PowerShell class module
class MathHelper {
    static [double]$PI = 3.14159
    static [int] Add([int]$a, [int]$b) { return $a + $b }
    static [int] Subtract([int]$a, [int]$b) { return $a - $b }
}

[MathHelper]::Add(5, 3)
[MathHelper]::Subtract(10, 4)
[MathHelper]::PI

# Script module with functions
# function Multiply { param($a, $b) return $a * $b }
# Export-ModuleMember -Function Multiply

# Dot sourcing a script
# . .script.ps1
Beginner
12. What are classes in PowerShell?

PowerShell supports object-oriented programming with classes, properties, and methods.

  • Class definition: class MyClass { ... }
  • Properties: [string]$Name
  • Constructor: MyClass() { }
  • Methods: [string] GetInfo() { ... }
  • Inheritance: class Child : Parent
powershell
# Classes and Types in PowerShell
# Abstract class
class Animal {
    [string]$Name
    [int]$Age
    
    Animal([string]$name, [int]$age) {
        $this.Name = $name
        $this.Age = $age
    }
    
    [string] MakeSound() {
        throw "MakeSound method must be overridden"
    }
}

# Concrete class
class Dog : Animal {
    Dog([string]$name, [int]$age) : base($name, $age) {}
    
    [string] MakeSound() {
        return "Woof!"
    }
}

# Class with properties and methods
class Person {
    [string]$Name
    [int]$Age
    [string]$City
    
    Person([string]$name, [int]$age, [string]$city = "Unknown") {
        $this.Name = $name
        $this.Age = $age
        $this.City = $city
    }
    
    [string] GetInfo() {
        return "$($this.Name) is $($this.Age) years old from $($this.City)"
    }
}

# Usage
$dog = [Dog]::new("Rex", 3)
$person = [Person]::new("Alice", 25)
Write-Host $dog.MakeSound()
Write-Host $person.GetInfo()

# Interface-like behavior using abstract classes
class Cat : Animal {
    Cat([string]$name, [int]$age) : base($name, $age) {}
    
    [string] MakeSound() {
        return "Meow!"
    }
}

$cat = [Cat]::new("Whiskers", 2)
Write-Host $cat.MakeSound()
Intermediate
13. What is the type system in PowerShell?

PowerShell has a rich type system based on .NET with type declarations, type checking, and type conversion.

  • Type declarations: [int]$x = 10
  • Type checking: $x -is [int]
  • Type conversion: [int]"42"
  • Strongly typed arrays: [int[]]$numbers = @(1,2,3)
  • Nullable types: [Nullable[int]]$value
powershell
# Type System in PowerShell
# Type declarations
function Get-Description {
    param([int]$x)
    return "Integer: $x"
}

function Get-FloatDescription {
    param([double]$x)
    return "Float: $x"
}

function Get-StringDescription {
    param([string]$x)
    return "String: $x"
}

function Get-ArrayDescription {
    param([array]$x)
    return "Array: $($x -join ', ')"
}

# Strongly typed array
[int[]]$numbers = @(1, 2, 3, 4, 5)

# Type checking
$value = 42
if ($value -is [int]) {
    Write-Host "Value is an integer"
}

# Type conversion
$number = [int]"42"
$float = [double]"3.14"
$string = [string]42

# Nullable types
$nullableValue = $null
if ($nullableValue -eq $null) {
    Write-Host "Value is null"
}

# Type constraints
function Add-Numbers {
    param(
        [Parameter(Mandatory=$true)]
        [int]$a,
        [int]$b
    )
    return $a + $b
}

Add-Numbers 5 3
Get-Description 42
Get-FloatDescription 3.14
Get-StringDescription "Hello"
Get-ArrayDescription @(1, 2, 3)
Intermediate
14. How to handle exceptions in PowerShell?

PowerShell provides try-catch-finally blocks for error handling with support for specific exception types.

  • Try-catch: try { ... } catch { ... }
  • Finally: try { ... } finally { ... }
  • Throw: throw "Error message"
  • Specific catch: catch [DivideByZeroException]
  • $Error: Automatic error variable
powershell
# Exceptions and Errors in PowerShell
# Try-catch block
try {
    # Code that might error
    $result = 10 / 0
    Write-Host $result
} catch [DivideByZeroException] {
    Write-Host "Division by zero: $($_.Exception.Message)"
}

# Specific error handling
try {
    $arr = @(1, 2, 3)
    Write-Host $arr[10]
} catch [System.Management.Automation.RuntimeException] {
    Write-Host "Index out of bounds!"
} catch {
    Write-Host "Other error: $($_.Exception.Message)"
}

# Finally block
try {
    $file = [System.IO.File]::OpenText("data.txt")
    Write-Host "File opened successfully"
    $file.Close()
} catch {
    Write-Host "Error opening file"
} finally {
    Write-Host "Cleanup performed"
}

# Throwing errors
function Divide {
    param($a, $b)
    if ($b -eq 0) {
        throw [System.DivideByZeroException]::new("Cannot divide by zero")
    }
    return $a / $b
}

# Using error
try {
    Divide 10 0
} catch {
    Write-Host "Error: $($_.Exception.Message)"
}

# Custom error records
$errorRecord = [System.Management.Automation.ErrorRecord]::new(
    "Custom error message",
    "MyErrorId",
    [System.Management.Automation.ErrorCategory]::InvalidOperation,
    $null
)
throw $errorRecord
Intermediate
15. How to work with files in PowerShell?

PowerShell provides cmdlets for file operations including reading, writing, and CSV handling.

  • Read: Get-Content
  • Write: Out-File
  • Append: Add-Content
  • CSV: Import-Csv, Export-Csv
  • File info: Get-ChildItem
powershell
# File I/O in PowerShell
# Reading files
try {
    $content = Get-Content "example.txt"
    Write-Host $content
} catch {
    Write-Host "File not found"
}

# Reading line by line
try {
    Get-Content "data.txt" | ForEach-Object {
        Write-Host $_
    }
} catch {
    Write-Host "Error reading file"
}

# Writing files
"Hello, World!" | Out-File "output.txt"
"This is line 2" | Out-File "output.txt" -Append

# Appending to files
"Appended line" | Out-File "output.txt" -Append

# Reading CSV
$data = Import-Csv "data.csv"
$data

# Writing CSV
$data = @(
    [PSCustomObject]@{Name="Alice"; Age=25; City="NYC"},
    [PSCustomObject]@{Name="Bob"; Age=30; City="LA"}
)
$data | Export-Csv "output.csv" -NoTypeInformation

# File operations
$files = Get-ChildItem -Path "." -Filter "*.txt"
foreach ($file in $files) {
    Write-Host $file.Name
    Write-Host $file.Length
}

# Using StreamReader/StreamWriter
$writer = [System.IO.StreamWriter]::new("example.txt")
$writer.WriteLine("Hello, World!")
$writer.Close()

$reader = [System.IO.StreamReader]::new("example.txt")
$content = $reader.ReadToEnd()
$reader.Close()
Write-Host $content
Intermediate
16. How to use modules and packages in PowerShell?

PowerShell uses the PowerShell Gallery for package management and modules for code organization.

  • Install: Install-Module -Name ModuleName
  • Import: Import-Module ModuleName
  • Gallery: Find-Module
  • Manifest: New-ModuleManifest
  • Update: Update-Module
powershell
# Modules and Packages in PowerShell
# Using PowerShell Gallery
# Install-Module -Name ModuleName

# Installing a module
# Install-Module -Name PSReadLine -Scope CurrentUser

# Importing a module
# Import-Module PSReadLine

# Using a module
# Get-PSReadLineOption

# Creating a module manifest
# New-ModuleManifest -Path .MyModule.psd1 -RootModule MyModule.psm1

# Using NuGet packages
# Install-PackageProvider -Name NuGet -Force
# Install-Module -Name PowerShellGet -Force

# Using a script module
# . .MyScript.ps1

# Using a binary module
# Import-Module .MyModule.dll

# Checking installed modules
# Get-Module -ListAvailable

# Updating modules
# Update-Module -Name ModuleName

# Uninstalling modules
# Uninstall-Module -Name ModuleName

# Using a private gallery
# Register-PSRepository -Name MyRepo -SourceLocation https://myrepo.com/nuget

# Example of using a module
# Install-Module -Name Pester -Force
# Invoke-Pester
Intermediate
17. How to create plots in PowerShell?

PowerShell can create plots using .NET Charting or by generating HTML with JavaScript libraries.

  • .NET Charting: Add-Type -AssemblyName System.Windows.Forms.DataVisualization
  • Chart.js: Generate HTML
  • Save: $chart.SaveImage
  • Custom: SVG generation
  • Web-based: HTML output
powershell
# Plotting in PowerShell
# Using .NET Charting
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Windows.Forms.DataVisualization

function New-Chart {
    $chart = New-Object System.Windows.Forms.DataVisualization.Charting.Chart
    $chart.Size = New-Object System.Drawing.Size(800, 600)
    $chart.BackColor = [System.Drawing.Color]::White
    
    $chartArea = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea
    $chart.ChartAreas.Add($chartArea)
    
    $series = New-Object System.Windows.Forms.DataVisualization.Charting.Series
    $series.ChartType = [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]::Line
    $chart.Series.Add($series)
    
    return $chart
}

function Add-DataPoint {
    param($chart, $x, $y)
    $chart.Series[0].Points.AddXY($x, $y)
}

# Create plot
$chart = New-Chart
1..10 | ForEach-Object {
    Add-DataPoint $chart $_ ($_ * $_)
}

# Save chart
$chart.SaveImage("chart.png", "png")

# Using Chart.js for web-based plots
$html = @"
<!DOCTYPE html>
<html>
<head>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
    <canvas id="myChart"></canvas>
    <script>
        const ctx = document.getElementById('myChart').getContext('2d');
        new Chart(ctx, {
            type: 'line',
            data: {
                labels: [1,2,3,4,5],
                datasets: [{
                    data: [1,4,9,16,25]
                }]
            }
        });
    </script>
</body>
</html>
"@
$html | Out-File "plot.html"
Intermediate
18. What are data structures in PowerShell?

PowerShell provides various data structures including arrays, hashtables, and .NET collections.

  • Stack: System.Collections.ArrayList
  • Queue: System.Collections.Queue
  • Hashtable: @
  • Set: System.Collections.Generic.HashSet
  • List: System.Collections.Generic.List
powershell
# Data Structures in PowerShell
# Stack using ArrayList
$stack = New-Object System.Collections.ArrayList
$stack.Add(1)
$stack.Add(2)
$stack.Add(3)
$stack.RemoveAt($stack.Count - 1)  # Pop

# Queue using Queue
$queue = New-Object System.Collections.Queue
$queue.Enqueue(1)
$queue.Enqueue(2)
$queue.Enqueue(3)
$queue.Dequeue()  # Remove first

# Hashtable as Map
$map = @{
    "Alice" = 25
    "Bob" = 30
    "Charlie" = 35
}

# HashSet
$set = New-Object System.Collections.Generic.HashSet[int]
$set.Add(1)
$set.Add(2)
$set.Add(2)  # Won't be added

# List
$list = New-Object System.Collections.Generic.List[int]
$list.Add(1)
$list.Add(2)
$list.Add(3)

# SortedSet
$sortedSet = New-Object System.Collections.Generic.SortedSet[int]
$sortedSet.Add(3)
$sortedSet.Add(1)
$sortedSet.Add(2)

# LinkedList
$linkedList = New-Object System.Collections.Generic.LinkedList[int]
$linkedList.AddLast(1)
$linkedList.AddLast(2)
$linkedList.AddFirst(0)

# Using built-in array
$array = @(1, 2, 3, 4, 5)

# Using generic List
$list = [System.Collections.Generic.List[int]]::new()
$list.Add(1)
$list.Add(2)
$list.Add(3)
Write-Host $list.Count
Intermediate
19. How to do statistics in PowerShell?

PowerShell provides statistical functions through Measure-Object and custom implementations.

  • Mean: Measure-Object -Average
  • Median: Custom function
  • Standard deviation: Custom calculation
  • Correlation: Manual calculation
  • Quantiles: Custom implementation
powershell
# Statistics in PowerShell
# Basic statistics functions
function Get-Mean {
    param($data)
    return ($data | Measure-Object -Average).Average
}

function Get-Median {
    param($data)
    $sorted = $data | Sort-Object
    $count = $sorted.Count
    if ($count % 2 -eq 1) {
        return $sorted[($count - 1) / 2]
    } else {
        return ($sorted[$count / 2 - 1] + $sorted[$count / 2]) / 2
    }
}

function Get-StandardDeviation {
    param($data)
    $mean = Get-Mean $data
    $variance = ($data | ForEach-Object { ($_ - $mean) * ($_ - $mean) } | Measure-Object -Sum).Sum / $data.Count
    return [math]::Sqrt($variance)
}

function Get-Variance {
    param($data)
    $mean = Get-Mean $data
    return ($data | ForEach-Object { ($_ - $mean) * ($_ - $mean) } | Measure-Object -Sum).Sum / $data.Count
}

function Get-Correlation {
    param($x, $y)
    $meanX = Get-Mean $x
    $meanY = Get-Mean $y
    $n = $x.Count
    
    $sumXY = 0
    $sumX2 = 0
    $sumY2 = 0
    
    for ($i = 0; $i -lt $n; $i++) {
        $dx = $x[$i] - $meanX
        $dy = $y[$i] - $meanY
        $sumXY += $dx * $dy
        $sumX2 += $dx * $dx
        $sumY2 += $dy * $dy
    }
    
    return $sumXY / [math]::Sqrt($sumX2 * $sumY2)
}

function Get-Quantile {
    param($data, $q)
    $sorted = $data | Sort-Object
    $n = $sorted.Count
    $pos = ($n - 1) * $q
    $base = [math]::Floor($pos)
    $frac = $pos - $base
    
    if ($frac -eq 0) {
        return $sorted[$base]
    } else {
        return $sorted[$base] + $frac * ($sorted[$base + 1] - $sorted[$base])
    }
}

# Usage
$data = 1..10
Write-Host "Mean: $(Get-Mean $data)"
Write-Host "Median: $(Get-Median $data)"
Write-Host "Standard Deviation: $(Get-StandardDeviation $data)"
Write-Host "Variance: $(Get-Variance $data)"

$x = 1..100
$y = $x | ForEach-Object { 2 * $_ + (Get-Random -Minimum -10 -Maximum 10) }
Write-Host "Correlation: $(Get-Correlation $x $y)"
Write-Host "Quantile 0.25: $(Get-Quantile $data 0.25)"
Write-Host "Quantile 0.75: $(Get-Quantile $data 0.75)"
Intermediate
20. How to do linear algebra in PowerShell?

PowerShell provides linear algebra operations through custom implementations using arrays.

  • Matrix multiplication: Matrix-Multiply
  • Transpose: Transpose-Matrix
  • Determinant: Determinant
  • Eigenvalues: Complex calculation
  • Inverse: Using Gauss-Jordan
powershell
# Linear Algebra in PowerShell
function New-Matrix {
    param($rows, $cols)
    $matrix = New-Object 'double[,]' $rows, $cols
    return $matrix
}

function Matrix-Multiply {
    param($A, $B)
    $rows = $A.GetLength(0)
    $cols = $B.GetLength(1)
    $inner = $B.GetLength(0)
    $result = New-Matrix $rows $cols
    
    for ($i = 0; $i -lt $rows; $i++) {
        for ($j = 0; $j -lt $cols; $j++) {
            $sum = 0
            for ($k = 0; $k -lt $inner; $k++) {
                $sum += $A[$i, $k] * $B[$k, $j]
            }
            $result[$i, $j] = $sum
        }
    }
    return $result
}

function Transpose-Matrix {
    param($matrix)
    $rows = $matrix.GetLength(0)
    $cols = $matrix.GetLength(1)
    $result = New-Matrix $cols $rows
    
    for ($i = 0; $i -lt $rows; $i++) {
        for ($j = 0; $j -lt $cols; $j++) {
            $result[$j, $i] = $matrix[$i, $j]
        }
    }
    return $result
}

function Determinant {
    param($matrix)
    $n = $matrix.GetLength(0)
    if ($n -eq 1) {
        return $matrix[0, 0]
    }
    if ($n -eq 2) {
        return $matrix[0, 0] * $matrix[1, 1] - $matrix[0, 1] * $matrix[1, 0]
    }
    
    $det = 0
    for ($j = 0; $j -lt $n; $j++) {
        $subMatrix = New-Matrix ($n-1) ($n-1)
        for ($i = 1; $i -lt $n; $i++) {
            $col = 0
            for ($k = 0; $k -lt $n; $k++) {
                if ($k -ne $j) {
                    $subMatrix[$i-1, $col] = $matrix[$i, $k]
                    $col++
                }
            }
        }
        $det += [math]::Pow(-1, $j) * $matrix[0, $j] * (Determinant $subMatrix)
    }
    return $det
}

# Usage
$A = New-Matrix 3 3
$A[0,0] = 1; $A[0,1] = 2; $A[0,2] = 3
$A[1,0] = 4; $A[1,1] = 5; $A[1,2] = 6
$A[2,0] = 7; $A[2,1] = 8; $A[2,2] = 10

$B = New-Matrix 3 1
$B[0,0] = 1; $B[1,0] = 2; $B[2,0] = 3

$product = Matrix-Multiply $A $B
$transpose = Transpose-Matrix $A
$det = Determinant $A

Write-Host "Matrix product:"
for ($i = 0; $i -lt $product.GetLength(0); $i++) {
    for ($j = 0; $j -lt $product.GetLength(1); $j++) {
        Write-Host $product[$i, $j]
    }
}
Write-Host "Determinant: $det"
Intermediate
21. How to work with dates in PowerShell?

PowerShell provides the Get-Date cmdlet and DateTime class for comprehensive date handling.

  • Current: Get-Date
  • Create: Get-Date "2024-01-01"
  • Arithmetic: $date.AddDays(10)
  • Difference: $date1 - $date2
  • Formatting: $date.ToString("yyyy-MM-dd")
powershell
# Dates and Time in PowerShell
# Current date and time
$now = Get-Date
Write-Host $now

# Date creation
$date1 = Get-Date "2024-01-01"
$date2 = Get-Date "2024-01-01 12:00:00"
Write-Host $date1
Write-Host $date2

# Date arithmetic
$date1 = $date1.AddDays(10)
Write-Host $date1
$date1 = $date1.AddMonths(2)
Write-Host $date1

# Date difference
$diff = $now - $date2
Write-Host "$($diff.Days) days, $($diff.Hours) hours"

# Formatting dates
$date = Get-Date "2024-01-01"
Write-Host $date.ToString("yyyy-MM-dd HH:mm:ss")

# Date functions
Write-Host (Get-Date).Year
Write-Host (Get-Date).Month
Write-Host (Get-Date).Day
Write-Host (Get-Date).DayOfWeek

# Date range
$start = Get-Date "2024-01-01"
$end = Get-Date "2024-01-10"
for ($date = $start; $date -le $end; $date = $date.AddDays(1)) {
    Write-Host $date.ToString("yyyy-MM-dd")
}

# Timezone handling
$timezone = [System.TimeZoneInfo]::FindSystemTimeZoneById("Eastern Standard Time")
$date = [System.TimeZoneInfo]::ConvertTimeFromUtc((Get-Date).ToUniversalTime(), $timezone)
Write-Host $date

# Timestamps
$timestamp = [DateTimeOffset]::Now.ToUnixTimeSeconds()
Write-Host $timestamp
$date = [DateTimeOffset]::FromUnixTimeSeconds($timestamp).LocalDateTime
Write-Host $date
Intermediate
22. How to use regular expressions in PowerShell?

PowerShell provides regex support through the -match operator, regex class, and various cmdlets.

  • Match: $text -match "hello"
  • Regex class: [regex]::Match($text, "hello")
  • Capture groups: $matches[1]
  • Replace: $text -replace "\d+", "NUM"
  • Split: [regex]::Split($text, "[\s,]+")
powershell
# Regular Expressions in PowerShell
# Match
$text = "hello world"
$match = [regex]::Match($text, "hello")
if ($match.Success) {
    Write-Host "Match found"
}

# Find all
$text2 = "hello world hello again"
$matches = [regex]::Matches($text2, "hello")
Write-Host $matches.Count

# Regex with capture groups
$text3 = "Date: 2024-01-01"
$match = [regex]::Match($text3, "(d{4})-(d{2})-(d{2})")
if ($match.Success) {
    Write-Host $match.Groups[1].Value  # year
    Write-Host $match.Groups[2].Value  # month
    Write-Host $match.Groups[3].Value  # day
}

# Replace with regex
$replaced = [regex]::Replace("Hello 123 World", "d+", "NUM")
Write-Host $replaced

# Case insensitive
$match = [regex]::Match("HELLO world", "hello", [System.Text.RegularExpressions.RegexOptions]::IgnoreCase)
if ($match.Success) {
    Write-Host "Case insensitive match found"
}

# Split with regex
$parts = [regex]::Split("Hello World PHP", "[s,]+")
$parts

# Replace callback
$result = [regex]::Replace("1 2 3 4 5", "d+", {
    param($match)
    return [int]$match.Value * 2
})
Write-Host $result

# Using -match operator
$text = "hello world"
if ($text -match "hello") {
    Write-Host "Match found using -match"
}

# Using -replace operator
$text = "Hello 123 World"
$text -replace "d+", "NUM"
Advanced
23. How to do parallel computing in PowerShell?

PowerShell supports parallel computing through ForEach-Object -Parallel, runspaces, and workflows.

  • ForEach-Object -Parallel: PowerShell 7.0+
  • Runspaces: RunspaceFactory
  • Workflows: workflow
  • Jobs: Start-Job
  • PoshRSJob: Community module
powershell
# Parallel Computing in PowerShell
# Using ForEach-Object -Parallel (PowerShell 7.0+)
$numbers = 1..10
$results = $numbers | ForEach-Object -Parallel {
    Start-Sleep -Seconds 1
    return $_ * $_
} -ThrottleLimit 5

# Using runspaces
$runspacePool = [runspacefactory]::CreateRunspacePool(1, 5)
$runspacePool.Open()

$jobs = @()
$numbers = 1..10

foreach ($num in $numbers) {
    $powershell = [powershell]::Create()
    $powershell.RunspacePool = $runspacePool
    $powershell.AddScript({
        param($x)
        Start-Sleep -Seconds 1
        return $x * $x
    }).AddArgument($num) | Out-Null
    
    $handle = $powershell.BeginInvoke()
    $jobs += @{
        PowerShell = $powershell
        Handle = $handle
    }
}

$results = @()
foreach ($job in $jobs) {
    $result = $job.PowerShell.EndInvoke($job.Handle)
    $results += $result
    $job.PowerShell.Dispose()
}
$runspacePool.Dispose()

# Using Start-Job
$job = Start-Job -ScriptBlock {
    Start-Sleep -Seconds 2
    return "Task completed"
}
$result = Receive-Job $job -Wait
Write-Host $result

# Using Workflows
workflow Process-Numbers {
    param($numbers)
    foreach -parallel ($num in $numbers) {
        Start-Sleep -Seconds 1
        return $num * $num
    }
}
$results = Process-Numbers -numbers (1..10)

# Using PoshRSJob
# Install-Module -Name PoshRSJob
# $jobs = 1..10 | Start-RSJob -ScriptBlock { Start-Sleep 1; $_ * $_ }
# $results = $jobs | Wait-RSJob | Receive-RSJob
Advanced
24. What is metaprogramming in PowerShell?

PowerShell supports metaprogramming through Invoke-Expression, dynamic code, and proxy functions.

  • Invoke-Expression: Invoke-Expression '$x + $y'
  • Script blocks: Dynamic code
  • Dynamic properties: Add-Member
  • Proxy functions: ProxyCommand
  • Dynamic modules: New-Module
powershell
# Metaprogramming in PowerShell
# Using Invoke-Expression for dynamic code execution
$code = '$x = 10; $y = 20; $x + $y'
$result = Invoke-Expression $code
Write-Host $result

# Dynamic function calls
function Add-Numbers {
    param($a, $b)
    return $a + $b
}
$functionName = 'Add-Numbers'
& $functionName 5 3

# Dynamic property access
$obj = [PSCustomObject]@{
    Property1 = "Value1"
    Property2 = "Value2"
}
$propertyName = "Property1"
$obj.$propertyName

# Dynamic method calls
$obj = [PSCustomObject]@{
    Method1 = { return "Method 1 called" }
    Method2 = { return "Method 2 called" }
}
$methodName = "Method1"
& $obj.$methodName

# Using Add-Member for dynamic properties
$obj = New-Object PSObject
Add-Member -InputObject $obj -MemberType NoteProperty -Name "DynamicProperty" -Value "Value"

# Using ScriptBlock
$scriptBlock = { param($x) return $x * 2 }
& $scriptBlock 5

# Using Proxy functions
$command = Get-Command "Get-Process"
$metadata = [System.Management.Automation.CommandMetadata]::new($command)
$proxy = [System.Management.Automation.ProxyCommand]::Create($metadata)
Invoke-Expression $proxy

# Dynamic module creation
New-Module -Name DynamicModule -ScriptBlock {
    function Add-Numbers { param($a, $b) $a + $b }
    Export-ModuleMember -Function Add-Numbers
} | Import-Module
Add-Numbers 5 3
Advanced
25. How to interface with C# in PowerShell?

PowerShell can interface with C# through Add-Type, loading assemblies, and using .NET framework.

  • Add-Type: Add-Type -TypeDefinition $source
  • DLL: Add-Type -Path "MyLibrary.dll"
  • COM objects: New-Object -ComObject
  • .NET classes: Direct usage
  • P/Invoke: Native methods
powershell
# Interoperability with C# in PowerShell
# Using C# code in PowerShell
$source = @"
using System;
public class MathHelper {
    public static int Add(int a, int b) {
        return a + b;
    }
    public static int Multiply(int a, int b) {
        return a * b;
    }
}
"@

Add-Type -TypeDefinition $source
[MathHelper]::Add(5, 3)
[MathHelper]::Multiply(4, 5)

# Using C# DLL
# Add-Type -Path "MyLibrary.dll"

# Using C# with parameters
$source = @"
using System;
public class Calculator {
    public static double Sin(double x) {
        return Math.Sin(x);
    }
}
"@
Add-Type -TypeDefinition $source
[Calculator]::Sin(0.5)

# Using COM objects
$excel = New-Object -ComObject Excel.Application
$excel.Visible = $true
$workbook = $excel.Workbooks.Add()
$worksheet = $workbook.Worksheets.Item(1)
$worksheet.Cells.Item(1, 1) = "Hello from PowerShell"
$excel.Quit()

# Using .NET framework
[System.Net.WebClient]::new().DownloadString("https://api.github.com")

# Using C# generic types
$list = [System.Collections.Generic.List[int]]::new()
$list.Add(1)
$list.Add(2)
$list.Add(3)

# Using C# LINQ
$numbers = @(1, 2, 3, 4, 5)
$query = [System.Linq.Enumerable]::Where($numbers, [Func[int,bool]]{ param($x) $x -gt 2 })
$query

# Using P/Invoke
$code = @"
using System;
using System.Runtime.InteropServices;
public class NativeMethods {
    [DllImport("user32.dll")]
    public static extern int MessageBox(IntPtr hWnd, string text, string caption, int type);
}
"@
Add-Type -TypeDefinition $code
[NativeMethods]::MessageBox([IntPtr]::Zero, "Hello from PowerShell", "Message", 0)
Advanced
26. How to optimize performance in PowerShell?

PowerShell performance can be optimized through various techniques including type declarations, avoiding pipelines, and using .NET methods.

  • Type declarations: [int[]]$array
  • ArrayList: For large collections
  • StringBuilder: For string concatenation
  • foreach statement: Faster than ForEach-Object
  • .NET methods: Direct usage
powershell
# Performance Optimization in PowerShell
# Performance tips

# 1. Use type declarations
function Sum-Array {
    param([int[]]$array)
    $sum = 0
    foreach ($value in $array) {
        $sum += $value
    }
    return $sum
}

# 2. Use ArrayList for large collections
$list = [System.Collections.ArrayList]::new()
for ($i = 0; $i -lt 10000; $i++) {
    $list.Add($i) | Out-Null
}

# 3. Use StringBuilder for string concatenation
$sb = [System.Text.StringBuilder]::new()
for ($i = 0; $i -lt 1000; $i++) {
    $sb.Append("$i ") | Out-Null
}
$result = $sb.ToString()

# 4. Avoid unnecessary pipeline operations
$numbers = 1..10000
$sum = 0
foreach ($num in $numbers) {
    $sum += $num
}

# 5. Use script block filters for Where-Object
$numbers | Where-Object { $_ -gt 5000 }

# 6. Use foreach statement vs ForEach-Object
$numbers = 1..10000
$result = @()
foreach ($num in $numbers) {
    $result += $num * 2
}

# 7. Use .NET methods when available
[System.Math]::Sqrt(100)

# 8. Use large memory page support
# Add-Type -TypeDefinition "using System; public class Memory { }"

# 9. Use PSReadLine for better performance
# Set-PSReadLineOption -HistorySaveStyle SaveIncrementally

# 10. Use PowerShell 7 for better performance
# $PSVersionTable

# 11. Use -NoProfile for scripts
# powershell.exe -NoProfile -File script.ps1

# 12. Use compression for network transfers
# Compress-Archive -Path .*.txt -DestinationPath archive.zip
Advanced
27. How to do networking in PowerShell?

PowerShell provides networking capabilities through Invoke-WebRequest, .NET classes, and custom implementations.

  • HTTP: Invoke-WebRequest
  • REST: Invoke-RestMethod
  • WebSocket: Community modules
  • TCP: System.Net.Sockets.TcpClient
  • DNS: [System.Net.Dns]::GetHostAddresses
powershell
# Networking in PowerShell
# HTTP GET request
function Invoke-Rest {
    param($url)
    try {
        $response = Invoke-WebRequest -Uri $url -Method Get
        return $response.Content
    } catch {
        Write-Host "Error: $($_.Exception.Message)"
        return $null
    }
}

# Example
# $data = Invoke-Rest "https://api.github.com"

# HTTP POST request
function Send-Data {
    param($url, $data)
    try {
        $json = $data | ConvertTo-Json
        $response = Invoke-WebRequest -Uri $url -Method Post -Body $json -ContentType "application/json"
        return $response.Content
    } catch {
        Write-Host "Error: $($_.Exception.Message)"
        return $null
    }
}

# Using Invoke-RestMethod
$result = Invoke-RestMethod -Uri "https://api.github.com" -Method Get

# WebSocket example
# Install-Module -Name WebSocket
# $ws = New-WebSocket -Uri "wss://echo.websocket.org"
# $ws.Send("Hello")
# $ws.Receive()

# TCP client
function Send-TCP {
    param($hostname, $port, $message)
    $client = New-Object System.Net.Sockets.TcpClient
    $client.Connect($hostname, $port)
    $stream = $client.GetStream()
    $writer = New-Object System.IO.StreamWriter($stream)
    $writer.WriteLine($message)
    $writer.Flush()
    $reader = New-Object System.IO.StreamReader($stream)
    $response = $reader.ReadToEnd()
    $client.Close()
    return $response
}

# TCP server
function Start-TCPServer {
    param($port = 8080)
    $listener = New-Object System.Net.Sockets.TcpListener([System.Net.IPAddress]::Any, $port)
    $listener.Start()
    Write-Host "Server listening on port $port"
    
    while ($true) {
        $client = $listener.AcceptTcpClient()
        $stream = $client.GetStream()
        $reader = New-Object System.IO.StreamReader($stream)
        $writer = New-Object System.IO.StreamWriter($stream)
        $request = $reader.ReadLine()
        $response = "HTTP/1.1 200 OK`r`nContent-Type: text/html`r`n`r`nHello from server!"
        $writer.Write($response)
        $writer.Flush()
        $client.Close()
    }
}

# DNS resolution
[System.Net.Dns]::GetHostAddresses("example.com")

# Ping
Test-Connection -ComputerName "example.com" -Count 4
Advanced
28. How to work with JSON in PowerShell?

PowerShell provides built-in cmdlets for JSON encoding and decoding.

  • Encode: ConvertTo-Json
  • Decode: ConvertFrom-Json
  • Pretty print: ConvertTo-Json -Depth 10
  • File: Get-Content | ConvertFrom-Json
  • Custom: System.Text.Json
powershell
# Working with JSON in PowerShell
# Encode to JSON
$data = @{
    name = "Alice"
    age = 25
    city = "NYC"
    hobbies = @("reading", "coding")
}
$json_string = $data | ConvertTo-Json
Write-Host $json_string

# Pretty print
$pretty_json = $data | ConvertTo-Json -Depth 10
Write-Host $pretty_json

# Decode from JSON
$json_str = '{"name":"Bob","age":30,"city":"LA"}'
$parsed = $json_str | ConvertFrom-Json
Write-Host $parsed.name
Write-Host $parsed.age

# Working with arrays
$json_array = @(1, 2, 3, 4, 5) | ConvertTo-Json
Write-Host $json_array
$parsed_array = $json_array | ConvertFrom-Json
$parsed_array

# Nested structures
$nested = @{
    user = @{
        id = 1
        profile = @{
            name = "Alice"
            email = "alice@example.com"
        }
    }
}
Write-Host ($nested | ConvertTo-Json -Depth 10)

# Read JSON from file
$data = Get-Content "data.json" | ConvertFrom-Json

# Write JSON to file
$data | ConvertTo-Json -Depth 10 | Out-File "data.json"

# Error handling
try {
    $parsed = '{"invalid":"json"}' | ConvertFrom-Json
} catch {
    Write-Host "JSON Error: $($_.Exception.Message)"
}

# Custom JSON serialization
$obj = [PSCustomObject]@{
    Name = "Alice"
    Age = 25
    City = "NYC"
}
$obj | ConvertTo-Json

# Using JsonSerializer
Add-Type -AssemblyName System.Text.Json
$json = [System.Text.Json.JsonSerializer]::Serialize($data)
$parsed = [System.Text.Json.JsonSerializer]::Deserialize($json, [PSCustomObject])
Advanced
29. How to test code in PowerShell?

PowerShell testing is done using Pester, a testing framework for PowerShell.

  • Pester: Install-Module -Name Pester
  • Describe: Test suite
  • It: Test case
  • Should: Assertions
  • Mock: Test doubles
powershell
# Testing in PowerShell
# Using Pester for testing
# Install-Module -Name Pester -Force

# Basic test
Describe "Math tests" {
    It "Adds two numbers" {
        $result = 2 + 2
        $result | Should -Be 4
    }
    
    It "Checks floating point" {
        $result = 0.1 + 0.2
        $result | Should -BeApproximately 0.3 -Within 0.001
    }
}

# Test with exceptions
Describe "Exception tests" {
    It "Throws divide by zero" {
        { 10 / 0 } | Should -Throw
    }
}

# Test with arrays
Describe "Array tests" {
    It "Has correct length" {
        $arr = @(1, 2, 3, 4, 5)
        $arr.Count | Should -Be 5
    }
    
    It "Contains value" {
        $arr = @(1, 2, 3, 4, 5)
        $arr | Should -Contain 3
    }
}

# Test with PSCustomObject
Describe "Object tests" {
    It "Creates person object" {
        $person = [PSCustomObject]@{
            Name = "Alice"
            Age = 25
        }
        $person.Name | Should -Be "Alice"
        $person.Age | Should -Be 25
    }
}

# Test with mocking
Describe "Mock tests" {
    Mock Get-Date { return Get-Date "2024-01-01" }
    
    It "Uses mocked date" {
        (Get-Date).Year | Should -Be 2024
    }
}

# Test with data providers
$testCases = @(
    @{ a = 1; b = 2; expected = 3 }
    @{ a = 0; b = 0; expected = 0 }
    @{ a = -1; b = 1; expected = 0 }
)

Describe "Data-driven tests" {
    It "Adds numbers <a> + <b> = <expected>" -TestCases $testCases {
        param($a, $b, $expected)
        ($a + $b) | Should -Be $expected
    }
}

# Running tests
# Invoke-Pester

# Code coverage
# Invoke-Pester -CodeCoverage *.ps1
Advanced
30. How to debug in PowerShell?

PowerShell provides various debugging tools including Write-Debug, breakpoints, and the debugger.

  • Write-Debug: Write-Debug "Message"
  • Breakpoints: Set-PSBreakpoint
  • Debugger: Wait-Debugger
  • $Error: Error variable
  • Trace-Command: Tracing
powershell
# Debugging in PowerShell
# Using Write-Debug
$DebugPreference = "Continue"
function Debug-Function {
    param($x)
    Write-Debug "Entering function with x = $x"
    $result = $x * 2
    Write-Debug "Result = $result"
    return $result
}
Debug-Function 5

# Using Write-Host for debugging
Write-Host "Debug message" -ForegroundColor Yellow

# Using Set-PSBreakpoint
Set-PSBreakpoint -Script .script.ps1 -Line 10
Set-PSBreakpoint -Variable x
Set-PSBreakpoint -Command Get-Process

# Using trace
Set-PSBreakpoint -Type Trace

# Using $Error variable
$Error[0] | Format-List -Force

# Using try-catch for error handling
try {
    $result = 10 / 0
} catch {
    Write-Host "Error: $($_.Exception.Message)"
    Write-Host "Stack trace: $($_.ScriptStackTrace)"
}

# Using $PSDebugContext
if ($PSDebugContext) {
    Write-Host "Debugging active"
}

# Using Debugger commands
# s (Step into)
# v (Step over)
# c (Continue)
# q (Quit)
# ? (Help)

# Using Wait-Debugger
# Wait-Debugger
# Continue execution with Step into

# Using Trace-Command
Trace-Command -Name ParameterBinding -Expression { Get-Process }

# Using Write-Warning for warnings
Write-Warning "This is a warning"

# Using Write-Error for errors
Write-Error "This is an error"

# Using Write-Information for informational messages
Write-Information "Informational message"
Advanced
31. What are abstract classes in PowerShell?

Abstract classes in PowerShell define base classes with abstract methods that derived classes must implement.

  • Abstract class: class Animal { [string] MakeSound() { throw ... } }
  • Concrete class: class Dog : Animal
  • Inheritance: : base($name, $age)
  • Type checking: $dog -is [Animal]
  • Interfaces: Using abstract classes
powershell
# Abstract Classes and Interfaces in PowerShell
# Abstract class (using abstract methods)
class Animal {
    [string]$Name
    [int]$Age
    
    Animal([string]$name, [int]$age) {
        $this.Name = $name
        $this.Age = $age
    }
    
    [string] MakeSound() {
        throw [System.NotImplementedException]::new("MakeSound method must be overridden")
    }
}

# Concrete classes
class Dog : Animal {
    Dog([string]$name, [int]$age) : base($name, $age) {}
    
    [string] MakeSound() {
        return "Woof!"
    }
}

class Cat : Animal {
    Cat([string]$name, [int]$age) : base($name, $age) {}
    
    [string] MakeSound() {
        return "Meow!"
    }
}

class Sparrow : Animal {
    [float]$Wingspan
    
    Sparrow([string]$name, [int]$age, [float]$wingspan) : base($name, $age) {
        $this.Wingspan = $wingspan
    }
    
    [string] MakeSound() {
        return "Chirp!"
    }
}

# Interface using abstract class
class SoundMaker {
    [string] MakeSound() {
        throw [System.NotImplementedException]::new("MakeSound method must be overridden")
    }
}

class Lion : SoundMaker {
    [string]$Name
    [int]$Age
    
    Lion([string]$name, [int]$age) {
        $this.Name = $name
        $this.Age = $age
    }
    
    [string] MakeSound() {
        return "Roar!"
    }
}

# Usage
$dog = [Dog]::new("Rex", 3)
$cat = [Cat]::new("Whiskers", 2)
$sparrow = [Sparrow]::new("Tweet", 1, 15.0)
$lion = [Lion]::new("Simba", 5)

Write-Host "$($dog.Name) says $($dog.MakeSound())"
Write-Host "$($cat.Name) says $($cat.MakeSound())"
Write-Host "$($sparrow.Name) says $($sparrow.MakeSound())"
Write-Host "$($lion.Name) says $($lion.MakeSound())"

# Type checking
Write-Host ($dog -is [Animal])
Write-Host ($dog -is [Dog])
Advanced
32. What are generic types in PowerShell?

PowerShell supports .NET generic types for type-safe collections and functions.

  • Generic List: [System.Collections.Generic.List[int]]
  • Generic Dictionary: [System.Collections.Generic.Dictionary[string,int]]
  • Generic HashSet: [System.Collections.Generic.HashSet[int]]
  • Generic Queue: [System.Collections.Generic.Queue[int]]
  • Generic Stack: [System.Collections.Generic.Stack[int]]
powershell
# Generic Types in PowerShell
# Using generic List
$list = [System.Collections.Generic.List[int]]::new()
$list.Add(1)
$list.Add(2)
$list.Add(3)

# Using generic Dictionary
$dict = [System.Collections.Generic.Dictionary[string,int]]::new()
$dict.Add("Alice", 25)
$dict.Add("Bob", 30)
$dict.Add("Charlie", 35)

# Using generic HashSet
$set = [System.Collections.Generic.HashSet[int]]::new()
$set.Add(1)
$set.Add(2)
$set.Add(2)  # Won't be added

# Using generic Queue
$queue = [System.Collections.Generic.Queue[int]]::new()
$queue.Enqueue(1)
$queue.Enqueue(2)
$queue.Enqueue(3)

# Using generic Stack
$stack = [System.Collections.Generic.Stack[int]]::new()
$stack.Push(1)
$stack.Push(2)
$stack.Push(3)

# Generic function using type parameters
function Create-GenericList {
    param($type)
    $listType = [System.Collections.Generic.List`1].MakeGenericType($type)
    return [Activator]::CreateInstance($listType)
}

# Usage
$intList = Create-GenericList ([int])
$intList.Add(1)
$intList.Add(2)

$stringList = Create-GenericList ([string])
$stringList.Add("Hello")
$stringList.Add("World")

# Generic method with type parameter
function Get-Item {
    param(
        [Parameter(Mandatory=$true)]
        [System.Collections.Generic.List[object]]$list,
        [int]$index
    )
    return $list[$index]
}

# Using LINQ with generic types
$numbers = [System.Collections.Generic.List[int]]::new()
$numbers.AddRange(@(1, 2, 3, 4, 5))
$evenNumbers = [System.Linq.Enumerable]::Where($numbers, [Func[int,bool]]{ param($x) $x % 2 -eq 0 })
$evenNumbers
Advanced
33. What are traits and composition in PowerShell?

PowerShell uses script blocks and hashtables for trait-like behavior and composition.

  • Script blocks: $Logger = { Write-Host "Log: $($args[0])" }
  • Composition: Using classes
  • Mixins: Hashtable merging
  • Traits: Add-Member
  • Multiple inheritance: Using interfaces
powershell
# Traits and Composition in PowerShell
# Using script blocks as traits
$Logger = {
    Write-Host "Log: $($args[0])"
}

function Use-Logger {
    param($message)
    & $Logger $message
}

# Mixing traits using hashtables
$UserTrait = @{
    Name = ""
    Age = 0
    GetInfo = { return "$($this.Name) is $($this.Age) years old" }
}

$User = [PSCustomObject]@{
    Name = "Alice"
    Age = 25
}
$User = $User | Select-Object * -ExcludeProperty * | Add-Member -PassThru -NotePropertyMembers $UserTrait
Write-Host $User.GetInfo()

# Using classes for composition
class Person {
    [string]$Name
    [int]$Age
    
    Person([string]$name, [int]$age) {
        $this.Name = $name
        $this.Age = $age
    }
    
    [string] GetInfo() {
        return "$($this.Name) is $($this.Age) years old"
    }
}

class Employee {
    hidden [Person]$Person
    [string]$JobTitle
    
    Employee([string]$name, [int]$age, [string]$jobTitle) {
        $this.Person = [Person]::new($name, $age)
        $this.JobTitle = $jobTitle
    }
    
    [string] GetInfo() {
        return "$($this.Person.GetInfo()) and works as $($this.JobTitle)"
    }
}

# Composition with multiple traits
class UserWithTraits {
    [hashtable]$Traits
    
    UserWithTraits([hashtable]$traits) {
        $this.Traits = $traits
    }
    
    [string] GetInfo() {
        $info = @()
        foreach ($key in $this.Traits.Keys) {
            $info += "$key: $($this.Traits[$key])"
        }
        return $info -join ", "
    }
}

# Usage
$employee = [Employee]::new("Alice", 25, "Developer")
Write-Host $employee.GetInfo()

$traits = @{
    Name = "Bob"
    Age = 30
    City = "LA"
}
$user = [UserWithTraits]::new($traits)
Write-Host $user.GetInfo()
Advanced
34. What are generators and coroutines in PowerShell?

PowerShell supports generators through functions that yield values, and coroutines through workflows and tasks.

  • Generator: function Get-Numbers { $i..$end }
  • Coroutine: workflow
  • State: return { $state++ }
  • Async: [System.Threading.Tasks.Task]::Run
  • Lazy: Pipeline
powershell
# Generators and Coroutines in PowerShell
# Using PowerShell functions as generators
function Get-Fibonacci {
    param($count)
    $a = 0
    $b = 1
    for ($i = 0; $i -lt $count; $i++) {
        $a, $b = $b, $a + $b
        $a
    }
}

# Using yield-like behavior with return
function Get-Numbers {
    param($start, $end)
    for ($i = $start; $i -le $end; $i++) {
        $i
    }
}

# Generator with state
function Get-Counter {
    $state = 0
    return {
        $state++
        return $state
    }
}

$counter = Get-Counter
Write-Host (& $counter)  # 1
Write-Host (& $counter)  # 2
Write-Host (& $counter)  # 3

# Generator with yield return using pipeline
function Get-Squares {
    param($n)
    1..$n | ForEach-Object { $_ * $_ }
}

# Coroutine using workflows
workflow Process-Items {
    param($items)
    foreach -parallel ($item in $items) {
        Start-Sleep -Seconds 1
        $item
    }
}

# Using Lazy evaluation
$lazy = 1..100 | Where-Object { $_ -gt 50 } | ForEach-Object { $_ * $_ }

# Using script blocks as coroutines
function Coroutine {
    $state = 0
    while ($true) {
        if ($state -eq 0) {
            $state = 1
            return "First call"
        } elseif ($state -eq 1) {
            $state = 2
            return "Second call"
        } else {
            $state = 0
            return "Third call"
        }
    }
}

$coroutine = Coroutine
for ($i = 0; $i -lt 6; $i++) {
    Write-Host $coroutine
}

# Using Task for async/await
$task = [System.Threading.Tasks.Task]::Run({
    Start-Sleep -Seconds 2
    return "Task completed"
})
$result = $task.Result
Advanced
35. What are advanced array operations in PowerShell?

PowerShell provides advanced array operations including matrix operations and element-wise transformations.

  • Matrix ops: Matrix-Multiply
  • Element-wise: ForEach-Object
  • Transpose: Transpose-Matrix
  • Norm: Frobenius norm
  • Trace/Diagonal: Custom functions
powershell
# Advanced Array Operations
# Array initialization
$A = New-Object 'double[,]' 3,3
$B = New-Object 'double[,]' 3,3
$C = New-Object 'double[,]' 3,3

# Initialize with values
for ($i = 0; $i -lt 3; $i++) {
    for ($j = 0; $j -lt 3; $j++) {
        $A[$i, $j] = 0
        $B[$i, $j] = 1
        $C[$i, $j] = 5
    }
}

# Identity matrix
$I = New-Object 'double[,]' 3,3
for ($i = 0; $i -lt 3; $i++) {
    for ($j = 0; $j -lt 3; $j++) {
        $I[$i, $j] = if ($i -eq $j) { 1 } else { 0 }
    }
}

# Reshaping (flatten)
$arr = 1..9
$matrix = $arr | ForEach-Object -Begin { $row = @() } -Process { 
    $row += $_
    if ($row.Count -eq 3) { 
        $row 
        $row = @() 
    } 
}

# Transpose
function Transpose-Matrix {
    param($matrix)
    $rows = $matrix.GetLength(0)
    $cols = $matrix.GetLength(1)
    $result = New-Object 'double[,]' $cols, $rows
    
    for ($i = 0; $i -lt $rows; $i++) {
        for ($j = 0; $j -lt $cols; $j++) {
            $result[$j, $i] = $matrix[$i, $j]
        }
    }
    return $result
}

# Element-wise operations
$A = @(@(1,2,3), @(4,5,6), @(7,8,9))
$B = $A | ForEach-Object { $_ | ForEach-Object { $_ + 1 } }
$C = $A | ForEach-Object { $_ | ForEach-Object { $_ * 2 } }
$D = $A | ForEach-Object { $_ | ForEach-Object { $_ * $_ } }

# Matrix multiplication
function Matrix-Multiply {
    param($A, $B)
    $rows = $A.Count
    $cols = $B[0].Count
    $inner = $B.Count
    $result = New-Object 'double[,]' $rows, $cols
    
    for ($i = 0; $i -lt $rows; $i++) {
        for ($j = 0; $j -lt $cols; $j++) {
            $sum = 0
            for ($k = 0; $k -lt $inner; $k++) {
                $sum += $A[$i][$k] * $B[$k][$j]
            }
            $result[$i, $j] = $sum
        }
    }
    return $result
}

# Norm (Frobenius)
function Get-Norm {
    param($matrix)
    $sum = 0
    foreach ($row in $matrix) {
        foreach ($val in $row) {
            $sum += $val * $val
        }
    }
    return [math]::Sqrt($sum)
}

# Trace
function Get-Trace {
    param($matrix)
    $sum = 0
    for ($i = 0; $i -lt $matrix.Count; $i++) {
        $sum += $matrix[$i][$i]
    }
    return $sum
}

# Diagonal
function Get-Diagonal {
    param($matrix)
    $result = @()
    for ($i = 0; $i -lt $matrix.Count; $i++) {
        $result += $matrix[$i][$i]
    }
    return $result
}

Write-Host "Norm: $(Get-Norm $A)"
Write-Host "Trace: $(Get-Trace $A)"
Write-Host "Diagonal: $(Get-Diagonal $A -join ', ')"
Advanced
36. How to handle missing data in PowerShell?

PowerShell handles missing data using $null values with various operators and functions.

  • Null coalescing: $value ?? "default"
  • Null coalescing assignment: $value ??= "default"
  • Null check: $value -eq $null
  • Filter: Where-Object { $_ -ne $null }
  • AllowNull: [AllowNull()][string]$value
powershell
# Working with Missing Data (Null handling)
# Creating arrays with missing values
$data = @(1, 2, $null, 4, 5, $null, 7)
$data

# Check for null values
function Has-Null {
    param($array)
    return $array -contains $null
}
Write-Host "Has null: $(Has-Null $data)"

# Remove null values
$clean_data = $data | Where-Object { $_ -ne $null }
$clean_data

# Replace null values
$replaced = $data | ForEach-Object { $_ ?? 0 }
$replaced

# Operations with null values
$x = @(1, 2, $null, 4)
$y = @(5, 6, $null, 8)

$z = for ($i = 0; $i -lt $x.Count; $i++) {
    if ($x[$i] -ne $null -and $y[$i] -ne $null) {
        $x[$i] + $y[$i]
    } else {
        $null
    }
}
$z

# Ignoring null values
$sum_complete = ($x | Where-Object { $_ -ne $null } | Measure-Object -Sum).Sum
Write-Host "Sum of complete data: $sum_complete"

# Null coalescing operator (PowerShell 7.0+)
$value = $null ?? "default"
Write-Host $value

# Null coalescing assignment (PowerShell 7.0+)
$value = $null
$value ??= "default"
Write-Host $value

# Optional and nullable types
function Process-Nullable {
    param([AllowNull()][string]$value)
    return $value ?? "null value"
}

# Working with null in hashtables
$hash = @{
    Name = "Alice"
    Age = $null
    City = "NYC"
}

foreach ($key in $hash.Keys) {
    if ($hash[$key] -eq $null) {
        Write-Host "$key is null"
    } else {
        Write-Host "$key: $($hash[$key])"
    }
}

# Using $null comparison
$arr = @{a = $null; b = 1}
Write-Host ($null -eq $arr.a)  # true
Write-Host ($arr.ContainsKey('a'))  # true
Advanced
37. How to do sorting and searching in PowerShell?

PowerShell provides built-in sorting and searching capabilities through cmdlets and custom functions.

  • Sort: Sort-Object
  • Custom sort: Sort-Object { $_[0] }
  • Search: Where-Object
  • Binary search: Custom implementation
  • Contains: -contains
powershell
# Sorting and Searching
# Basic sorting
$arr = @(5, 2, 8, 1, 9, 3)
$sorted = $arr | Sort-Object
$sorted

# Sorting with custom comparator
$arr3 = @(@(5, "apple"), @(3, "banana"), @(8, "cherry"))
$sorted3 = $arr3 | Sort-Object { $_[0] }
$sorted3

# Sorting descending
$arr4 = @(5, 2, 8, 1, 9, 3)
$sorted4 = $arr4 | Sort-Object -Descending
$sorted4

# Sort by property
$people = @(
    [PSCustomObject]@{Name="Alice"; Age=25}
    [PSCustomObject]@{Name="Bob"; Age=30}
    [PSCustomObject]@{Name="Charlie"; Age=25}
)
$sorted5 = $people | Sort-Object Age, Name
$sorted5

# Search functions
$arr6 = @(1, 3, 5, 7, 9, 11)
$greater_than_5 = $arr6 | Where-Object { $_ -gt 5 }
$greater_than_5

$first_greater_than_5 = $arr6 | Where-Object { $_ -gt 5 } | Select-Object -First 1
Write-Host "First greater: $first_greater_than_5"

$last_greater_than_5 = $arr6 | Where-Object { $_ -gt 5 } | Select-Object -Last 1
Write-Host "Last greater: $last_greater_than_5"

# Contains
$has_seven = $arr6 -contains 7
$has_four = $arr6 -contains 4
Write-Host "Has 7: $has_seven"
Write-Host "Has 4: $has_four"

# Binary search
function Binary-Search {
    param($arr, $target)
    $left = 0
    $right = $arr.Count - 1
    
    while ($left -le $right) {
        $mid = [math]::Floor(($left + $right) / 2)
        if ($arr[$mid] -eq $target) {
            return $mid
        } elseif ($arr[$mid] -lt $target) {
            $left = $mid + 1
        } else {
            $right = $mid - 1
        }
    }
    return -1
}

$arr7 = @(1, 2, 3, 4, 5, 6, 7)
$index = Binary-Search $arr7 5
Write-Host "Found at index: $index"
Advanced
38. What are mathematical operations in PowerShell?

PowerShell provides mathematical operations through arithmetic operators and .NET Math class.

  • Arithmetic: +, -, *, /, %
  • Trigonometric: [math]::Sin, [math]::Cos
  • Random: Get-Random
  • Statistics: Measure-Object
  • Linear algebra: Custom functions
powershell
# Mathematical Operations
# Basic arithmetic
$x = 10
$y = 3
Write-Host "x + y = $($x + $y)"
Write-Host "x - y = $($x - $y)"
Write-Host "x * y = $($x * $y)"
Write-Host "x / y = $($x / $y)"
Write-Host "x % y = $($x % $y)"
Write-Host "x ^ y = $([math]::Pow($x, $y))"

# Mathematical functions
$pi = [math]::PI
Write-Host "sin(pi/4) = $([math]::Sin($pi / 4))"
Write-Host "cos(pi/4) = $([math]::Cos($pi / 4))"
Write-Host "tan(pi/4) = $([math]::Tan($pi / 4))"
Write-Host "exp(1) = $([math]::Exp(1))"
Write-Host "log(e) = $([math]::Log([math]::Exp(1)))"
Write-Host "log10(100) = $([math]::Log10(100))"
Write-Host "sqrt(9) = $([math]::Sqrt(9))"

# Special functions
Write-Host "abs(-5) = $([math]::Abs(-5))"
Write-Host "ceil(3.14) = $([math]::Ceiling(3.14))"
Write-Host "floor(3.14) = $([math]::Floor(3.14))"
Write-Host "round(3.14) = $([math]::Round(3.14))"
Write-Host "max(1, 3, 5) = $([math]::Max(1, [math]::Max(3, 5)))"
Write-Host "min(1, 3, 5) = $([math]::Min(1, [math]::Min(3, 5)))"

# Random numbers
Write-Host "Random int: $(Get-Random -Minimum 1 -Maximum 10)"
Write-Host "Random double: $(Get-Random -Minimum 0.0 -Maximum 1.0)"

# Statistics
$data = @(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Write-Host "sum = $(($data | Measure-Object -Sum).Sum)"
Write-Host "mean = $(($data | Measure-Object -Average).Average)"
Write-Host "min = $(($data | Measure-Object -Minimum).Minimum)"
Write-Host "max = $(($data | Measure-Object -Maximum).Maximum)"
Advanced
39. How to do data serialization in PowerShell?

PowerShell provides various serialization methods including XML, JSON, CSV, and CLI XML.

  • CLI XML: Export-CliXml
  • JSON: ConvertTo-Json
  • CSV: Export-Csv
  • XML: System.Xml.XmlDocument
  • Binary: BinaryFormatter
powershell
# Data Serialization
# Using Export-CliXml and Import-CliXml
$data = @{
    Name = "Alice"
    Age = 25
    Hobbies = @("reading", "coding")
}
$data | Export-CliXml -Path "data.xml"
$imported = Import-CliXml -Path "data.xml"
$imported

# Using ConvertTo-Json and ConvertFrom-Json
$json = $data | ConvertTo-Json -Depth 10
$json | Out-File "data.json"
$parsed = Get-Content "data.json" | ConvertFrom-Json
$parsed

# Using Export-Csv and Import-Csv
$people = @(
    [PSCustomObject]@{Name="Alice"; Age=25; City="NYC"}
    [PSCustomObject]@{Name="Bob"; Age=30; City="LA"}
)
$people | Export-Csv -Path "people.csv" -NoTypeInformation
$imported = Import-Csv "people.csv"
$imported

# Using BinaryFormatter (deprecated)
$binary = [System.IO.MemoryStream]::new()
$formatter = [System.Runtime.Serialization.Formatters.Binary.BinaryFormatter]::new()
$formatter.Serialize($binary, $data)
$binary.Position = 0
$deserialized = $formatter.Deserialize($binary)
$deserialized

# Using XML
$xml = [System.Xml.XmlDocument]::new()
$root = $xml.CreateElement("root")
$xml.AppendChild($root) | Out-Null

foreach ($key in $data.Keys) {
    $element = $xml.CreateElement($key)
    $element.InnerText = $data[$key]
    $root.AppendChild($element) | Out-Null
}
$xml.Save("data.xml")

# Using YAML (requires module)
# Install-Module -Name powershell-yaml
# $yaml = ConvertTo-Yaml $data
# $yaml | Out-File "data.yaml"
# $parsed = Get-Content "data.yaml" | ConvertFrom-Yaml

# Using Protobuf (requires module)
# Install-Module -Name PSProtobuf
# $bytes = ConvertTo-Protobuf $data
# $parsed = ConvertFrom-Protobuf $bytes
Advanced
40. How to interface with external systems in PowerShell?

PowerShell can interface with databases, Redis, Memcached, and execute shell commands.

  • Database: System.Data.SqlClient
  • SQLite: PSSQLite
  • MySQL: MySql module
  • Redis: Redis module
  • Shell: & "command"
powershell
# Interfacing with External Systems
# Database connections
$connectionString = "Server=localhost;Database=test;User Id=user;Password=pass;"
try {
    $connection = New-Object System.Data.SqlClient.SqlConnection($connectionString)
    $connection.Open()
    $command = $connection.CreateCommand()
    $command.CommandText = "SELECT * FROM users WHERE id = @id"
    $command.Parameters.AddWithValue("@id", 1) | Out-Null
    $reader = $command.ExecuteReader()
    while ($reader.Read()) {
        Write-Host "User: $($reader['name'])"
    }
    $connection.Close()
} catch {
    Write-Host "Database error: $($_.Exception.Message)"
}

# SQLite
# Install-Module -Name PSSQLite
# $data = Invoke-SqliteQuery -DataSource "database.db" -Query "SELECT * FROM users"

# MySQL
# Install-Module -Name MySql
# $connectionString = "Server=localhost;Database=test;Uid=user;Pwd=pass;"
# $connection = New-Object MySql.Data.MySqlClient.MySqlConnection($connectionString)

# PostgreSQL
# Install-Module -Name Npgsql
# $connectionString = "Host=localhost;Database=test;Username=user;Password=pass"
# $connection = New-Object Npgsql.NpgsqlConnection($connectionString)

# Redis (requires module)
# Install-Module -Name Redis
# $redis = Connect-Redis -Host "localhost" -Port 6379
# Set-RedisKey -Key "key" -Value "value"
# $value = Get-RedisKey -Key "key"

# Executing shell commands
$output = & "ls" "-la"
Write-Host $output

# Using Start-Process
Start-Process -FilePath "notepad.exe" -WindowStyle Normal

# Using Invoke-Command
$session = New-PSSession -ComputerName "server"
Invoke-Command -Session $session -ScriptBlock { Get-Process }

# REST API
$response = Invoke-RestMethod -Uri "https://api.github.com" -Method Get
Write-Host $response
Coding Round
41. Reverse a string

Reverse a string using array reversal, manual iteration, or recursion.

  • Array method: [array]::Reverse($chars)
  • Manual: for ($i = $s.Length - 1; $i -ge 0; $i--)
  • Recursive: function Reverse-StringRecursive
  • Performance: O(n) time
powershell
# Reverse a string
function Reverse-String {
    param([string]$s)
    $chars = $s.ToCharArray()
    [array]::Reverse($chars)
    return -join $chars
}

function Reverse-StringManual {
    param([string]$s)
    $reversed = ""
    for ($i = $s.Length - 1; $i -ge 0; $i--) {
        $reversed += $s[$i]
    }
    return $reversed
}

function Reverse-StringRecursive {
    param([string]$s)
    if ($s.Length -le 1) {
        return $s
    }
    return (Reverse-StringRecursive $s.Substring(1)) + $s[0]
}

$s = "hello"
Write-Host "Original: $s"
Write-Host "Reversed: $(Reverse-String $s)"
Write-Host "Reversed (manual): $(Reverse-StringManual $s)"
Write-Host "Reversed (recursive): $(Reverse-StringRecursive $s)"
Coding Round
42. Check palindrome

Check if a string is a palindrome by comparing characters from both ends.

  • Method: Is-Palindrome
  • Case insensitive: ToLower
  • Ignore spaces: Replace(" ", "")
  • Recursive: Is-PalindromeRecursive
powershell
# Check palindrome
function Is-Palindrome {
    param([string]$s)
    $cleaned = $s.ToLower().Replace(" ", "")
    $reversed = -join ($cleaned.ToCharArray() | ForEach-Object { $_ } | Sort-Object -Descending)
    return $cleaned -eq $reversed
}

function Is-PalindromeManual {
    param([string]$s)
    $cleaned = $s.ToLower().Replace(" ", "")
    $len = $cleaned.Length
    for ($i = 0; $i -lt $len / 2; $i++) {
        if ($cleaned[$i] -ne $cleaned[$len - 1 - $i]) {
            return $false
        }
    }
    return $true
}

function Is-PalindromeRecursive {
    param([string]$s)
    $cleaned = $s.ToLower().Replace(" ", "")
    if ($cleaned.Length -le 1) {
        return $true
    }
    if ($cleaned[0] -ne $cleaned[-1]) {
        return $false
    }
    return Is-PalindromeRecursive $cleaned.Substring(1, $cleaned.Length - 2)
}

$strings = @("racecar", "hello", "A man a plan a canal Panama", "race a car")
foreach ($s in $strings) {
    Write-Host "`"$s`" is palindrome: $(Is-Palindrome $s)"
}
Coding Round
43. Find max in array

Find the maximum value using Measure-Object, iteration, or recursion.

  • Built-in: Measure-Object -Maximum
  • Manual: foreach ($value in $arr)
  • Recursive: Get-MaxRecursive
  • Edge cases: Empty array
powershell
# Find max in array
function Get-Max {
    param($arr)
    return ($arr | Measure-Object -Maximum).Maximum
}

function Get-MaxManual {
    param($arr)
    if ($arr.Count -eq 0) { return $null }
    $max = $arr[0]
    foreach ($value in $arr) {
        if ($value -gt $max) {
            $max = $value
        }
    }
    return $max
}

function Get-MaxRecursive {
    param($arr, $index = 0, $max = $null)
    if ($index -ge $arr.Count) {
        return $max
    }
    if ($max -eq $null -or $arr[$index] -gt $max) {
        $max = $arr[$index]
    }
    return Get-MaxRecursive $arr ($index + 1) $max
}

$arr = @(1, 5, 3, 9, 2)
Write-Host "Array: $($arr -join ', ')"
Write-Host "Max: $(Get-Max $arr)"
Write-Host "Max (manual): $(Get-MaxManual $arr)"
Write-Host "Max (recursive): $(Get-MaxRecursive $arr)"
Coding Round
44. Remove duplicates

Remove duplicates using Sort-Object -Unique or manual tracking.

  • Built-in: $arr | Sort-Object -Unique
  • Manual: seen hashtable
  • Preserve order: Manual method
  • Time: O(n)
powershell
# Remove duplicates
function Remove-Duplicates {
    param($arr)
    return $arr | Sort-Object -Unique
}

function Remove-DuplicatesManual {
    param($arr)
    $seen = @{}
    $result = @()
    foreach ($value in $arr) {
        if (-not $seen.ContainsKey($value)) {
            $seen[$value] = $true
            $result += $value
        }
    }
    return $result
}

$arr = @("apple", "banana", "apple", "orange", "banana", "grape")
Write-Host "Original: $($arr -join ', ')"
Write-Host "Without duplicates: $(Remove-Duplicates $arr -join ', ')"
Write-Host "Without duplicates (manual): $(Remove-DuplicatesManual $arr -join ', ')"
Coding Round
45. Merge arrays

Merge arrays using addition, Merge-Arrays, or sorted merge.

  • Addition: $arr1 + $arr2
  • Sorted merge: Merge-Sorted
  • Unique: Sort-Object -Unique
  • Performance: O(n) time
powershell
# Merge arrays
function Merge-Arrays {
    param($arr1, $arr2)
    return $arr1 + $arr2
}

function Merge-Sorted {
    param($arr1, $arr2)
    $result = @()
    $i = 0
    $j = 0
    
    while ($i -lt $arr1.Count -and $j -lt $arr2.Count) {
        if ($arr1[$i] -le $arr2[$j]) {
            $result += $arr1[$i]
            $i++
        } else {
            $result += $arr2[$j]
            $j++
        }
    }
    
    while ($i -lt $arr1.Count) {
        $result += $arr1[$i]
        $i++
    }
    
    while ($j -lt $arr2.Count) {
        $result += $arr2[$j]
        $j++
    }
    
    return $result
}

function Merge-Unique {
    param($arr1, $arr2)
    return ($arr1 + $arr2) | Sort-Object -Unique
}

$arr1 = @(1, 2, 3)
$arr2 = @(4, 5, 6)
Write-Host "Merged: $(Merge-Arrays $arr1 $arr2 -join ', ')"

$sorted1 = @(1, 3, 5, 7)
$sorted2 = @(2, 4, 6, 8)
Write-Host "Merged sorted: $(Merge-Sorted $sorted1 $sorted2 -join ', ')"
Coding Round
46. Convert string to number

Convert string to number using type casting or TryParse.

  • Cast: [int]$s, [double]$s
  • Safe: [double]::TryParse
  • Error handling: try
  • Default: Return 0 on failure
powershell
# Convert string to number
function Convert-ToNumber {
    param([string]$s)
    return [double]$s
}

function Convert-ToInt {
    param([string]$s)
    return [int]$s
}

function Convert-ToFloat {
    param([string]$s)
    return [double]$s
}

function Convert-ToNumberSafe {
    param([string]$s)
    $result = 0
    if ([double]::TryParse($s, [ref]$result)) {
        return $result
    }
    return 0
}

$strings = @("42", "3.14", "hello", "123", "45.67")
foreach ($s in $strings) {
    Write-Host "`"$s`" -> int: $(Convert-ToInt $s), float: $(Convert-ToFloat $s)"
}
Coding Round
47. Loop through dictionary

Iterate through hashtable using foreach or GetEnumerator.

  • Keys: foreach ($key in $dict.Keys)
  • GetEnumerator: $dict.GetEnumerator()
  • Find: $dict.ContainsKey($key)
  • Return: $dict[$key] ?? $null
powershell
# Loop through dictionary (hashtable)
function Loop-Dictionary {
    param($dict)
    foreach ($key in $dict.Keys) {
        Write-Host "$key => $($dict[$key])"
    }
}

function Find-Key {
    param($dict, $key)
    if ($dict.ContainsKey($key)) {
        return $dict[$key]
    }
    return $null
}

$data = @{
    Name = "Alice"
    Age = 25
    City = "NYC"
}

Write-Host "Dictionary:"
Loop-Dictionary $data
Write-Host ""

$name = Find-Key $data "Name"
Write-Host "Name: $name"
$country = Find-Key $data "Country"
Write-Host "Country: $(if ($country -eq $null) { 'Not found' } else { $country })"
Coding Round
48. Delay function execution

Delay execution using Start-Sleep or Start-Job for async.

  • Blocking: Start-Sleep -Seconds $seconds
  • Async: Start-Job
  • Callback: Delay-WithCallback
  • Use case: Scheduling
powershell
# Delay function execution
function Delay-Seconds {
    param($seconds, $callback)
    Start-Sleep -Seconds $seconds
    return & $callback
}

function Delay-Async {
    param($seconds, $callback)
    $job = Start-Job -ScriptBlock {
        param($sec, $cb)
        Start-Sleep -Seconds $sec
        & $cb
    } -ArgumentList $seconds, $callback
    return $job
}

function Delay-WithCallback {
    param($seconds, $callback, $resultCallback)
    $job = Start-Job -ScriptBlock {
        param($sec, $cb, $resultCb)
        Start-Sleep -Seconds $sec
        $result = & $cb
        & $resultCb $result
    } -ArgumentList $seconds, $callback, $resultCallback
    return $job
}

function Delayed-Print {
    param($message, $seconds)
    Write-Host "Starting delay of $seconds seconds"
    Delay-Seconds $seconds { Write-Host $message }
}

Write-Host "Delayed execution examples:"
Delayed-Print "After 2 seconds" 2
Write-Host "Main script continues"
Coding Round
49. HTTP GET request

Make HTTP requests using Invoke-WebRequest or Invoke-RestMethod.

  • GET: Invoke-WebRequest -Uri $url
  • POST: Invoke-WebRequest -Method Post
  • Headers: -Headers parameter
  • Error handling: try-catch
powershell
# HTTP GET request
function Get-Url {
    param($url)
    try {
        $response = Invoke-WebRequest -Uri $url -Method Get -UserAgent "PowerShell Script"
        return $response.Content
    } catch {
        Write-Host "Error: $($_.Exception.Message)"
        return $null
    }
}

function Post-Data {
    param($url, $data)
    try {
        $json = $data | ConvertTo-Json
        $response = Invoke-WebRequest -Uri $url -Method Post -Body $json -ContentType "application/json"
        return $response.Content
    } catch {
        Write-Host "Error: $($_.Exception.Message)"
        return $null
    }
}

try {
    $result = Get-Url "https://api.github.com"
    if ($result) {
        Write-Host $result.Substring(0, 500) + "..."
    }
} catch {
    Write-Host "Error: $($_.Exception.Message)"
}

# Example POST request
$postData = @{
    Name = "Alice"
    Age = 25
}
# $result = Post-Data "https://httpbin.org/post" $postData
# Write-Host $result
Coding Round
50. Create a promise-like task

Create promise-like behavior using script blocks with resolve/reject functions.

  • Promise: New-Promise
  • Then: Then method
  • Catch: Catch method
  • All: Promise.All
powershell
# Create a promise-like task
function New-Promise {
    param($executor)
    $result = $null
    $state = "pending"
    $callbacks = @()
    
    function Resolve {
        param($value)
        if ($state -ne "pending") { return }
        $state = "fulfilled"
        $result = $value
        foreach ($callback in $callbacks) {
            & $callback $value
        }
    }
    
    function Reject {
        param($reason)
        if ($state -ne "pending") { return }
        $state = "rejected"
        $result = $reason
        foreach ($callback in $callbacks) {
            & $callback $reason
        }
    }
    
    $promise = [PSCustomObject]@{
        State = $state
        Result = $result
        Then = {
            param($onFulfilled, $onRejected)
            $newPromise = New-Promise {
                param($resolve, $reject)
                $callback = {
                    param($value)
                    if ($state -eq "fulfilled" -and $onFulfilled) {
                        try {
                            $newResult = & $onFulfilled $value
                            & $resolve $newResult
                        } catch {
                            & $reject $_
                        }
                    } elseif ($state -eq "rejected" -and $onRejected) {
                        try {
                            $newResult = & $onRejected $value
                            & $resolve $newResult
                        } catch {
                            & $reject $_
                        }
                    } else {
                        if ($state -eq "fulfilled") { & $resolve $value }
                        else { & $reject $value }
                    }
                }
                if ($state -eq "pending") {
                    $callbacks += $callback
                } else {
                    & $callback $result
                }
            }
            return $newPromise
        }
        Catch = {
            param($onRejected)
            return $promise.Then.Invoke($null, $onRejected)
        }
    }
    
    & $executor $resolve $reject
    return $promise
}

# Usage
$promise1 = New-Promise {
    param($resolve, $reject)
    Start-Sleep -Seconds 1
    & $resolve "Success!"
}

$promise1.Then.Invoke({
    param($value)
    Write-Host "Result: $value"
})

$promise2 = New-Promise {
    param($resolve, $reject)
    Start-Sleep -Seconds 2
    & $reject "Failed!"
}

$promise2.Catch.Invoke({
    param($reason)
    Write-Host "Error: $reason"
})

# Wait for all promises to complete
Start-Sleep -Seconds 3
Coding Round
51. Factorial

Calculate factorial using recursion or iteration.

  • Recursive: function Get-Factorial { if ($n -le 1) { 1 } else { $n * (Get-Factorial ($n - 1)) } }
  • Iterative: for ($i = 2; $i -le $n; $i++)
  • Edge cases: 0! = 1
  • Performance: Iterative faster
powershell
# Factorial
function Get-Factorial {
    param($n)
    if ($n -le 1) {
        return 1
    }
    return $n * (Get-Factorial ($n - 1))
}

function Get-FactorialIterative {
    param($n)
    $result = 1
    for ($i = 2; $i -le $n; $i++) {
        $result *= $i
    }
    return $result
}

$n = 5
Write-Host "Factorial of $n:"
Write-Host "Recursive: $(Get-Factorial $n)"
Write-Host "Iterative: $(Get-FactorialIterative $n)"
Coding Round
52. Fibonacci

Calculate Fibonacci numbers using recursion, iteration, or memoization.

  • Recursive: function Get-Fibonacci
  • Iterative: for ($i = 2; $i -le $n; $i++)
  • Memoized: $cache = @
  • Complexity: O(n) iterative
powershell
# Fibonacci
function Get-Fibonacci {
    param($n)
    if ($n -le 1) {
        return $n
    }
    return (Get-Fibonacci ($n - 1)) + (Get-Fibonacci ($n - 2))
}

function Get-FibonacciIterative {
    param($n)
    if ($n -le 1) {
        return $n
    }
    $a = 0
    $b = 1
    for ($i = 2; $i -le $n; $i++) {
        $c = $a + $b
        $a = $b
        $b = $c
    }
    return $b
}

function Get-FibonacciMemoized {
    param($n)
    $cache = @{}
    function Fib {
        param($num)
        if ($num -le 1) { return $num }
        if (-not $cache.ContainsKey($num)) {
            $cache[$num] = (Fib ($num - 1)) + (Fib ($num - 2))
        }
        return $cache[$num]
    }
    return Fib $n
}

$n = 10
Write-Host "Fibonacci of $n:"
Write-Host "Recursive: $(Get-Fibonacci $n)"
Write-Host "Iterative: $(Get-FibonacciIterative $n)"
Write-Host "Memoized: $(Get-FibonacciMemoized $n)"
Coding Round
53. FizzBuzz

Print numbers with FizzBuzz logic using conditional statements.

  • If-else: if ($i % 15 -eq 0)
  • Switch: switch statement
  • Array: Invoke-FizzBuzzArray
  • Output: Write-Host
powershell
# FizzBuzz
function Invoke-FizzBuzz {
    param($n)
    for ($i = 1; $i -le $n; $i++) {
        if ($i % 15 -eq 0) {
            Write-Host "FizzBuzz"
        } elseif ($i % 3 -eq 0) {
            Write-Host "Fizz"
        } elseif ($i % 5 -eq 0) {
            Write-Host "Buzz"
        } else {
            Write-Host $i
        }
    }
}

function Invoke-FizzBuzzArray {
    param($n)
    $result = @()
    for ($i = 1; $i -le $n; $i++) {
        if ($i % 15 -eq 0) {
            $result += "FizzBuzz"
        } elseif ($i % 3 -eq 0) {
            $result += "Fizz"
        } elseif ($i % 5 -eq 0) {
            $result += "Buzz"
        } else {
            $result += $i.ToString()
        }
    }
    return $result
}

Write-Host "FizzBuzz for 15:"
Invoke-FizzBuzz 15

Write-Host "FizzBuzz array:"
$result = Invoke-FizzBuzzArray 15
Write-Host ($result -join ", ")
Coding Round
54. Find missing number

Find missing number using sum formula or XOR operation.

  • Sum: $total = $n * ($n + 1) / 2
  • XOR: -bxor
  • Time: O(n)
  • Edge cases: Empty array
powershell
# Find missing number
function Find-Missing {
    param($arr)
    $n = $arr.Count + 1
    $total = $n * ($n + 1) / 2
    $sum = ($arr | Measure-Object -Sum).Sum
    return $total - $sum
}

function Find-MissingXOR {
    param($arr)
    $n = $arr.Count + 1
    $xor_all = 0
    for ($i = 1; $i -le $n; $i++) {
        $xor_all = $xor_all -bxor $i
    }
    $xor_arr = 0
    foreach ($value in $arr) {
        $xor_arr = $xor_arr -bxor $value
    }
    return $xor_all -bxor $xor_arr
}

$arr = @(1, 2, 4, 5, 6)
Write-Host "Missing number: $(Find-Missing $arr)"
Write-Host "Missing number (XOR): $(Find-MissingXOR $arr)"
Coding Round
55. Find duplicates

Find duplicates using Group-Object or manual tracking.

  • Group-Object: $arr | Group-Object | Where-Object { $_.Count -gt 1 }
  • Manual: seen hashtable
  • Set: HashSet
  • Time: O(n)
powershell
# Find duplicates
function Find-Duplicates {
    param($arr)
    $seen = @{}
    $duplicates = @()
    foreach ($value in $arr) {
        if ($seen.ContainsKey($value)) {
            if ($duplicates -notcontains $value) {
                $duplicates += $value
            }
        } else {
            $seen[$value] = $true
        }
    }
    return $duplicates
}

function Find-DuplicatesCount {
    param($arr)
    $groups = $arr | Group-Object
    return $groups | Where-Object { $_.Count -gt 1 } | ForEach-Object { $_.Name }
}

$arr = @(1, 2, 3, 2, 4, 3, 5, 6, 5)
Write-Host "Original: $($arr -join ', ')"
Write-Host "Duplicates: $(Find-Duplicates $arr -join ', ')"
Write-Host "Duplicates (count): $(Find-DuplicatesCount $arr -join ', ')"
Coding Round
56. Sum of array

Sum array elements using Measure-Object -Sum or manual loop.

  • Built-in: $arr | Measure-Object -Sum
  • Manual: foreach ($value in $arr) { $sum += $value }
  • Empty: Returns 0
  • Performance: Built-in faster
powershell
# Sum of array
function Get-Sum {
    param($arr)
    return ($arr | Measure-Object -Sum).Sum
}

function Get-SumManual {
    param($arr)
    $sum = 0
    foreach ($value in $arr) {
        $sum += $value
    }
    return $sum
}

$arr = @(1, 2, 3, 4, 5)
Write-Host "Array: $($arr -join ', ')"
Write-Host "Sum: $(Get-Sum $arr)"
Write-Host "Sum (manual): $(Get-SumManual $arr)"
Coding Round
57. Average of array

Calculate average using Measure-Object -Average or manual division.

  • Built-in: $arr | Measure-Object -Average
  • Manual: ($sum) / $arr.Count
  • Integer: [math]::Floor
  • Empty: Return 0
powershell
# Average of array
function Get-Average {
    param($arr)
    if ($arr.Count -eq 0) { return 0 }
    return ($arr | Measure-Object -Average).Average
}

function Get-AverageFloat {
    param($arr)
    if ($arr.Count -eq 0) { return 0.0 }
    return (($arr | Measure-Object -Sum).Sum) / $arr.Count
}

function Get-AverageInteger {
    param($arr)
    if ($arr.Count -eq 0) { return 0 }
    return [math]::Floor((($arr | Measure-Object -Sum).Sum) / $arr.Count)
}

$int_arr = @(1, 2, 3, 4, 5)
$float_arr = @(1.0, 2.0, 3.0, 4.0, 5.0)
Write-Host "Average (int array): $(Get-Average $int_arr)"
Write-Host "Average (float array): $(Get-AverageFloat $float_arr)"
Write-Host "Average (integer): $(Get-AverageInteger $int_arr)"
Coding Round
58. Sort array ascending

Sort arrays using Sort-Object or custom sort.

  • Non-mutating: $arr | Sort-Object
  • In-place: $arr = $arr | Sort-Object
  • Custom: Sort-Object { $_ }
  • Performance: Built-in optimized
powershell
# Sort array ascending
function Sort-Ascending {
    param($arr)
    return $arr | Sort-Object
}

function Sort-AscendingInPlace {
    param([ref]$arr)
    $arr.Value = $arr.Value | Sort-Object
}

$arr = @(5, 2, 8, 1, 9, 3)
Write-Host "Original: $($arr -join ', ')"
Write-Host "Sorted ascending: $(Sort-Ascending $arr -join ', ')"
Sort-AscendingInPlace ([ref]$arr)
Write-Host "Sorted in-place: $($arr -join ', ')"
Coding Round
59. Sort array descending

Sort descending using Sort-Object -Descending or custom comparator.

  • Built-in: $arr | Sort-Object -Descending
  • Custom: Sort-Object { $_ } -Descending
  • In-place: $arr = $arr | Sort-Object -Descending
  • Performance: Built-in optimized
powershell
# Sort array descending
function Sort-Descending {
    param($arr)
    return $arr | Sort-Object -Descending
}

function Sort-DescendingInPlace {
    param([ref]$arr)
    $arr.Value = $arr.Value | Sort-Object -Descending
}

$arr = @(5, 2, 8, 1, 9, 3)
Write-Host "Original: $($arr -join ', ')"
Write-Host "Sorted descending: $(Sort-Descending $arr -join ', ')"
Sort-DescendingInPlace ([ref]$arr)
Write-Host "Sorted in-place: $($arr -join ', ')"
Coding Round
60. Flatten nested array

Flatten nested arrays using recursion or iterative stack approach.

  • Recursive: Flatten-Array
  • Iterative: Flatten-ArrayIterative
  • One level: $arr | ForEach-Object { $_ }
  • Depth: Handle arbitrary depth
powershell
# Flatten nested array
function Flatten-Array {
    param($arr)
    $result = @()
    foreach ($item in $arr) {
        if ($item -is [array]) {
            $result += Flatten-Array $item
        } else {
            $result += $item
        }
    }
    return $result
}

function Flatten-ArrayIterative {
    param($arr)
    $result = @()
    $stack = $arr -as [array] | ForEach-Object { $_ } | Sort-Object -Descending
    while ($stack.Count -gt 0) {
        $item = $stack[-1]
        $stack = $stack[0..($stack.Count - 2)]
        if ($item -is [array]) {
            $stack += $item -as [array] | ForEach-Object { $_ }
        } else {
            $result += $item
        }
    }
    return $result
}

$nested = @(@(1, 2), @(3, 4, 5), @(6), @(7, 8, 9, 10))
$deeper = @(@(1, 2), @(3, @(4, 5)))

Write-Host "Nested: $($nested -join ', ')"
Write-Host "Flatten: $(Flatten-Array $nested -join ', ')"
Write-Host "Deeper: $($deeper -join ', ')"
Write-Host "Flatten deeper: $(Flatten-Array $deeper -join ', ')"
Coding Round
61. Chunk array

Split array into chunks using manual slicing or loops.

  • Manual: Chunk-Array
  • Predicate: Chunk-ArrayByPredicate
  • Use case: Batch processing
  • Time: O(n)
powershell
# Chunk array
function Chunk-Array {
    param($arr, $size)
    $result = @()
    $i = 0
    while ($i -lt $arr.Count) {
        $chunk = @()
        for ($j = 0; $j -lt $size -and $i -lt $arr.Count; $j++) {
            $chunk += $arr[$i]
            $i++
        }
        $result += $chunk
    }
    return $result
}

function Chunk-ArrayByPredicate {
    param($arr, $predicate)
    $result = @()
    $current = @()
    foreach ($item in $arr) {
        if (& $predicate $item) {
            if ($current.Count -gt 0) {
                $result += $current
                $current = @()
            }
            $result += @($item)
        } else {
            $current += $item
        }
    }
    if ($current.Count -gt 0) {
        $result += $current
    }
    return $result
}

$arr = 1..10
Write-Host "Original: $($arr -join ', ')"
Write-Host "Chunk (size 3):"
$chunks = Chunk-Array $arr 3
foreach ($chunk in $chunks) {
    Write-Host "[$($chunk -join ', ')]"
}
Coding Round
63. Quick sort

Implement quick sort with partitioning and recursion.

  • Recursive: Quick-Sort
  • In-place: Quick-SortInPlace
  • Pivot: First or last element
  • Time: O(n log n) average
powershell
# Quick sort
function Quick-Sort {
    param($arr)
    if ($arr.Count -le 1) {
        return $arr
    }
    $pivot = $arr[0]
    $left = @()
    $right = @()
    for ($i = 1; $i -lt $arr.Count; $i++) {
        if ($arr[$i] -lt $pivot) {
            $left += $arr[$i]
        } else {
            $right += $arr[$i]
        }
    }
    return (Quick-Sort $left) + $pivot + (Quick-Sort $right)
}

function Quick-SortInPlace {
    param([ref]$arr, $low = 0, $high = $null)
    if ($high -eq $null) {
        $high = $arr.Value.Count - 1
    }
    if ($low -lt $high) {
        $pi = Partition $arr $low $high
        Quick-SortInPlace $arr $low ($pi - 1)
        Quick-SortInPlace $arr ($pi + 1) $high
    }
}

function Partition {
    param([ref]$arr, $low, $high)
    $pivot = $arr.Value[$high]
    $i = $low - 1
    for ($j = $low; $j -lt $high; $j++) {
        if ($arr.Value[$j] -le $pivot) {
            $i++
            $temp = $arr.Value[$i]
            $arr.Value[$i] = $arr.Value[$j]
            $arr.Value[$j] = $temp
        }
    }
    $temp = $arr.Value[$i + 1]
    $arr.Value[$i + 1] = $arr.Value[$high]
    $arr.Value[$high] = $temp
    return $i + 1
}

$arr = @(5, 3, 8, 4, 2, 7, 1, 6)
Write-Host "Original: $($arr -join ', ')"
Write-Host "Quick sort: $(Quick-Sort $arr -join ', ')"
Quick-SortInPlace ([ref]$arr)
Write-Host "Quick sort (in-place): $($arr -join ', ')"
Coding Round
64. Merge sort

Implement merge sort with divide and conquer approach.

  • Divide: Split array
  • Merge: Merge function
  • Time: O(n log n)
  • Space: O(n)
powershell
# Merge sort
function Merge-Sort {
    param($arr)
    if ($arr.Count -le 1) {
        return $arr
    }
    $mid = [math]::Floor($arr.Count / 2)
    $left = Merge-Sort $arr[0..($mid - 1)]
    $right = Merge-Sort $arr[$mid..($arr.Count - 1)]
    return Merge $left $right
}

function Merge {
    param($left, $right)
    $result = @()
    $i = 0
    $j = 0
    while ($i -lt $left.Count -and $j -lt $right.Count) {
        if ($left[$i] -le $right[$j]) {
            $result += $left[$i]
            $i++
        } else {
            $result += $right[$j]
            $j++
        }
    }
    while ($i -lt $left.Count) {
        $result += $left[$i]
        $i++
    }
    while ($j -lt $right.Count) {
        $result += $right[$j]
        $j++
    }
    return $result
}

$arr = @(5, 3, 8, 4, 2, 7, 1, 6)
Write-Host "Original: $($arr -join ', ')"
Write-Host "Merge sort: $(Merge-Sort $arr -join ', ')"
Coding Round
65. Bubble sort

Implement bubble sort with optimization to stop early if no swaps occur.

  • Basic: for ($i = 0; $i -lt $n - 1; $i++)
  • Optimized: $swapped flag
  • Time: O(n²) worst case
  • Use case: Small datasets
powershell
# Bubble sort
function Bubble-Sort {
    param($arr)
    $n = $arr.Count
    for ($i = 0; $i -lt $n - 1; $i++) {
        for ($j = 0; $j -lt $n - $i - 1; $j++) {
            if ($arr[$j] -gt $arr[$j + 1]) {
                $temp = $arr[$j]
                $arr[$j] = $arr[$j + 1]
                $arr[$j + 1] = $temp
            }
        }
    }
    return $arr
}

function Bubble-SortOptimized {
    param($arr)
    $n = $arr.Count
    for ($i = 0; $i -lt $n - 1; $i++) {
        $swapped = $false
        for ($j = 0; $j -lt $n - $i - 1; $j++) {
            if ($arr[$j] -gt $arr[$j + 1]) {
                $temp = $arr[$j]
                $arr[$j] = $arr[$j + 1]
                $arr[$j + 1] = $temp
                $swapped = $true
            }
        }
        if (-not $swapped) {
            break
        }
    }
    return $arr
}

$arr = @(5, 3, 8, 4, 2, 7, 1, 6)
Write-Host "Original: $($arr -join ', ')"
Write-Host "Bubble sort: $(Bubble-Sort $arr -join ', ')"
Write-Host "Bubble sort optimized: $(Bubble-SortOptimized $arr -join ', ')"
Coding Round
66. Intersection of arrays

Find intersection using Where-Object or hashtable lookup.

  • Where-Object: $arr1 | Where-Object { $arr2 -contains $_ }
  • Hashtable: containsKey
  • Time: O(n*m) or O(n+m) with set
  • Unique: Returns unique values
powershell
# Intersection of arrays
function Get-Intersection {
    param($arr1, $arr2)
    return $arr1 | Where-Object { $arr2 -contains $_ }
}

function Get-IntersectionSet {
    param($arr1, $arr2)
    $set = @{}
    foreach ($item in $arr2) {
        $set[$item] = $true
    }
    $result = @()
    foreach ($item in $arr1) {
        if ($set.ContainsKey($item)) {
            $result += $item
        }
    }
    return $result
}

$arr1 = @("apple", "banana", "orange", "grape", "kiwi")
$arr2 = @("banana", "kiwi", "mango", "grape")
Write-Host "Intersection: $(Get-Intersection $arr1 $arr2 -join ', ')"
Write-Host "Intersection (set): $(Get-IntersectionSet $arr1 $arr2 -join ', ')"

$ints1 = @(1, 2, 3, 4, 5)
$ints2 = @(4, 5, 6, 7, 8)
Write-Host "Intersection (ints): $(Get-Intersection $ints1 $ints2 -join ', ')"
Coding Round
67. Union of arrays

Union arrays using Sort-Object -Unique or manual merge.

  • Built-in: ($arr1 + $arr2) | Sort-Object -Unique
  • Manual: contains check
  • Time: O(n log n) with sort
  • Preserve order: Manual method
powershell
# Union of arrays
function Get-Union {
    param($arr1, $arr2)
    return ($arr1 + $arr2) | Sort-Object -Unique
}

function Get-UnionManual {
    param($arr1, $arr2)
    $result = $arr1
    foreach ($item in $arr2) {
        if ($result -notcontains $item) {
            $result += $item
        }
    }
    return $result
}

$arr1 = @("apple", "banana", "orange")
$arr2 = @("orange", "grape", "kiwi")
Write-Host "Union: $(Get-Union $arr1 $arr2 -join ', ')"
Write-Host "Union (manual): $(Get-UnionManual $arr1 $arr2 -join ', ')"

$ints1 = @(1, 2, 3, 4)
$ints2 = @(4, 5, 6, 7)
Write-Host "Union (ints): $(Get-Union $ints1 $ints2 -join ', ')"
Coding Round
68. Difference of arrays

Find difference using Where-Object or symmetric difference.

  • Where-Object: $arr1 | Where-Object { $arr2 -notcontains $_ }
  • Symmetric: Get-SymmetricDifference
  • Time: O(n*m)
  • Performance: Use hashtable for O(n)
powershell
# Difference of arrays
function Get-Difference {
    param($arr1, $arr2)
    return $arr1 | Where-Object { $arr2 -notcontains $_ }
}

function Get-SymmetricDifference {
    param($arr1, $arr2)
    $diff1 = Get-Difference $arr1 $arr2
    $diff2 = Get-Difference $arr2 $arr1
    return $diff1 + $diff2
}

$arr1 = @("apple", "banana", "orange", "grape")
$arr2 = @("banana", "kiwi", "grape")
Write-Host "Difference: $(Get-Difference $arr1 $arr2 -join ', ')"
Write-Host "Symmetric difference: $(Get-SymmetricDifference $arr1 $arr2 -join ', ')"

$ints1 = @(1, 2, 3, 4, 5)
$ints2 = @(4, 5, 6, 7, 8)
Write-Host "Difference (ints): $(Get-Difference $ints1 $ints2 -join ', ')"
Coding Round
69. Group by property

Group objects by property using Group-Object or manual grouping.

  • Group-Object: $people | Group-Object Age
  • Manual: Group-ByProperty
  • Use case: Data aggregation
  • Time: O(n)
powershell
# Group by property
function Group-ByProperty {
    param($arr, $property)
    $groups = @{}
    foreach ($item in $arr) {
        $key = $item.$property
        if (-not $groups.ContainsKey($key)) {
            $groups[$key] = @()
        }
        $groups[$key] += $item
    }
    return $groups
}

# Example data
$people = @(
    [PSCustomObject]@{Name="Alice"; Age=25; City="NYC"}
    [PSCustomObject]@{Name="Bob"; Age=30; City="LA"}
    [PSCustomObject]@{Name="Charlie"; Age=25; City="NYC"}
    [PSCustomObject]@{Name="David"; Age=35; City="Chicago"}
    [PSCustomObject]@{Name="Eve"; Age=30; City="LA"}
)

Write-Host "Group by age:"
$byAge = Group-ByProperty $people "Age"
foreach ($age in $byAge.Keys) {
    $names = $byAge[$age].Name -join ', '
    Write-Host "Age $age: $names"
}

Write-Host "Group by city:"
$byCity = Group-ByProperty $people "City"
foreach ($city in $byCity.Keys) {
    $names = $byCity[$city].Name -join ', '
    Write-Host "City $city: $names"
}
Coding Round
70. Deep clone object

Create deep copies of objects using recursion to clone nested structures.

  • Method: Deep-Clone
  • Objects: PSCustomObject cloning
  • Arrays: Recursive copy
  • Hashtables: Key-value copy
powershell
# Deep clone object
function Deep-Clone {
    param($obj)
    if ($obj -is [array]) {
        $result = @()
        foreach ($item in $obj) {
            $result += Deep-Clone $item
        }
        return $result
    } elseif ($obj -is [hashtable]) {
        $result = @{}
        foreach ($key in $obj.Keys) {
            $result[$key] = Deep-Clone $obj[$key]
        }
        return $result
    } elseif ($obj -is [PSCustomObject]) {
        $result = [PSCustomObject]@{}
        foreach ($prop in $obj.PSObject.Properties) {
            $result | Add-Member -MemberType NoteProperty -Name $prop.Name -Value (Deep-Clone $prop.Value)
        }
        return $result
    } else {
        return $obj
    }
}

# Example
$address = [PSCustomObject]@{Street="123 Main St"; City="NYC"}
$person = [PSCustomObject]@{Name="Alice"; Address=$address}
$cloned = Deep-Clone $person

$cloned.Address.Street = "456 Oak St"
Write-Host "Original: $($person.Address.Street)"
Write-Host "Cloned: $($cloned.Address.Street)"
Coding Round
71. Immutable update

Perform immutable updates on nested data structures using path-based updates.

  • Method: Update-Immutable
  • Path: Dot notation
  • Recursive: Helper function
  • Use case: State management
powershell
# Immutable update
function Update-Immutable {
    param($obj, $path, $value)
    $parts = $path -split '.'
    if ($parts.Count -eq 1) {
        $result = $obj.Clone()
        $result[$parts[0]] = $value
        return $result
    }
    
    $first = $parts[0]
    $rest = $parts[1..($parts.Count - 1)] -join '.'
    $result = $obj.Clone()
    if ($result.ContainsKey($first)) {
        $result[$first] = Update-Immutable $result[$first] $rest $value
    } else {
        $result[$first] = Update-Immutable @{} $rest $value
    }
    return $result
}

$state = @{user = @{name = "Alice"; age = 25}}
$newState = Update-Immutable $state "user.age" 26

Write-Host "Original: $($state.user.age)"
Write-Host "Updated: $($newState.user.age)"
Coding Round
72. Pipe function

Implement pipe function for left-to-right function composition.

  • Method: Pipe
  • Implementation: foreach loop
  • Direction: Left to right
  • Use case: Function chaining
powershell
# Pipe function
function Pipe {
    param($value, [scriptblock[]]$functions)
    $result = $value
    foreach ($fn in $functions) {
        $result = & $fn $result
    }
    return $result
}

function Pipe-Operator {
    param($value, $functions)
    $result = $value
    foreach ($fn in $functions) {
        $result = & $fn $result
    }
    return $result
}

$double = { param($x) $x * 2 }
$addTen = { param($x) $x + 10 }
$square = { param($x) $x * $x }

$result = Pipe 5 $double, $addTen, $square
Write-Host "Pipe: $result"

# Using pipeline with functions
function Double { process { $_ * 2 } }
function AddTen { process { $_ + 10 } }
function Square { process { $_ * $_ } }

$result2 = 5 | Double | AddTen | Square
Write-Host "Pipeline: $result2"
Coding Round
73. Compose function

Implement compose function for right-to-left function composition.

  • Method: Compose
  • Implementation: Reverse order
  • Direction: Right to left
  • Use case: Function composition
powershell
# Compose function
function Compose {
    param([scriptblock[]]$functions)
    return {
        param($value)
        $result = $value
        foreach ($fn in ($functions | Sort-Object -Descending)) {
            $result = & $fn $result
        }
        return $result
    }
}

$double = { param($x) $x * 2 }
$addTen = { param($x) $x + 10 }
$square = { param($x) $x * $x }

$composed = Compose $double, $addTen, $square
$result = & $composed 5
Write-Host "Composed: $result"

# Alternative compose using filter
function Compose-Filter {
    param($functions)
    return {
        param($value)
        $result = $value
        foreach ($fn in ($functions | Sort-Object -Descending)) {
            $result = & $fn $result
        }
        return $result
    }
}

$composed2 = Compose-Filter $double, $addTen, $square
$result2 = & $composed2 5
Write-Host "Composed filter: $result2"
Coding Round
74. Memoization

Implement memoization to cache function results based on arguments.

  • Method: Memoize
  • Cache: hashtable
  • Limit: Memoize-WithLimit
  • Multiple args: Memoize-Multiple
powershell
# Memoization
function Memoize {
    param($fn)
    $cache = @{}
    return {
        param($arg)
        if (-not $cache.ContainsKey($arg)) {
            $cache[$arg] = & $fn $arg
        }
        return $cache[$arg]
    }
}

function Memoize-Multiple {
    param($fn)
    $cache = @{}
    return {
        param($args)
        $key = $args -join '|'
        if (-not $cache.ContainsKey($key)) {
            $cache[$key] = & $fn $args
        }
        return $cache[$key]
    }
}

function Memoize-WithLimit {
    param($fn, $limit)
    $cache = @{}
    $keys = @()
    return {
        param($arg)
        if (-not $cache.ContainsKey($arg)) {
            if ($keys.Count -ge $limit) {
                $oldest = $keys[0]
                $keys = $keys[1..($keys.Count - 1)]
                $cache.Remove($oldest)
            }
            $cache[$arg] = & $fn $arg
            $keys += $arg
        }
        return $cache[$arg]
    }
}

# Example: Fibonacci with memoization
$fib = Memoize {
    param($n)
    if ($n -le 1) { return $n }
    return (& $fib ($n - 1)) + (& $fib ($n - 2))
}

$start = Get-Date
Write-Host "Fibonacci(35): $( & $fib 35 )"
$time1 = (Get-Date) - $start
Write-Host "Time: $($time1.TotalSeconds)s"

$start2 = Get-Date
Write-Host "Fibonacci(35) again: $( & $fib 35 )"
$time2 = (Get-Date) - $start2
Write-Host "Time: $($time2.TotalSeconds)s"
Coding Round
75. Once function

Implement once function that ensures a function is called only once.

  • Method: Once
  • Flag: $called
  • Reset: Once-WithReset
  • Result: Cached result
powershell
# Once function
function Once {
    param($fn)
    $called = $false
    $result = $null
    return {
        param($args)
        if (-not $called) {
            $called = $true
            $result = & $fn $args
        }
        return $result
    }
}

function Once-WithReset {
    param($fn)
    $called = $false
    $result = $null
    $reset = {
        $called = $false
        $result = $null
    }
    
    $fnOnce = {
        param($args)
        if (-not $called) {
            $called = $true
            $result = & $fn $args
        }
        return $result
    }
    
    return @{
        Function = $fnOnce
        Reset = $reset
    }
}

$initialize = Once {
    param($value)
    Write-Host "Initialized with $value"
    return $value * 2
}

Write-Host "First call: $( & $initialize 10 )"
Write-Host "Second call: $( & $initialize 20 )"

$init = Once-WithReset {
    param($value)
    Write-Host "Initialized with $value"
    return $value * 2
}

Write-Host "First with reset: $( & $init.Function 10 )"
& $init.Reset
Write-Host "After reset: $( & $init.Function 20 )"
Coding Round
76. Debounce with leading edge

Implement debounce with leading edge execution using timers.

  • Method: Debounce-Leading
  • State: $lastCall
  • Timer: System.Timers.Timer
  • Use case: Rate limiting
powershell
# Debounce with leading edge
function Debounce-Leading {
    param($fn, $delay)
    $lastCall = 0
    $timeout = $null
    return {
        param($args)
        $now = (Get-Date).Ticks / 10000000.0
        if ($now - $lastCall -ge $delay) {
            $lastCall = $now
            return & $fn $args
        }
        
        if ($timeout -eq $null) {
            $timeout = @{
                Start = $now
                Args = $args
            }
            $timer = [System.Timers.Timer]::new(($delay - ($now - $lastCall)) * 1000)
            $timer.Add_Elapsed({
                $lastCall = (Get-Date).Ticks / 10000000.0
                & $fn $timeout.Args
                $timeout = $null
                $timer.Dispose()
            })
            $timer.Start()
        }
    }
}

function Debounce-LeadingSimple {
    param($fn, $delay)
    $lastCall = 0
    return {
        param($args)
        $now = (Get-Date).Ticks / 10000000.0
        if ($now - $lastCall -ge $delay) {
            $lastCall = $now
            return & $fn $args
        }
        return $null
    }
}

$debounced = Debounce-LeadingSimple {
    param($value)
    Write-Host "Processing: $value"
} 2

Write-Host "Call 1: $( & $debounced 1 )"
Write-Host "Call 2: $( & $debounced 2 )"
Start-Sleep -Seconds 3
Write-Host "Call 3: $( & $debounced 3 )"
Coding Round
77. Throttle with leading edge

Implement throttle with leading edge execution based on time since last call.

  • Method: Throttle-Leading
  • State: $lastCall
  • Skipped: Track skipped calls
  • Trailing: Throttle-WithTrailing
powershell
# Throttle with leading edge
function Throttle-Leading {
    param($fn, $delay)
    $lastCall = 0
    return {
        param($args)
        $now = (Get-Date).Ticks / 10000000.0
        if ($now - $lastCall -ge $delay) {
            $lastCall = $now
            return & $fn $args
        }
        return $null
    }
}

function Throttle-LeadingWithSkipped {
    param($fn, $delay)
    $lastCall = 0
    $skipped = 0
    return {
        param($args)
        $now = (Get-Date).Ticks / 10000000.0
        if ($now - $lastCall -ge $delay) {
            if ($skipped -gt 0) {
                Write-Host "Skipped $skipped calls"
                $skipped = 0
            }
            $lastCall = $now
            return & $fn $args
        }
        $skipped++
        return $null
    }
}

function Throttle-WithTrailing {
    param($fn, $delay)
    $lastCall = 0
    $pending = $null
    $timer = $null
    
    return {
        param($args)
        $now = (Get-Date).Ticks / 10000000.0
        if ($now - $lastCall -ge $delay) {
            $lastCall = $now
            return & $fn $args
        }
        
        $pending = $args
        if ($timer -eq $null) {
            $remaining = $delay - ($now - $lastCall)
            $timer = [System.Timers.Timer]::new($remaining * 1000)
            $timer.Add_Elapsed({
                $lastCall = (Get-Date).Ticks / 10000000.0
                if ($pending -ne $null) {
                    & $fn $pending
                    $pending = $null
                }
                $timer.Dispose()
                $timer = $null
            })
            $timer.Start()
        }
    }
}

$throttled = Throttle-Leading {
    param($value)
    Write-Host "Processing: $value"
} 2

Write-Host "Call 1: $( & $throttled 1 )"
Write-Host "Call 2: $( & $throttled 2 )"
Start-Sleep -Seconds 3
Write-Host "Call 3: $( & $throttled 3 )"
Coding Round
78. Deep equal

Implement deep equality comparison for nested structures.

  • Method: Deep-Equal
  • Primitive: -eq
  • Arrays: Recursive compare
  • Objects: Compare properties
powershell
# Deep equal
function Deep-Equal {
    param($obj1, $obj2)
    if ($obj1 -eq $obj2) {
        return $true
    }
    
    if ($obj1.GetType() -ne $obj2.GetType()) {
        return $false
    }
    
    if ($obj1 -is [array] -and $obj2 -is [array]) {
        if ($obj1.Count -ne $obj2.Count) {
            return $false
        }
        for ($i = 0; $i -lt $obj1.Count; $i++) {
            if (-not (Deep-Equal $obj1[$i] $obj2[$i])) {
                return $false
            }
        }
        return $true
    }
    
    if ($obj1 -is [hashtable] -and $obj2 -is [hashtable]) {
        if ($obj1.Count -ne $obj2.Count) {
            return $false
        }
        foreach ($key in $obj1.Keys) {
            if (-not $obj2.ContainsKey($key)) {
                return $false
            }
            if (-not (Deep-Equal $obj1[$key] $obj2[$key])) {
                return $false
            }
        }
        return $true
    }
    
    if ($obj1 -is [PSCustomObject] -and $obj2 -is [PSCustomObject]) {
        $props1 = $obj1.PSObject.Properties
        $props2 = $obj2.PSObject.Properties
        if ($props1.Count -ne $props2.Count) {
            return $false
        }
        foreach ($prop in $props1) {
            if (-not ($obj2 | Get-Member -Name $prop.Name)) {
                return $false
            }
            if (-not (Deep-Equal $prop.Value $obj2.$($prop.Name))) {
                return $false
            }
        }
        return $true
    }
    
    return $obj1 -eq $obj2
}

$obj1 = @{a = 1; b = @{c = 2}}
$obj2 = @{a = 1; b = @{c = 2}}
$obj3 = @{a = 1; b = @{c = 3}}

Write-Host "obj1 == obj2: $(Deep-Equal $obj1 $obj2)"
Write-Host "obj1 == obj3: $(Deep-Equal $obj1 $obj3)"
Coding Round
79. Observable pattern

Implement observable pattern with subscription and notification.

  • Observable: Observable class
  • Subscribe: Subscribe method
  • Notify: Notify method
  • Stateful: StatefulObservable
powershell
# Observable pattern
class Observable {
    [hashtable]$Subscribers
    
    Observable() {
        $this.Subscribers = @{}
    }
    
    [string] Subscribe([scriptblock]$callback) {
        $id = [guid]::NewGuid().ToString()
        $this.Subscribers[$id] = $callback
        return $id
    }
    
    [void] Unsubscribe([string]$id) {
        $this.Subscribers.Remove($id)
    }
    
    [void] Notify($data) {
        foreach ($callback in $this.Subscribers.Values) {
            & $callback $data
        }
    }
    
    [void] Clear() {
        $this.Subscribers.Clear()
    }
}

class StatefulObservable : Observable {
    [object]$State
    
    StatefulObservable($initialState) : base() {
        $this.State = $initialState
    }
    
    [void] SetState($newState) {
        $this.State = $newState
        $this.Notify($newState)
    }
    
    [object] GetState() {
        return $this.State
    }
}

$observable = [Observable]::new()
$id1 = $observable.Subscribe({ param($data) Write-Host "Observer1: $data" })
$id2 = $observable.Subscribe({ param($data) Write-Host "Observer2: $data" })

Write-Host "Notifying observers:"
$observable.Notify("Hello, World!")

$observable.Unsubscribe($id1)
Write-Host "After unsubscribing observer1:"
$observable.Notify("Hello again!")

$stateful = [StatefulObservable]::new(0)
$stateful.Subscribe({ param($state) Write-Host "State changed to: $state" })
Write-Host "Current state: $($stateful.GetState())"
$stateful.SetState(10)
$stateful.SetState(20)
Coding Round
80. Singleton pattern

Implement singleton pattern to ensure only one instance exists.

  • Class: Singleton class
  • Instance: static $Instance
  • Private: Constructor
  • Closure: New-Singleton
powershell
# Singleton pattern
class Singleton {
    static [Singleton]$Instance = $null
    
    [hashtable]$Data = @{}
    
    Singleton() {}
    
    static [Singleton] GetInstance() {
        if ($null -eq [Singleton]::Instance) {
            [Singleton]::Instance = [Singleton]::new()
        }
        return [Singleton]::Instance
    }
    
    [void] Set([string]$key, $value) {
        $this.Data[$key] = $value
    }
    
    $Get([string]$key) {
        return $this.Data[$key] ?? $null
    }
}

# Alternative singleton using script block
function New-Singleton {
    param($init)
    $instance = $null
    return {
        if ($instance -eq $null) {
            Write-Host "Initializing singleton"
            $instance = & $init
        }
        return $instance
    }
}

$getConfig = New-Singleton {
    return @{Name = "App"; Version = 1.0}
}

$config1 = & $getConfig
$config2 = & $getConfig

Write-Host "config1 == config2: $($config1 -eq $config2)"
Write-Host "config1 name: $($config1.Name)"

$singleton1 = [Singleton]::GetInstance()
$singleton2 = [Singleton]::GetInstance()
Write-Host "singleton1 == singleton2: $($singleton1 -eq $singleton2)"

$singleton1.Set("key", "value")
Write-Host "singleton2 get: $($singleton2.Get("key"))"
Coding Round
81. Factory pattern

Implement factory pattern for creating objects without specifying concrete classes.

  • Factory: UserFactory
  • Create: Create method
  • Specific: CreateAdmin, CreateGuest
  • Type: Switch on type
powershell
# Factory pattern
class User {
    [string]$Name
    [string]$Type
    
    User([string]$name, [string]$type) {
        $this.Name = $name
        $this.Type = $type
    }
}

class Admin : User {
    Admin([string]$name) : base($name, "admin") {}
}

class Guest : User {
    Guest([string]$name) : base($name, "guest") {}
}

class RegularUser : User {
    RegularUser([string]$name) : base($name, "regular") {}
}

class UserFactory {
    static [User] Create([string]$type, [string]$name) {
        switch ($type) {
            "admin" { return [Admin]::new($name) }
            "guest" { return [Guest]::new($name) }
            default { return [RegularUser]::new($name) }
        }
    }
    
    static [Admin] CreateAdmin([string]$name) {
        return [Admin]::new($name)
    }
    
    static [Guest] CreateGuest([string]$name) {
        return [Guest]::new($name)
    }
    
    static [RegularUser] CreateRegular([string]$name) {
        return [RegularUser]::new($name)
    }
}

$user1 = [UserFactory]::Create("admin", "Alice")
$user2 = [UserFactory]::Create("guest", "Bob")
$user3 = [UserFactory]::Create("regular", "Charlie")

Write-Host "$($user1.Name) is $($user1.Type)"
Write-Host "$($user2.Name) is $($user2.Type)"
Write-Host "$($user3.Name) is $($user3.Type)"
Coding Round
82. Strategy pattern

Implement strategy pattern with interchangeable payment methods.

  • Strategy: PaymentStrategy
  • Context: PaymentContext
  • Execute: ExecutePayment
  • Decorator: DiscountDecorator
powershell
# Strategy pattern
class PaymentStrategy {
    [string]$Name
    PaymentStrategy([string]$name) { $this.Name = $name }
    virtual [void] Pay([double]$amount) {
        Write-Host "Paid $amount with $($this.Name)"
    }
}

class CreditCardStrategy : PaymentStrategy {
    CreditCardStrategy() : base("Credit Card") {}
}

class PayPalStrategy : PaymentStrategy {
    PayPalStrategy() : base("PayPal") {}
}

class CryptoStrategy : PaymentStrategy {
    CryptoStrategy() : base("Crypto") {}
}

class PaymentContext {
    [PaymentStrategy]$Strategy
    
    PaymentContext([PaymentStrategy]$strategy) {
        $this.Strategy = $strategy
    }
    
    [void] SetStrategy([PaymentStrategy]$strategy) {
        $this.Strategy = $strategy
    }
    
    [void] ExecutePayment([double]$amount) {
        $this.Strategy.Pay($amount)
    }
}

# Usage
$context = [PaymentContext]::new([CreditCardStrategy]::new())
$context.ExecutePayment(100.0)
$context.SetStrategy([PayPalStrategy]::new())
$context.ExecutePayment(50.0)
$context.SetStrategy([CryptoStrategy]::new())
$context.ExecutePayment(75.0)

# With discount decorator
class DiscountDecorator : PaymentStrategy {
    [PaymentStrategy]$InnerStrategy
    [double]$Discount
    
    DiscountDecorator([PaymentStrategy]$strategy, [double]$discount) : base("") {
        $this.InnerStrategy = $strategy
        $this.Discount = $discount
    }
    
    [void] Pay([double]$amount) {
        $discounted = $amount * (1 - $this.Discount)
        Write-Host "Applied discount of $($this.Discount * 100)%"
        $this.InnerStrategy.Pay($discounted)
    }
}

$discounted = [DiscountDecorator]::new([PayPalStrategy]::new(), 0.1)
$discounted.Pay(100.0)
Coding Round
83. Observer pattern

Implement observer pattern with subject and observer classes.

  • Subject: ConcreteSubject
  • Observer: Observer
  • Attach: Attach method
  • Notify: SetState method
powershell
# Observer pattern
class Observer {
    [string]$Name
    
    Observer([string]$name) {
        $this.Name = $name
    }
    
    [void] Update($data) {
        Write-Host "Observer $($this.Name) received: $data"
    }
}

class Subject {
    [hashtable]$Observers = @{}
    
    [void] Attach([Observer]$observer) {
        $id = [guid]::NewGuid().ToString()
        $this.Observers[$id] = $observer
    }
    
    [void] Detach([Observer]$observer) {
        $keys = $this.Observers.Keys
        foreach ($key in $keys) {
            if ($this.Observers[$key] -eq $observer) {
                $this.Observers.Remove($key)
                break
            }
        }
    }
    
    [void] Notify($data) {
        foreach ($observer in $this.Observers.Values) {
            $observer.Update($data)
        }
    }
}

class ConcreteSubject : Subject {
    $State
    
    [void] SetState($state) {
        $this.State = $state
        $this.Notify($state)
    }
    
    $GetState() {
        return $this.State
    }
}

class DerivedObserver : Observer {
    [scriptblock]$Transform
    
    DerivedObserver([string]$name, [scriptblock]$transform) : base($name) {
        $this.Transform = $transform
    }
    
    [void] Update($data) {
        $transformed = & $this.Transform $data
        Write-Host "Derived observer $($this.Name): $transformed"
    }
}

# Usage
$subject = [ConcreteSubject]::new()
$observer1 = [Observer]::new("1")
$observer2 = [Observer]::new("2")
$observer3 = [DerivedObserver]::new("3", { param($data) $data.ToUpper() })

$subject.Attach($observer1)
$subject.Attach($observer2)
$subject.Attach($observer3)

Write-Host "Setting state:"
$subject.SetState("Hello, World!")
$subject.SetState("Another update")

$subject.Detach($observer1)
Write-Host "After detaching observer1:"
$subject.SetState("Final state")
Coding Round
84. Decorator pattern

Implement decorator pattern for adding features to coffee.

  • Component: BasicCoffee
  • Decorator: CoffeeDecorator
  • Additions: MilkDecorator, SugarDecorator
  • Chaining: Nested decorators
powershell
# Decorator pattern
class Coffee {
    virtual [double] GetCost() { return 0.0 }
    virtual [string] GetDescription() { return "" }
}

class BasicCoffee : Coffee {
    [double] GetCost() { return 5.0 }
    [string] GetDescription() { return "Coffee" }
}

class CoffeeDecorator : Coffee {
    [Coffee]$InnerCoffee
    
    CoffeeDecorator([Coffee]$coffee) {
        $this.InnerCoffee = $coffee
    }
    
    [double] GetCost() { return $this.InnerCoffee.GetCost() }
    [string] GetDescription() { return $this.InnerCoffee.GetDescription() }
}

class MilkDecorator : CoffeeDecorator {
    MilkDecorator([Coffee]$coffee) : base($coffee) {}
    
    [double] GetCost() {
        return $this.InnerCoffee.GetCost() + 2.0
    }
    
    [string] GetDescription() {
        return $this.InnerCoffee.GetDescription() + ", Milk"
    }
}

class SugarDecorator : CoffeeDecorator {
    SugarDecorator([Coffee]$coffee) : base($coffee) {}
    
    [double] GetCost() {
        return $this.InnerCoffee.GetCost() + 1.0
    }
    
    [string] GetDescription() {
        return $this.InnerCoffee.GetDescription() + ", Sugar"
    }
}

class CaramelDecorator : CoffeeDecorator {
    CaramelDecorator([Coffee]$coffee) : base($coffee) {}
    
    [double] GetCost() {
        return $this.InnerCoffee.GetCost() + 2.5
    }
    
    [string] GetDescription() {
        return $this.InnerCoffee.GetDescription() + ", Caramel"
    }
}

class WhippedCreamDecorator : CoffeeDecorator {
    WhippedCreamDecorator([Coffee]$coffee) : base($coffee) {}
    
    [double] GetCost() {
        return $this.InnerCoffee.GetCost() + 1.5
    }
    
    [string] GetDescription() {
        return $this.InnerCoffee.GetDescription() + ", Whipped Cream"
    }
}

# Usage
$coffee = [BasicCoffee]::new()
Write-Host "$($coffee.GetDescription()) (`$$($coffee.GetCost())`)"

$withMilk = [MilkDecorator]::new($coffee)
Write-Host "$($withMilk.GetDescription()) (`$$($withMilk.GetCost())`)"

$withSugar = [SugarDecorator]::new($coffee)
Write-Host "$($withSugar.GetDescription()) (`$$($withSugar.GetCost())`)"

$withMilkSugar = [SugarDecorator]::new([MilkDecorator]::new($coffee))
Write-Host "$($withMilkSugar.GetDescription()) (`$$($withMilkSugar.GetCost())`)"

$fullyDecorated = [CaramelDecorator]::new(
    [WhippedCreamDecorator]::new(
        [SugarDecorator]::new(
            [MilkDecorator]::new($coffee)
        )
    )
)
Write-Host "$($fullyDecorated.GetDescription()) (`$$($fullyDecorated.GetCost())`)"
Coding Round
85. Command pattern

Implement command pattern with execute, undo, and redo operations.

  • Command: AddCommand, SubtractCommand
  • History: CommandHistory
  • Macro: MacroCommand
  • Operations: Execute, Undo, Redo
powershell
# Command pattern
class Command {
    virtual [void] Execute() {}
    virtual [void] Undo() {}
    virtual [void] Redo() {}
}

class AddCommand : Command {
    [ref]$Receiver
    [int]$Value
    
    AddCommand([ref]$receiver, [int]$value) {
        $this.Receiver = $receiver
        $this.Value = $value
    }
    
    [void] Execute() {
        $this.Receiver.Value += $this.Value
    }
    
    [void] Undo() {
        $this.Receiver.Value -= $this.Value
    }
    
    [void] Redo() {
        $this.Execute()
    }
}

class SubtractCommand : Command {
    [ref]$Receiver
    [int]$Value
    
    SubtractCommand([ref]$receiver, [int]$value) {
        $this.Receiver = $receiver
        $this.Value = $value
    }
    
    [void] Execute() {
        $this.Receiver.Value -= $this.Value
    }
    
    [void] Undo() {
        $this.Receiver.Value += $this.Value
    }
    
    [void] Redo() {
        $this.Execute()
    }
}

class MacroCommand : Command {
    [Command[]]$Commands
    
    MacroCommand([Command[]]$commands) {
        $this.Commands = $commands
    }
    
    [void] Execute() {
        foreach ($cmd in $this.Commands) {
            $cmd.Execute()
        }
    }
    
    [void] Undo() {
        for ($i = $this.Commands.Count - 1; $i -ge 0; $i--) {
            $this.Commands[$i].Undo()
        }
    }
    
    [void] Redo() {
        $this.Execute()
    }
}

class CommandHistory {
    [System.Collections.ArrayList]$History = @()
    [int]$Current = 0
    
    [void] Execute([Command]$command) {
        $command.Execute()
        $this.History = $this.History[0..($this.Current - 1)]
        $this.History.Add($command)
        $this.Current++
    }
    
    [bool] Undo() {
        if ($this.Current -gt 0) {
            $this.Current--
            $this.History[$this.Current].Undo()
            return $true
        }
        return $false
    }
    
    [bool] Redo() {
        if ($this.Current -lt $this.History.Count) {
            $this.History[$this.Current].Redo()
            $this.Current++
            return $true
        }
        return $false
    }
}

# Usage
$counter = 0
$history = [CommandHistory]::new()

$add5 = [AddCommand]::new([ref]$counter, 5)
$sub3 = [SubtractCommand]::new([ref]$counter, 3)

Write-Host "Initial: $counter"
$history.Execute($add5)
Write-Host "After add: $counter"
$history.Execute($sub3)
Write-Host "After sub: $counter"
$history.Undo()
Write-Host "After undo: $counter"
$history.Redo()
Write-Host "After redo: $counter"

$macro = [MacroCommand]::new(@($add5, $add5, $sub3))
$history.Execute($macro)
Write-Host "After macro: $counter"
Coding Round
86. Memento pattern

Implement memento pattern for state capture and restoration.

  • Originator: Originator
  • Memento: Memento
  • Caretaker: Caretaker
  • Undo/Redo: Undo, Redo
powershell
# Memento pattern
class Memento {
    $State
    
    Memento($state) {
        $this.State = $state
    }
    
    $GetState() {
        return $this.State
    }
}

class Originator {
    $State
    
    Originator($state) {
        $this.State = $state
    }
    
    [Memento] Save() {
        return [Memento]::new($this.State)
    }
    
    [void] Restore([Memento]$memento) {
        $this.State = $memento.GetState()
    }
    
    [void] SetState($state) {
        $this.State = $state
    }
    
    $GetState() {
        return $this.State
    }
}

class Caretaker {
    [System.Collections.ArrayList]$Mementos = @()
    [int]$Current = 0
    
    [void] Save([Memento]$memento) {
        $this.Mementos = $this.Mementos[0..($this.Current - 1)]
        $this.Mementos.Add($memento)
        $this.Current++
    }
    
    [Memento] Undo() {
        if ($this.Current -gt 0) {
            $this.Current--
            return $this.Mementos[$this.Current]
        }
        return $null
    }
    
    [Memento] Redo() {
        if ($this.Current -lt $this.Mementos.Count) {
            $memento = $this.Mementos[$this.Current]
            $this.Current++
            return $memento
        }
        return $null
    }
}

# Usage
$originator = [Originator]::new(@{value = 0})
$caretaker = [Caretaker]::new()

$caretaker.Save($originator.Save())
$originator.SetState(@{value = 1})
$caretaker.Save($originator.Save())
$originator.SetState(@{value = 2})
$caretaker.Save($originator.Save())
$originator.SetState(@{value = 3})

Write-Host "Current: $($originator.GetState().value)"

$memento = $caretaker.Undo()
if ($memento) {
    $originator.Restore($memento)
    Write-Host "After undo: $($originator.GetState().value)"
}

$memento = $caretaker.Redo()
if ($memento) {
    $originator.Restore($memento)
    Write-Host "After redo: $($originator.GetState().value)"
}
Coding Round
87. Mediator pattern

Implement mediator pattern for centralized communication between colleagues.

  • Mediator: Mediator
  • Colleague: Colleague
  • Send: Send method
  • Register: Register method
powershell
# Mediator pattern
class Mediator {
    [System.Collections.ArrayList]$Colleagues = @()
    
    [void] Register([Colleague]$colleague) {
        $this.Colleagues.Add($colleague)
        $colleague.SetMediator($this)
    }
    
    [void] Send([string]$message, [Colleague]$sender) {
        foreach ($colleague in $this.Colleagues) {
            if ($colleague -ne $sender) {
                $colleague.Receive($message)
            }
        }
    }
}

class Colleague {
    [string]$Name
    [Mediator]$Mediator
    
    Colleague([string]$name) {
        $this.Name = $name
    }
    
    [void] SetMediator([Mediator]$mediator) {
        $this.Mediator = $mediator
    }
    
    [void] Send([string]$message) {
        $this.Mediator.Send($message, $this)
    }
    
    [void] Receive([string]$message) {
        Write-Host "$($this.Name) received: $message"
    }
}

class StatefulColleague : Colleague {
    $State
    
    StatefulColleague([string]$name, $state) : base($name) {
        $this.State = $state
    }
    
    [void] Receive([string]$message) {
        Write-Host "$($this.Name) (state $($this.State)) received: $message"
    }
    
    [void] SetState($state) {
        $this.State = $state
    }
}

# Usage
$mediator = [Mediator]::new()
$alice = [Colleague]::new("Alice")
$bob = [Colleague]::new("Bob")
$charlie = [Colleague]::new("Charlie")

$mediator.Register($alice)
$mediator.Register($bob)
$mediator.Register($charlie)

Write-Host "Sending messages:"
$alice.Send("Hello everyone!")
$bob.Send("Meeting at 3pm")

$mediator2 = [Mediator]::new()
$alice2 = [StatefulColleague]::new("Alice", 0)
$bob2 = [StatefulColleague]::new("Bob", 1)

$mediator2.Register($alice2)
$mediator2.Register($bob2)
$alice2.Send("Custom message for stateful colleagues")
Coding Round
88. Chain of Responsibility

Implement chain of responsibility with linked handlers.

  • Handler: Handler class
  • Chain: SetNext method
  • Processing: Handle method
  • Concrete: AuthHandler, LoggerHandler
powershell
# Chain of Responsibility
class Handler {
    [Handler]$Next = $null
    
    [Handler] SetNext([Handler]$handler) {
        $this.Next = $handler
        return $handler
    }
    
    virtual [bool] Handle($request) {
        if ($this.Next) {
            return $this.Next.Handle($request)
        }
        return $true
    }
}

class AuthHandler : Handler {
    [bool] Handle($request) {
        if ($request.ContainsKey("token")) {
            Write-Host "Authentication passed"
            return $this.Next.Handle($request)
        }
        Write-Host "Authentication failed"
        return $false
    }
}

class LoggerHandler : Handler {
    [bool] Handle($request) {
        $url = $request["url"] ?? "unknown"
        Write-Host "Logging request: $url"
        return $this.Next.Handle($request)
    }
}

class ValidationHandler : Handler {
    [bool] Handle($request) {
        if ($request.ContainsKey("data")) {
            Write-Host "Validation passed"
            return $this.Next.Handle($request)
        }
        Write-Host "Validation failed"
        return $false
    }
}

class RateLimitHandler : Handler {
    $LastCall = 0
    $Limit = 5
    
    [bool] Handle($request) {
        $now = [DateTime]::UtcNow.Ticks / 10000000.0
        if ($now - $this.LastCall -ge $this.Limit) {
            $this.LastCall = $now
            Write-Host "Rate limit passed"
            return $this.Next.Handle($request)
        }
        Write-Host "Rate limit exceeded"
        return $false
    }
}

# Usage
$auth = [AuthHandler]::new()
$logger = [LoggerHandler]::new()
$validator = [ValidationHandler]::new()
$rateLimiter = [RateLimitHandler]::new()

$auth.SetNext($logger).SetNext($validator).SetNext($rateLimiter)

$request = @{
    token = "valid"
    url = "/api"
    data = "payload"
}
Write-Host "Processing valid request:"
$auth.Handle($request)

$request2 = @{
    url = "/public"
}
Write-Host "Processing invalid request:"
$auth.Handle($request2)
Coding Round
89. State pattern

Implement state pattern with context and state transitions.

  • State: State class
  • Context: Context
  • Transitions: Handle method
  • Data: StatefulContext
powershell
# State pattern
class State {
    virtual [void] Handle([Context]$context) {}
}

class ReadyState : State {
    [void] Handle([Context]$context) {
        Write-Host "Ready: Waiting for input"
        $context.SetState([ProcessingState]::new())
    }
}

class ProcessingState : State {
    [void] Handle([Context]$context) {
        Write-Host "Processing: Working on task"
        $context.SetState([CompletedState]::new())
    }
}

class CompletedState : State {
    [void] Handle([Context]$context) {
        Write-Host "Completed: Task finished"
        $context.SetState([ReadyState]::new())
    }
}

class ErrorState : State {
    [void] Handle([Context]$context) {
        Write-Host "Error: Something went wrong"
        $context.SetState([ReadyState]::new())
    }
}

class Context {
    [State]$State
    [hashtable]$Data = @{}
    
    Context([State]$state) {
        $this.State = $state
    }
    
    [void] SetState([State]$state) {
        $this.State = $state
    }
    
    [void] Request() {
        $this.State.Handle($this)
    }
    
    [void] SetData($key, $value) {
        $this.Data[$key] = $value
    }
    
    $GetData($key) {
        return $this.Data[$key] ?? $null
    }
}

class StatefulContext : Context {
    [void] Request() {
        $this.State.Handle($this)
        $this.SetData("last_state", $this.State.GetType().Name)
    }
}

# Usage
$context = [Context]::new([ReadyState]::new())
for ($i = 0; $i -lt 5; $i++) {
    Write-Host "Step $($i + 1): " -NoNewline
    $context.Request()
}

Write-Host "With data:"
$context2 = [StatefulContext]::new([ReadyState]::new())
for ($i = 0; $i -lt 5; $i++) {
    $context2.SetData("step", $i + 1)
    $context2.Request()
    Write-Host "Data: $($context2.GetData("last_state"))"
}
Coding Round
90. Proxy pattern

Implement proxy pattern for access control and lazy initialization.

  • Subject: RealSubject
  • Proxy: Proxy
  • Logging: LoggingProxy
  • Auth: AuthProxy
powershell
# Proxy pattern
class RealSubject {
    [string] Request() {
        return "RealSubject: Handling request"
    }
}

class Proxy {
    [RealSubject]$RealSubject = $null
    
    [string] Request() {
        if ($this.RealSubject -eq $null) {
            Write-Host "Proxy: Creating real subject"
            $this.RealSubject = [RealSubject]::new()
        }
        Write-Host "Proxy: Using cached real subject"
        return $this.RealSubject.Request()
    }
}

class LoggingProxy {
    [RealSubject]$Subject
    
    LoggingProxy([RealSubject]$subject) {
        $this.Subject = $subject
    }
    
    [string] Request() {
        Write-Host "Logging: Request started"
        $result = $this.Subject.Request()
        Write-Host "Logging: Request completed"
        return $result
    }
}

class AuthProxy {
    [RealSubject]$Subject
    [string]$User
    
    AuthProxy([RealSubject]$subject, [string]$user) {
        $this.Subject = $subject
        $this.User = $user
    }
    
    [string] Request() {
        if ($this.Authenticate()) {
            Write-Host "Auth: Access granted"
            return $this.Subject.Request()
        }
        Write-Host "Auth: Access denied"
        return "Unauthorized"
    }
    
    [bool] Authenticate() {
        return $this.User -eq "admin"
    }
}

# Usage
$proxy = [Proxy]::new()
Write-Host $proxy.Request()
Write-Host $proxy.Request()

$real = [RealSubject]::new()
$loggingProxy = [LoggingProxy]::new($real)
Write-Host $loggingProxy.Request()

$authProxy = [AuthProxy]::new($real, "admin")
Write-Host $authProxy.Request()

$authProxy2 = [AuthProxy]::new($real, "guest")
Write-Host $authProxy2.Request()
Coding Round
91. Flyweight pattern

Implement flyweight pattern for sharing objects to save memory.

  • Flyweight: Flyweight
  • Factory: FlyweightFactory
  • Get: GetFlyweight
  • Operation: Operation
powershell
# Flyweight pattern
class Flyweight {
    [string]$SharedState
    
    Flyweight([string]$sharedState) {
        $this.SharedState = $sharedState
    }
    
    [string] Operation([string]$uniqueState) {
        return "Shared: $($this.SharedState), Unique: $uniqueState"
    }
}

class FlyweightFactory {
    [hashtable]$Flyweights = @{}
    
    [Flyweight] GetFlyweight([string]$sharedState) {
        if (-not $this.Flyweights.ContainsKey($sharedState)) {
            $this.Flyweights[$sharedState] = [Flyweight]::new($sharedState)
        }
        return $this.Flyweights[$sharedState]
    }
    
    [int] GetCount() {
        return $this.Flyweights.Count
    }
}

# Usage
$factory = [FlyweightFactory]::new()
$fw1 = $factory.GetFlyweight("state1")
$fw2 = $factory.GetFlyweight("state1")
$fw3 = $factory.GetFlyweight("state2")

Write-Host "fw1 and fw2 are same: $($fw1 -eq $fw2)"
Write-Host "fw1 and fw3 are same: $($fw1 -eq $fw3)"

Write-Host $fw1.Operation("unique1")
Write-Host $fw2.Operation("unique2")
Write-Host $fw3.Operation("unique3")

Write-Host "Number of flyweights: $($factory.GetCount())"
Coding Round
92. Bridge pattern

Implement bridge pattern for separating abstraction from implementation.

  • Implementation: ConcreteImplementationA
  • Abstraction: ExtendedAbstraction
  • Alternative: AlternativeAbstraction
  • Operation: Operation
powershell
# Bridge pattern
class Implementation {
    virtual [string] Operation() { return "" }
}

class ConcreteImplementationA : Implementation {
    [string] Operation() {
        return "ConcreteImplementationA: Operation"
    }
}

class ConcreteImplementationB : Implementation {
    [string] Operation() {
        return "ConcreteImplementationB: Operation"
    }
}

class Abstraction {
    [Implementation]$Implementation
    
    Abstraction([Implementation]$implementation) {
        $this.Implementation = $implementation
    }
    
    virtual [string] Operation() {
        return $this.Implementation.Operation()
    }
}

class ExtendedAbstraction : Abstraction {
    ExtendedAbstraction([Implementation]$implementation) : base($implementation) {}
    
    [string] Operation() {
        return "ExtendedAbstraction: $($this.Implementation.Operation())"
    }
}

class AlternativeAbstraction : Abstraction {
    AlternativeAbstraction([Implementation]$implementation) : base($implementation) {}
    
    [string] Operation() {
        return "AlternativeAbstraction: $($this.Implementation.Operation())"
    }
}

# Usage
$implA = [ConcreteImplementationA]::new()
$implB = [ConcreteImplementationB]::new()

$abstraction1 = [ExtendedAbstraction]::new($implA)
$abstraction2 = [ExtendedAbstraction]::new($implB)
$abstraction3 = [AlternativeAbstraction]::new($implA)

Write-Host $abstraction1.Operation()
Write-Host $abstraction2.Operation()
Write-Host $abstraction3.Operation()
Coding Round
93. Adapter pattern

Implement adapter pattern for converting interfaces.

  • Target: Target
  • Adaptee: Adaptee
  • Adapter: Adapter
  • Logging: LoggingAdapter
powershell
# Adapter pattern
class Target {
    [string] Request() {
        return "Target: Request"
    }
}

class Adaptee {
    [string] SpecificRequest() {
        return "Adaptee: Specific Request"
    }
}

class Adapter : Target {
    [Adaptee]$Adaptee
    
    Adapter([Adaptee]$adaptee) {
        $this.Adaptee = $adaptee
    }
    
    [string] Request() {
        return $this.Adaptee.SpecificRequest()
    }
}

class LoggingAdapter : Adapter {
    LoggingAdapter([Adaptee]$adaptee) : base($adaptee) {}
    
    [string] Request() {
        Write-Host "Adapter: Logging request"
        return $this.Adaptee.SpecificRequest()
    }
}

# Usage
$target = [Target]::new()
$adaptee = [Adaptee]::new()
$adapter = [Adapter]::new($adaptee)

Write-Host $target.Request()
Write-Host $adapter.Request()

$loggingAdapter = [LoggingAdapter]::new($adaptee)
Write-Host $loggingAdapter.Request()
Coding Round
94. Facade pattern

Implement facade pattern for simplifying complex subsystems.

  • Subsystems: SubsystemA, SubsystemB
  • Facade: Facade
  • Operations: SimpleOperation, ComplexOperation
  • Interface: Simplified API
powershell
# Facade pattern
class SubsystemA {
    [string] OperationA() {
        return "SubsystemA: Operation"
    }
}

class SubsystemB {
    [string] OperationB() {
        return "SubsystemB: Operation"
    }
}

class SubsystemC {
    [string] OperationC() {
        return "SubsystemC: Operation"
    }
}

class Facade {
    [SubsystemA]$SubsystemA
    [SubsystemB]$SubsystemB
    [SubsystemC]$SubsystemC
    
    Facade() {
        $this.SubsystemA = [SubsystemA]::new()
        $this.SubsystemB = [SubsystemB]::new()
        $this.SubsystemC = [SubsystemC]::new()
    }
    
    [string] SimpleOperation() {
        return $this.SubsystemA.OperationA()
    }
    
    [string] ComplexOperation() {
        return "$($this.SubsystemA.OperationA())`n$($this.SubsystemB.OperationB())`n$($this.SubsystemC.OperationC())"
    }
}

# Usage
$facade = [Facade]::new()
Write-Host "Simple operation:`n$($facade.SimpleOperation())"
Write-Host "Complex operation:`n$($facade.ComplexOperation())"
Coding Round
95. Composite pattern

Implement composite pattern for tree structures.

  • Component: Component
  • Leaf: Leaf
  • Composite: Composite
  • Operation: Operation
powershell
# Composite pattern
class Component {
    [string]$Name
    
    Component([string]$name) {
        $this.Name = $name
    }
    
    virtual [string] Operation() { return "" }
    virtual [void] Add([Component]$component) { throw "Cannot add to leaf" }
    virtual [void] Remove([Component]$component) { throw "Cannot remove from leaf" }
    virtual [array] GetChildren() { return @() }
}

class Leaf : Component {
    Leaf([string]$name) : base($name) {}
    
    [string] Operation() {
        return "Leaf $($this.Name): Operation"
    }
}

class Composite : Component {
    [System.Collections.ArrayList]$Children = @()
    
    Composite([string]$name) : base($name) {}
    
    [string] Operation() {
        $result = "Composite $($this.Name): Operation`n"
        foreach ($child in $this.Children) {
            $result += "$($child.Operation())`n"
        }
        return $result
    }
    
    [void] Add([Component]$component) {
        $this.Children.Add($component)
    }
    
    [void] Remove([Component]$component) {
        $this.Children.Remove($component)
    }
    
    [array] GetChildren() {
        return $this.Children
    }
    
    [int] CountLeaves() {
        $count = 0
        foreach ($child in $this.Children) {
            if ($child -is [Leaf]) {
                $count++
            } else {
                $count += $child.CountLeaves()
            }
        }
        return $count
    }
}

# Usage
$leaf1 = [Leaf]::new("A")
$leaf2 = [Leaf]::new("B")
$leaf3 = [Leaf]::new("C")
$leaf4 = [Leaf]::new("D")

$composite1 = [Composite]::new("Comp1")
$composite1.Add($leaf1)
$composite1.Add($leaf2)

$composite2 = [Composite]::new("Comp2")
$composite2.Add($leaf3)
$composite2.Add($composite1)

$root = [Composite]::new("Root")
$root.Add($leaf4)
$root.Add($composite2)

Write-Host $root.Operation()
Write-Host "Number of leaves: $($root.CountLeaves())"
Coding Round
96. Visitor pattern

Implement visitor pattern for adding operations to objects.

  • Visitor: Visitor
  • Element: ElementA, ElementB
  • Accept: Accept
  • Counting: CountingVisitor
powershell
# Visitor pattern
class Element {
    [string]$Data
    
    Element([string]$data) {
        $this.Data = $data
    }
    
    virtual [string] Accept([Visitor]$visitor) { return "" }
}

class ElementA : Element {
    ElementA([string]$data) : base($data) {}
    
    [string] Accept([Visitor]$visitor) {
        return $visitor.VisitA($this)
    }
}

class ElementB : Element {
    ElementB([string]$data) : base($data) {}
    
    [string] Accept([Visitor]$visitor) {
        return $visitor.VisitB($this)
    }
}

class Visitor {
    virtual [string] VisitA([ElementA]$element) { return "" }
    virtual [string] VisitB([ElementB]$element) { return "" }
}

class ConcreteVisitor : Visitor {
    [string] VisitA([ElementA]$element) {
        return "Visiting ElementA: $($element.Data)"
    }
    
    [string] VisitB([ElementB]$element) {
        return "Visiting ElementB: $($element.Data)"
    }
}

class CountingVisitor : Visitor {
    [int]$CountA = 0
    [int]$CountB = 0
    
    [string] VisitA([ElementA]$element) {
        $this.CountA++
        return "Visiting ElementA ($($this.CountA)): $($element.Data)"
    }
    
    [string] VisitB([ElementB]$element) {
        $this.CountB++
        return "Visiting ElementB ($($this.CountB)): $($element.Data)"
    }
}

class ExtendedVisitor : Visitor {
    [string] VisitA([ElementA]$element) {
        return "Extended: $($element.Data) (A)"
    }
    
    [string] VisitB([ElementB]$element) {
        return "Extended: $($element.Data) (B)"
    }
}

# Usage
$elements = @(
    [ElementA]::new("Hello"),
    [ElementB]::new("World"),
    [ElementA]::new("PowerShell"),
    [ElementB]::new("Visitor")
)

$visitor = [ConcreteVisitor]::new()
$countingVisitor = [CountingVisitor]::new()
$extendedVisitor = [ExtendedVisitor]::new()

Write-Host "Using standard visitor:"
foreach ($element in $elements) {
    Write-Host $element.Accept($visitor)
}

Write-Host "Using counting visitor:"
foreach ($element in $elements) {
    Write-Host $element.Accept($countingVisitor)
}
Write-Host "Counts: A=$($countingVisitor.CountA), B=$($countingVisitor.CountB)"

Write-Host "Using extended visitor:"
foreach ($element in $elements) {
    Write-Host $element.Accept($extendedVisitor)
}
Coding Round
97. Iterator pattern

Implement iterator pattern for sequential access.

  • Iterator: Iterator
  • Reverse: ReverseIterator
  • Filter: FilteredIterator
  • Skip: SkipIterator
powershell
# Iterator pattern
class Iterator {
    $Collection
    [int]$Position = 0
    
    Iterator($collection) {
        $this.Collection = $collection
    }
    
    $Current() {
        return $this.Collection[$this.Position] ?? $null
    }
    
    [int] Key() {
        return $this.Position
    }
    
    [void] Next() {
        $this.Position++
    }
    
    [void] Rewind() {
        $this.Position = 0
    }
    
    [bool] Valid() {
        return $this.Position -lt $this.Collection.Count
    }
}

class ReverseIterator : Iterator {
    ReverseIterator($collection) : base($collection) {
        $this.Position = $collection.Count - 1
    }
    
    [void] Next() {
        $this.Position--
    }
    
    [void] Rewind() {
        $this.Position = $this.Collection.Count - 1
    }
    
    [bool] Valid() {
        return $this.Position -ge 0
    }
}

class FilteredIterator : Iterator {
    [scriptblock]$Predicate
    
    FilteredIterator($collection, [scriptblock]$predicate) : base($collection) {
        $this.Predicate = $predicate
        $this.Collection = $collection | Where-Object $predicate
    }
}

class SkipIterator : Iterator {
    SkipIterator($collection, $n) : base($collection) {
        $this.Collection = $collection[$n..($collection.Count - 1)]
    }
}

# Usage
$collection = @("A", "B", "C", "D", "E")
$iterator = [Iterator]::new($collection)

Write-Host "Forward iteration:"
while ($iterator.Valid()) {
    Write-Host $iterator.Current() -NoNewline
    Write-Host " " -NoNewline
    $iterator.Next()
}
Write-Host ""

$reverseIterator = [ReverseIterator]::new($collection)
Write-Host "Reverse iteration:"
while ($reverseIterator.Valid()) {
    Write-Host $reverseIterator.Current() -NoNewline
    Write-Host " " -NoNewline
    $reverseIterator.Next()
}
Write-Host ""

$filteredIterator = [FilteredIterator]::new($collection, { param($item) $item.Length -le 1 })
Write-Host "Filtered iteration:"
while ($filteredIterator.Valid()) {
    Write-Host $filteredIterator.Current() -NoNewline
    Write-Host " " -NoNewline
    $filteredIterator.Next()
}
Write-Host ""
Coding Round
98. Template Method pattern

Implement template method with customizable steps.

  • Template: Template
  • Method: TemplateMethod
  • Default: DefaultTemplate
  • Logging: LoggingTemplate
powershell
# Template Method pattern
class Template {
    [void] TemplateMethod() {
        Write-Host $this.Step1()
        Write-Host $this.Step2()
        Write-Host $this.Step3()
    }
    
    virtual [string] Step1() { return "" }
    virtual [string] Step2() { return "" }
    virtual [string] Step3() { return "" }
}

class DefaultTemplate : Template {
    [string] Step1() { return "Step 1" }
    [string] Step2() { return "Step 2" }
    [string] Step3() { return "Step 3" }
}

class LoggingTemplate : Template {
    [Template]$InnerTemplate
    
    LoggingTemplate([Template]$template) {
        $this.InnerTemplate = $template
    }
    
    [string] Step1() {
        $result = $this.InnerTemplate.Step1()
        Write-Host "Logging: $result"
        return $result
    }
    
    [string] Step2() {
        $result = $this.InnerTemplate.Step2()
        Write-Host "Logging: $result"
        return $result
    }
    
    [string] Step3() {
        $result = $this.InnerTemplate.Step3()
        Write-Host "Logging: $result"
        return $result
    }
}

class DataProcessingTemplate : Template {
    [string]$Data
    
    DataProcessingTemplate([string]$data) {
        $this.Data = $data
    }
    
    [string] Step1() {
        return "Processing data: $($this.Data) - Step 1"
    }
    
    [string] Step2() {
        return "Processing data: $($this.Data) - Step 2"
    }
    
    [string] Step3() {
        return "Processing data: $($this.Data) - Step 3"
    }
}

# Usage
Write-Host "Using default template:"
$default = [DefaultTemplate]::new()
$default.TemplateMethod()

Write-Host "Using logging template:"
$logging = [LoggingTemplate]::new($default)
$logging.TemplateMethod()

Write-Host "Using data processing template:"
$dataTemplate = [DataProcessingTemplate]::new("example")
$dataTemplate.TemplateMethod()
Coding Round
99. Builder pattern

Implement builder pattern for constructing complex objects.

  • Builder: Builder
  • Director: Director
  • Product: Product
  • Build: BuildMinimal, BuildFull
powershell
# Builder pattern
class Product {
    [System.Collections.ArrayList]$Parts = @()
    
    [void] AddPart([string]$part) {
        $this.Parts.Add($part)
    }
    
    [void] ListParts() {
        Write-Host ($this.Parts -join ", ")
    }
}

class Builder {
    [Product]$Product
    
    Builder() {
        $this.Reset()
    }
    
    [void] Reset() {
        $this.Product = [Product]::new()
    }
    
    [void] BuildStepA() {
        $this.Product.AddPart("Part A")
    }
    
    [void] BuildStepB() {
        $this.Product.AddPart("Part B")
    }
    
    [void] BuildStepC() {
        $this.Product.AddPart("Part C")
    }
    
    [Product] GetResult() {
        $result = $this.Product
        $this.Reset()
        return $result
    }
}

class Director {
    [Builder]$Builder
    
    Director([Builder]$builder) {
        $this.Builder = $builder
    }
    
    [void] BuildMinimal() {
        $this.Builder.BuildStepA()
    }
    
    [void] BuildFull() {
        $this.Builder.BuildStepA()
        $this.Builder.BuildStepB()
        $this.Builder.BuildStepC()
    }
    
    [void] BuildCustom([string[]]$steps) {
        $this.Builder.Reset()
        foreach ($step in $steps) {
            switch ($step) {
                "A" { $this.Builder.BuildStepA() }
                "B" { $this.Builder.BuildStepB() }
                "C" { $this.Builder.BuildStepC() }
            }
        }
    }
}

# Usage
$builder = [Builder]::new()
$director = [Director]::new($builder)

Write-Host "Minimal product:"
$director.BuildMinimal()
$builder.GetResult().ListParts()

Write-Host "Full product:"
$director.BuildFull()
$builder.GetResult().ListParts()

Write-Host "Custom product:"
$builder.BuildStepC()
$builder.BuildStepA()
$builder.GetResult().ListParts()

Write-Host "Director custom:"
$director.BuildCustom(@("C", "A", "B"))
$builder.GetResult().ListParts()
Coding Round
100. Prototype pattern

Implement prototype pattern for cloning objects.

  • Prototype: Prototype
  • Clone: Clone
  • Deep clone: DeepClone
  • Mutable: MutablePrototype
powershell
# Prototype pattern
class Prototype {
    $Data
    
    Prototype($data) {
        $this.Data = $data
    }
    
    [Prototype] Clone() {
        return [Prototype]::new($this.Data)
    }
    
    [Prototype] DeepClone() {
        return [Prototype]::new($this.DeepCopy($this.Data))
    }
    
    hidden DeepCopy($value) {
        if ($value -is [array]) {
            $result = @()
            foreach ($item in $value) {
                $result += $this.DeepCopy($item)
            }
            return $result
        } elseif ($value -is [hashtable]) {
            $result = @{}
            foreach ($key in $value.Keys) {
                $result[$key] = $this.DeepCopy($value[$key])
            }
            return $result
        } elseif ($value -is [PSCustomObject]) {
            $result = [PSCustomObject]@{}
            foreach ($prop in $value.PSObject.Properties) {
                $result | Add-Member -MemberType NoteProperty -Name $prop.Name -Value ($this.DeepCopy($prop.Value))
            }
            return $result
        } else {
            return $value
        }
    }
}

class MutablePrototype : Prototype {
    MutablePrototype($data) : base($data) {}
    
    [void] SetData($data) {
        $this.Data = $data
    }
}

# Usage
$original = [Prototype]::new(@{Name = "Original"; Value = 42})
$copy = $original.Clone()
$deepCopy = $original.DeepClone()

Write-Host "Original: $($original.Data | ConvertTo-Json)"
Write-Host "Copy: $($copy.Data | ConvertTo-Json)"
Write-Host "Deep copy: $($deepCopy.Data | ConvertTo-Json)"

$mutable = [MutablePrototype]::new(@(1, 2, 3))
Write-Host "Original data: $($mutable.Data -join ', ')"
$mutable.SetData(@(4, 5, 6))
Write-Host "Modified data: $($mutable.Data -join ', ')"

$clonedMutable = $mutable.Clone()
Write-Host "Clone data: $($clonedMutable.Data -join ', ')"