100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Functions and Parameters

Learn to write reusable PowerShell functions with typed, validated, pipeline-aware parameters, and understand how advanced functions behave like native cmdlets.

Control Flow & FunctionsIntermediate10 min readJul 10, 2026
Analogies

Defining Functions and Basic Parameters

A PowerShell function is declared with the function keyword followed by a name and a script block: function Verb-Noun { param($Name) ... }. PowerShell's naming convention pairs an approved verb (Get, Set, New, Remove, Test, etc., listed by Get-Verb) with a singular noun, which keeps function names predictable and lets Get-Command discover them consistently. Parameters are declared inside a param() block at the top of the function, and each can carry a type constraint like [string] or [int] that PowerShell enforces by attempting a conversion before the function body runs.

🏏

Cricket analogy: Like naming a fielding drill Get-CatchPractice rather than DoCatchStuff, the same verb-noun discipline the BCCI's coaching manuals use for named drills so coaches can find them instantly.

Parameter Validation and Attributes

Validation attributes placed above a parameter enforce constraints before the function body ever runs: [ValidateNotNullOrEmpty()] rejects null or empty strings, [ValidateSet('A','B','C')] restricts input to specific values (and also drives tab-completion), [ValidateRange(1,100)] bounds numeric input, and [ValidateScript({...})] runs custom logic returning $true or $false. Marking a parameter [Parameter(Mandatory)] forces PowerShell to prompt interactively for a value if the caller omits it, rather than letting the function run with $null.

🏏

Cricket analogy: Like a scoring app using [ValidateRange(0,6)] on $runsThisBall, rejecting an invalid value before it ever hits the scorecard, since no legal delivery scores more than 6 runs at once (barring overthrows).

Pipeline Input and ValueFromPipeline

A function accepts piped input by marking a parameter [Parameter(ValueFromPipeline=$true)] (for whole objects) or [Parameter(ValueFromPipelineByPropertyName=$true)] (to bind by matching property names). To process each piped item, the function needs a process {} block; without one, a function only receives the last object in the pipeline because a bare function body behaves like an end {} block that runs once after all input has arrived. begin {}, process {}, and end {} mirror the three phases available to ForEach-Object.

🏏

Cricket analogy: Like a scorer function with a process{} block updating the scorecard for every single ball piped in from a live feed, rather than only recording the final ball of the over.

Advanced Functions with CmdletBinding

Adding [CmdletBinding()] above param() turns an ordinary function into an advanced function that behaves like a compiled cmdlet: it gains common parameters (-Verbose, -Debug, -ErrorAction, -WarningAction), automatic support for -WhatIf and -Confirm when combined with SupportsShouldProcess=$true, and stricter parameter binding. Inside such a function, Write-Verbose and Write-Debug output is suppressed unless the caller passes -Verbose or -Debug, giving you diagnostic logging that doesn't clutter normal output. SupportsShouldProcess pairs with an explicit if ($PSCmdlet.ShouldProcess($target, $action)) check around any destructive operation.

🏏

Cricket analogy: Like a review system that only shows ball-tracking detail (-Verbose) when the third umpire explicitly requests it, keeping the broadcast clean for viewers who don't ask for that layer.

powershell
function Remove-OldLogFile {
    [CmdletBinding(SupportsShouldProcess = $true)]
    param(
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [ValidateNotNullOrEmpty()]
        [string]$Path,

        [Parameter()]
        [ValidateRange(1, 365)]
        [int]$OlderThanDays = 30
    )

    begin {
        $cutoff = (Get-Date).AddDays(-$OlderThanDays)
        Write-Verbose "Removing files older than $cutoff"
    }

    process {
        $file = Get-Item -Path $Path -ErrorAction SilentlyContinue
        if (-not $file) {
            Write-Warning "Skipping missing file: $Path"
            return
        }
        if ($file.LastWriteTime -lt $cutoff) {
            if ($PSCmdlet.ShouldProcess($file.FullName, 'Delete log file')) {
                Remove-Item -Path $file.FullName -Force
                Write-Verbose "Deleted $($file.FullName)"
            }
        }
    }

    end {
        Write-Verbose 'Cleanup complete.'
    }
}

Get-ChildItem 'C:\Logs' -Filter *.log | Remove-OldLogFile -OlderThanDays 90 -WhatIf

Use Get-Verb to list the ~100 PowerShell-approved verbs (Get, Set, New, Remove, Test, Invoke, etc.). Using an unapproved verb like Create- or Delete- still works, but PowerShell emits a warning when the module loads and it breaks the discoverability convention that Get-Command and tab-completion rely on.

Without a process {} block, a function that receives piped input only sees the LAST object in the pipeline, because the entire function body runs once as an implicit end block after all pipeline input has already been collected. This is a common source of bugs when converting a simple function into a pipeline-aware one.

  • Functions follow Verb-Noun naming using PowerShell-approved verbs from Get-Verb for discoverability.
  • Type-constrained parameters ([string], [int], etc.) trigger automatic conversion and rejection of incompatible input.
  • Validation attributes like [ValidateSet], [ValidateRange], and [ValidateScript] enforce constraints before the function body runs.
  • ValueFromPipeline and ValueFromPipelineByPropertyName let a function accept piped objects.
  • A process {} block is required to handle every piped item; without it, only the last item is processed.
  • [CmdletBinding()] adds common parameters (-Verbose, -Debug, -ErrorAction) and enables cmdlet-like behavior.
  • SupportsShouldProcess with $PSCmdlet.ShouldProcess() enables -WhatIf and -Confirm for destructive operations.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#PowerShellStudyNotes#FunctionsAndParameters#Functions#Parameters#Defining#Parameter#StudyNotes#SkillVeris#ExamPrep