Skip to content

PowerShell Functions with Parameters

How to create flexible PowerShell functions using the param() block with typed parameters, default values, mandatory inputs, and both positional and named argument binding.

Parameters allow a function to accept dynamic input from callers, making code flexible, reusable, and configurable rather than hardcoded to a single behavior. In PowerShell, formal parameters are declared inside a param() block placed at the very beginning of the function body. The runtime engine automatically provides command-line argument binding, strong type enforcement, tab completion, and interactive prompts for missing required values.

The param() Block

The param() block is the standard mechanism for declaring parameters in both functions and standalone scripts. It must be the first non-comment statement inside the function body.

Basic Syntax

function <FunctionName> {
    param (
        [<Type>] $<ParameterName1>,
        [<Type>] $<ParameterName2>
    )

}
param-basic.ps1powershell
function Show-Greeting {
    param(
        [string]$Name
    )

    Write-Output "Hello, $Name!"
}

Show-Greeting -Name "Tom"

Where:

  • param([string]$Name) declares a single parameter named $Name, strongly typed as a [string].
  • -Name "Tom" passes the value into the function when calling it.
Consolepowershell
./param-basic.ps1
Outputplaintext
Hello, Tom!

Multiple Parameters

param-multiple.ps1powershell
function Show-ServerGreeting {
    param (
        [string]$ServerName,
        [int]$PortNumber
    )

    Write-Output "Connecting to host: $ServerName on port: $PortNumber"
}

Show-ServerGreeting -ServerName "web-prod-01" -PortNumber 443
Consolepowershell
pwsh ./param-multiple.ps1
Outputplaintext
Connecting to host: web-prod-01 on port: 443

Where:

  • Each parameter is separated by a comma inside the param() block.
  • [string] and [int] enforce type constraints, rejecting incompatible values automatically.

Positional vs. Named Parameters

PowerShell functions can be invoked using either named parameters or positional arguments.

When invoking with parameter names, the arguments can be passed in any order because PowerShell maps each argument using the explicit parameter flag:

Consolepowershell
function Show-ServerGreeting {
    param (
        [string]$ServerName,
        [int]$PortNumber
    )

    Write-Output "Connecting to host: $ServerName on port: $PortNumber"
}

Show-ServerGreeting -ServerName "sql01" -PortNumber 1433
Show-ServerGreeting -PortNumber 1433 -ServerName "sql01"

Using named parameters improves code readability in scripts and prevents accidental binding errors if the function's internal parameter list changes later.

2. Positional Parameters

By default, any parameter in a standard function can also be bound positionally based on the order it is declared inside the param() block:

Consolepowershell
function Show-ServerGreeting {
    param (
        [string]$ServerName,
        [int]$PortNumber
    )

    Write-Output "Connecting to host: $ServerName on port: $PortNumber"
}

Show-ServerGreeting "sql01" 1433
Outputplaintext
Connecting to host: sql01 on port: 1433

Where without explicit -ServerName/-PortNumber labels, PowerShell assigns arguments to parameters based on their declared order in the param() block.

Explicitly Controlling Position

To explicitly declare the exact argument position regardless of physical declaration order in the code, use the Position attribute inside [Parameter()]:

explicit-position.ps1powershell
function Show-UserInfo {
    param(
        [Parameter(Position = 0)]
        [string]$Name,

        [Parameter(Position = 1)]
        [int]$Age
    )

    Write-Output "$Name is $Age years old."
}

Default Parameter Values

A default parameter value provides a fallback value if the caller omits that parameter during invocation. Default values are assigned directly within the param() declaration using the assignment operator (=):

default-values.ps1powershell
function Connect-DatabaseEndpoint {
    param (
        [string]$ServerName,
        [int]$PortNumber = 1433,
        [string]$Database = "Master",
        [int]$TimeoutSeconds = 30
    )

    [PSCustomObject]@{
        TargetHost     = $ServerName
        ListeningPort  = $PortNumber
        TargetDatabase = $Database
        Timeout        = $TimeoutSeconds
    }
}

Connect-DatabaseEndpoint -ServerName "sql-cluster-01"
Consolepowershell
pwsh ./default-values.ps1
Outputplaintext
TargetHost     ListeningPort TargetDatabase Timeout
----------     ------------- -------------- -------
sql-cluster-01          1433 Master              30

Where:

  • $PortNumber = 1433, $Database = "Master", and $TimeoutSeconds = 30 provide fallback values.
  • If the caller supplies -PortNumber 1500, the explicit argument overrides the default 1433.
  • Calling the function with no arguments falls back to all defaults.

A simpler example with defaults for all parameters:

Consolepowershell
function Show-UserInfo {
    param(
        [string]$Name = "Guest",
        [int]$Age = 18
    )

    Write-Output "$Name is $Age years old."
}

Show-UserInfo
Show-UserInfo -Name "Taylor"
Outputplaintext
Guest is 18 years old.
Taylor is 18 years old.

Mandatory Parameters

To ensure a function cannot run without a required input, mark the parameter with the [Parameter(Mandatory = $true)] attribute (or the shorthand [Parameter(Mandatory)]). If a caller runs the function without providing a mandatory parameter, PowerShell pauses execution and displays an interactive prompt asking the user to supply the missing value.

mandatory-param.ps1powershell
function New-UserAccount {
    param(
        [Parameter(Mandatory)]
        [string]$Username
    )

    Write-Output "Creating account for: $Username"
}

New-UserAccount
Consolepowershell
./mandatory-param.ps1
Outputplaintext
cmdlet New-UserAccount at command pipeline position 1
Supply values for the following parameters:
Username:

Where:

  • [Parameter(Mandatory)] tells PowerShell to require this parameter.
  • If the caller omits -Username, PowerShell pauses and interactively prompts for it instead of failing silently or using $null.

Supply the parameter explicitly to run without prompting:

Consolepowershell
./mandatory-param.ps1 -Username "admin01"
Outputplaintext
Creating account for: admin01

Combining Mandatory with Optional Parameters

combined-example.ps1powershell
function New-Employee {
    param(
        [Parameter(Mandatory)]
        [string]$Name,

        [Parameter(Mandatory)]
        [string]$Department,

        [string]$Title = "Staff"
    )

    Write-Output "$Name joins $Department as $Title."
}

New-Employee -Name "Morgan" -Department "Engineering"
Consolepowershell
./combined-example.ps1
Outputplaintext
Morgan joins Engineering as Staff.

Where:

  • $Name and $Department are required; omitting either triggers an interactive prompt.
  • $Title remains optional, falling back to "Staff" if not specified.

Customizing the Missing Prompt Message

You can provide an informative error or guidance message using the HelpMessage property:

param (
    [Parameter(Mandatory = $true, HelpMessage = "Specify a single drive letter (e.g., 'E' or 'F').")]
    [string]$DriveLetter
)

If the prompt appears, the operator can type !? to display your custom help text.

Practical Example: Resilient Service Management Function

The following production-style function combines mandatory parameters, position binding, default values, and switch parameters into a service management utility:

Invoke-ServiceRestart.ps1powershell
function Invoke-ServiceRestart {
    param (
        [Parameter(Mandatory = $true, Position = 0, HelpMessage = "Enter the Windows service name.")]
        [string]$ServiceName,

        [Parameter(Position = 1)]
        [int]$TimeoutSeconds = 15,

        [switch]$Force
    )

    Write-Output "Checking service '$ServiceName'..."

    $TargetService = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
    if ($null -eq $TargetService) {
        Write-Error "Service '$ServiceName' does not exist on this host."
        return
    }

    Write-Output "Restarting service '$ServiceName' (Timeout: $TimeoutSeconds s)..."

    try {
        if ($Force) {
            Restart-Service -Name $ServiceName -Force -ErrorAction Stop
        } else {
            Restart-Service -Name $ServiceName -ErrorAction Stop
        }

        $TargetService.WaitForStatus('Running', [TimeSpan]::FromSeconds($TimeoutSeconds))

        [PSCustomObject]@{
            ServiceName      = $TargetService.ServiceName
            DisplayName      = $TargetService.DisplayName
            FinalStatus      = $TargetService.Status
            RestartSucceeded = $true
            ExecutionTime    = (Get-Date -Format "HH:mm:ss")
        }
    }
    catch {
        Write-Error "Failed to restart service '$ServiceName': $($_.Exception.Message)"
    }
}

Invoke-ServiceRestart -ServiceName "Spooler" -TimeoutSeconds 10

Where:

  • [Parameter(Mandatory = $true, Position = 0)] makes $ServiceName required and lets callers pass it as the first argument without typing -ServiceName.
  • [int]$TimeoutSeconds = 15 supplies a 15-second default timeout.
  • [switch]$Force defines a boolean switch parameter ($true when -Force is passed, $false when omitted).
  • $TargetService.WaitForStatus(...) calls a native .NET method to block until the service enters the desired state.

Execute the script from the console:

Consolepowershell
pwsh ./Invoke-ServiceRestart.ps1
Outputplaintext
Checking service 'Spooler'...
Restarting service 'Spooler' (Timeout: 10 s)...

ServiceName DisplayName   FinalStatus RestartSucceeded ExecutionTime
----------- -----------   ----------- ---------------- -------------
Spooler     Print Spooler     Running             True 00:25:10

Quick Reference

Concept Syntax Example
Single parameter [Type]$Name param([string]$Name)
Multiple parameters Comma-separated param([string]$Name, [int]$Age)
Named invocation -ParamName Value Show-Greeting -Name "Tom"
Positional invocation Values in order Show-Greeting "Tom"
Explicit position [Parameter(Position = 0)] [Parameter(Position = 0)] [string]$Name
Default value = value [int]$Port = 1433
Mandatory parameter [Parameter(Mandatory)] [Parameter(Mandatory)] [string]$User
Help message HelpMessage = "..." [Parameter(Mandatory, HelpMessage = "...")]
Switch parameter [switch]$Flag [switch]$Force
Navigation