Arguments enable creating dynamic, reusable script logic by parameterizing core data. This comprehensive expert guide covers methods, validation, best practices and more for robust PowerShell argument handling.

What are Arguments from a Coding Perspective

Arguments, or parameters, provide a way to pass data into function or script scopes. By coding logic to accept variables rather than hard-coded values, the behavior becomes configurable per invocation.

For example, we could lookup a specific user account:

$user = Get-ADUser -Identity ‘JohnDoe‘ 

But it is better practice to define a parameter:

param($UserName)

$user = Get-ADUser -Identity $UserName

Now any user can be looked up by passing the account name. This separates fixed program logic from configurable input data for modular code reuse.

Why Use Arguments

Main benefits of coding with arguments:

  • Configurability – Customize behavior by parameter input
  • Reusability – Call same logic for different needs
  • Maintainability – Isolate changeable data from core logic
  • Testability – Substitute input data to test scenarios
  • Flexibility – Adapt without altering underlying code

Basic Passing Techniques

PowerShell offers built-in ways to pass input values.

param Statement

The param() statement enables defining named parameters:

param($Query, $Server)

Callers pass values to the argument names:

.\Script.ps1 -Query ‘AD User Query‘ -Server DC01

This binds the inputs to $Query and $Server variables respectively.

$args Automatic Array

All input values get packed into the $args array automatically:

$args[0] -> First Value
$args[1] -> Second Value

Iterate $args directly or cast to another data type like array or hash table.

Pipeline Input Binding

The $input variable contains pipeline-passed objects for iteration:

Get-Process | .\Script.ps1

Then in the script:

process {
    foreach ($object in $input) {
        # Take action on each pipeline object
    }
}

Binding automatic variables streamlines passing data between commands.

Parameter Validation

Validating Simple Input

The parameter statement supports advanced validation rules before accepting values including:

ValidateSet – Check if value matches an allowed set

[ValidateSet(‘John‘,‘Sarah‘,‘Johnathan‘)]
[string]$Name

ValidatePattern – Match regex rules

[ValidatePattern(‘^[A-Z]{3}[0-9]{4}$‘)]  
[string]$PartNumber    

ValidateRange – Numeric min and max

[ValidateRange(0,120)]
[int]$Age

And more like ValidateNotNullOrEmpty, ValidateCount, ValidateLength etc.

Validating Complex Types

We can validate Hashtables:

param
(
    [ValidateNotNull()]
    [hashtable]$Settings
)  

Arrays:

[array]$UserList

And full custom objects:

param
(
    [ValidateScript({
        if (-not ($_.FirstName -and $_.LastName)) {
            throw "First and last name must be populated"
        }
        $true 
    })]
    [PSCustomObject]$User
)

This future proofs input handling as logic grows.

Securing Credentials

The Get-Credential cmdlet generates domain credential objects:

$cred = Get-Credential
.\Script.ps1 -Credential $cred

Then validate in param():

param(
    [ValidateNotNull()]
    [System.Management.Automation.PSCredential]
    [System.Management.Automation.Credential()]$Credential = [System.Management.Automation.PSCredential]::Empty
)

This properly handles sensitive credentials.

Handling Invalid Data

Instead of hard failures, handle invalid data gracefully:

param
(
    [ValidateSet(‘A‘,‘B‘)]
    [string]$Choice
)

process {
    if ($Choice -notin ‘A‘, ‘B‘) {
        Write-Warning "Invalid choice ‘$Choice‘, defaulting to A"  
        $Choice = ‘A‘
    }

    "Performing work for choice $Choice"
}

This prevents errors and provides context to correct issues.

Splatting for Complex Input

Hashtables containing parameter name/value pairs can be splatted into commands using the @ syntax:

$params = @{  
    ComputerName = $Servers 
    Credential = $AdminCreds
    ScriptBlock = {Get-Service BITS}
}

Invoke-Command @params

Splatting condenses parameter lists for better readability with many arguments. Parameters can also be built programmatically for reusable invocation code.

Prompting Users for Input

The Read-Host cmdlet asks for user input:

$systemName = Read-Host -Prompt ‘Enter server name‘

Validate prompted values before usage:

do {
    $server = Read-Host -Prompt ‘Enter server‘
} while (-not $server)

"Connecting to $server" 

Integrate prompting into scripts to simplify running workflows interactively.

Argument Best Practices

Follow these guidelines when working with arguments:

  • Validate all input via parameter attributes or manually
  • Use clear, descriptive parameter names like -ServerList vs -List
  • Document parameters via comment based help and Param() blocks
  • Initialize default values for optional parameters
  • Handle invalid values gracefully instead of errors
  • Consider splatting for complex input lists
  • Prompt for input when running interactive sessions
  • Organize reusable logic into modules with consistent parameters

Careful argument coding prevents bugs, enhances usability and enables more modular components.

Advanced Argument Techniques

Several lesser known features provide additional capabilities.

Parameter Aliases

Define aliases to allow alternate parameter names:

param
(
    [Parameter(Mandatory)]
    [alias(‘CN‘,‘UserName‘)]
    $CredentialName
) 

Now -CredentialName, -CN and -UserName are interchangeable.

Dynamic ValidateSet

Generate allowed values dynamically:

$dataset = 1..100

param(
    [ValidateSet($dataset)]
    $Number
)

Rather than a static list.

Parameter Sets

Define unique parameter combinations with parameter sets:

[CmdletBinding(DefaultParameterSetName = ‘Set1‘)]
param (
    [Parameter(ParameterSetName=‘Set1‘, Position=0)]
    $UserName,

    [Parameter(ParameterSetName=‘Set2‘, Mandatory)]
    $FirstName
)

process {
    if ($PsCmdlet.ParameterSetName -eq ‘Set1‘) {
        # Use $UserName 
    }
    else {
        # Use $FirstName
    }
}

This enables specialized input scenarios.

Recommended Learning Resources

For deeper knowledge on arguments in PowerShell, refer to:

  • About Parameters Get-Help about_Parameters
  • About Automatic Variables Get-Help about_Automatic_Variables
  • Microsoft Docs: Parameters in PowerShell

These cover additional capabilities not discussed here like parameter binding behavior, variable naming, type conversion, etc.

Putting It All Together

Arguments enable building robust reusable logic by separating parameters from core programming algorithms. PowerShell provides many techniques from basic to advanced with sanity checking via validation. Follow best practices to create well-designed components. Consider organizing reusable functions into modules with consistent argument patterns.

This guide covered fundamental methods up through improved reliability by parameterization and tested reuse via substitutable input data. Pass arguments in PowerShell confidently utilizing everything outlined here to enhance script quality.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *