Skip to content

PowerShell Functions

How to create, call, and manage reusable PowerShell functions using the function keyword, following the Verb-Noun convention for consistency with native cmdlets.

A function in PowerShell is a named, reusable block of code that encapsulates instructions, processes data, and emits objects into the pipeline. Once declared in memory or imported via a script, functions behave identically to compiled native cmdlets. Organizing code into reusable functions simplifies maintenance, reduces code duplication, and enables modular script architecture, letting you avoid repeating the same logic throughout a script, group related operations together, and give complex logic a clear, descriptive name.

The function Keyword and Syntax

A function is declared using the function keyword, followed by the function's identifier and an executable script block enclosed in curly braces ({ }).

Basic Syntax

function <FunctionName> {
}
basic-function.ps1powershell
function Show-Greeting {
    Write-Output "Hello from a PowerShell function!"
}

Where:

  • function is the keyword that begins the declaration.
  • Show-Greeting is the function's name, registered in the Function: PSDrive in memory.
  • { } encloses the function body, the statements that run whenever the function is called.

Calling a Function

Once defined, a function is called simply by typing its name, exactly like calling a built-in cmdlet.

call-function.ps1powershell
function Show-Greeting {
    Write-Output "Hello from a PowerShell function!"
}

Show-Greeting
Consolepowershell
./call-function.ps1
Outputplaintext
Hello from a PowerShell function!

Where:

  • Show-Greeting on the last line invokes the function, running everything inside its { } block.
  • The function must be defined before it's called in the script, as PowerShell reads and executes top to bottom.

Functions Can Be Called Multiple Times

call-multiple.ps1powershell
function Show-Greeting {
    Write-Output "Hello from a PowerShell function!"
}

Show-Greeting
Show-Greeting
Show-Greeting
Consolepowershell
./call-multiple.ps1
Outputplaintext
Hello from a PowerShell function!
Hello from a PowerShell function!
Hello from a PowerShell function!

A more complete example that reads from the environment:

basic-function-demo.ps1powershell
function Show-WelcomeMessage {
    $CurrentUser = $env:USERNAME
    $CurrentHost = $env:COMPUTERNAME
    Write-Output "PowerShell session initialized for $CurrentUser on $CurrentHost."
}

Show-WelcomeMessage
Consolepowershell
pwsh ./basic-function-demo.ps1
Outputplaintext
PowerShell session initialized for Tom on WORKSTATION-01.

Function Naming: The Verb-Noun Convention

Just like built-in cmdlets, custom functions should follow the Verb-Noun naming convention (see Frequently Used Cmdlets), which makes your own functions feel like a natural extension of PowerShell itself.

  • The Verb: Describes the action taken (e.g., Get, Set, New, Remove, Test, Start, Stop, Invoke).
  • The Noun: Describes the resource or system component being acted upon (e.g., HostBaseline, ServiceState, NetworkRoute). Cmdlet nouns should always be singular (e.g., Get-DiskReport, not Get-DisksReport).
  Approved Verb         Singular Noun
        │                     │
   ┌────┴─────┐        ┌──────┴──────┐
       Get        -     ServiceStatus

Inspecting Approved Verbs

PowerShell enforces an approved list of verbs to maintain predictable semantics. You can query approved verbs at any time using Get-Verb:

Consolepowershell
Get-Verb | Select-Object -First 5
Outputplaintext
Verb        Group
----        -----
Add         Common
Clear       Common
Close       Common
Copy        Common
Enter       Common
Consolepowershell
Get-Verb -Verb "Test", "Get", "Invoke"
Outputplaintext
Verb   AliasPrefix Group       Description
----   ----------- -----       -----------
Get    g           Common      Specifies an action that retrieves a resource...
Invoke i           Lifecycle   Specifies an action that does not map directly...
Test   t           Diagnostic  Specifies an action that verifies the operation...

Good vs Poor Function Names

Poor Name Good Name Why
DoStuff Restart-PrintSpooler Uses an approved verb and a clear, singular noun
ProcessFiles Move-ArchivedFiles Process isn't an approved verb; Move is specific and standard
checkService Test-ServiceStatus Uses Test (an approved verb) and proper PascalCase
getdata Get-InventoryData Follows casing conventions and uses a specific noun
well-named-function.ps1powershell
function Test-ServiceStatus {
    param(
        [string]$ServiceName
    )

    $service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
    if ($null -eq $service) {
        Write-Output "$ServiceName not found."
    } else {
        Write-Output "$ServiceName is currently: $($service.Status)"
    }
}

Test-ServiceStatus -ServiceName "Spooler"
Consolepowershell
./well-named-function.ps1
Outputplaintext
Spooler is currently: Running

Why the Convention Matters

  • Discoverability: Functions named consistently with Verb-Noun are easier for other developers (and your future self) to understand at a glance.
  • Tooling support: Get-Command and Get-Help work seamlessly with properly named functions, just as they do with built-in cmdlets.
  • Avoiding naming conflicts: Following the convention reduces the likelihood of colliding with existing cmdlet or module function names.

Inspecting and Managing Functions in Memory

All active functions are exposed through the built-in Function: PSDrive. You can inspect, modify, or test functions using standard provider cmdlets (Get-Item, Get-ChildItem):

Consolepowershell
Test-Path -Path "Function:\Show-WelcomeMessage"

(Get-Item -Path "Function:\Show-WelcomeMessage").Definition
Outputplaintext
True
$CurrentUser = $env:USERNAME
    $CurrentHost = $env:COMPUTERNAME
    Write-Output "PowerShell session initialized for $CurrentUser on $CurrentHost."

To remove a function from the active session:

Consolepowershell
Remove-Item -Path "Function:\Show-WelcomeMessage"

Practical Example: System Uptime Diagnostic Function

The following script declares a structured diagnostic function named Get-HostUptime. It queries the local operating system configuration via CIM, computes elapsed operational uptime using DateTime arithmetic, and emits a structured [PSCustomObject]:

Get-HostUptime.ps1powershell
function Get-HostUptime {
    $OperatingSystem = Get-CimInstance -ClassName Win32_OperatingSystem
    $LastBoot = $OperatingSystem.LastBootUpTime
    $CurrentTime = Get-Date

    $UptimeSpan = $CurrentTime - $LastBoot

    [PSCustomObject]@{
        ComputerName   = $env:COMPUTERNAME
        LastBootTime   = $LastBoot.ToString("yyyy-MM-dd HH:mm:ss")
        UptimeDays     = [math]::Round($UptimeSpan.TotalDays, 1)
        UptimeHours    = [math]::Round($UptimeSpan.TotalHours, 1)
        Status         = if ($UptimeSpan.TotalDays -gt 30) { "Reboot Recommended" } else { "Normal" }
    }
}

Get-HostUptime

Where:

  • function Get-HostUptime defines the function using an approved verb (Get) and a singular noun (HostUptime).
  • Get-CimInstance -ClassName Win32_OperatingSystem queries the Windows management layer for operating system telemetry.
  • $CurrentTime - $LastBoot performs date arithmetic to calculate a System.TimeSpan object.
  • [PSCustomObject] wraps the diagnostic fields into a structured object for tabular console rendering or pipeline streaming.

Execute the script from the console:

Consolepowershell
pwsh ./Get-HostUptime.ps1
Outputplaintext
ComputerName : WEB01
LastBootTime : 2026-09-27 16:38:06
UptimeDays   : 0.3
UptimeHours  : 7.3
Status       : Normal

Quick Reference

Task Syntax
Declare a function function Name { ... }
Call a function Name
Call with named parameters Name -Param "value"
List approved verbs Get-Verb
Check if function exists Test-Path "Function:\Name"
View function source code (Get-Item "Function:\Name").Definition
Remove a function from session Remove-Item "Function:\Name"
Load function into current session . ./script.ps1 (dot-source)
Navigation