PSPowerShell · Lesson 4 of 8

Functions & Cmdlets

PowerShell functions can behave like cmdlets — with parameters, validation, help text, and pipeline support. It's the most sophisticated function system in any shell.

PowerShell
# Basic function
function Get-Greeting {
    param(
        [string]$Name = "World",
        [string]$Title = "friend"
    )
    return "Hello, $Title $Name!"
}

Get-Greeting                       # Hello, friend World!
Get-Greeting -Name "Alice"         # Hello, friend Alice!
Get-Greeting -Name "Smith" -Title "Dr."  # Hello, Dr. Smith!

# Advanced function with validation and help
function Convert-Temperature {
    <#
    .SYNOPSIS
        Convert temperature between Celsius and Fahrenheit.
    .EXAMPLE
        Convert-Temperature -Value 100 -From Celsius
    #>
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, Position=0)]
        [double]$Value,

        [Parameter(Mandatory)]
        [ValidateSet("Celsius", "Fahrenheit")]
        [string]$From
    )

    if ($From -eq "Celsius") {
        $result = $Value * 9/5 + 32
        Write-Output "$Value°C = $result°F"
    } else {
        $result = ($Value - 32) * 5/9
        Write-Output "$Value°F = $([math]::Round($result, 2))°C"
    }
}

Convert-Temperature -Value 100 -From Celsius     # 100°C = 212°F
Convert-Temperature -Value 212 -From Fahrenheit  # 212°F = 100°C

# Get built-in help
# Get-Help Convert-Temperature
PowerShell
# Pipeline-aware function
function Format-FileSize {
    param(
        [Parameter(ValueFromPipeline)]
        [System.IO.FileInfo]$File
    )

    process {
        $size = $File.Length
        $unit = switch ($size) {
            { $_ -gt 1GB } { "GB"; break }
            { $_ -gt 1MB } { "MB"; break }
            { $_ -gt 1KB } { "KB"; break }
            default { "B" }
        }
        $formatted = switch ($unit) {
            "GB" { "{0:F2} GB" -f ($size / 1GB) }
            "MB" { "{0:F2} MB" -f ($size / 1MB) }
            "KB" { "{0:F2} KB" -f ($size / 1KB) }
            default { "$size B" }
        }
        [PSCustomObject]@{
            Name = $File.Name
            Size = $formatted
            Extension = $File.Extension
        }
    }
}

# Use it in a pipeline
Get-ChildItem -File | Format-FileSize | Sort-Object Name | Format-Table