Table of Contents

    PowerShell functions are the building blocks of automation, and understanding their parameters is key to crafting efficient and adaptable scripts. Let’s explore the power and versatility that parameters bring to PowerShell functions.

    Understanding PowerShell Function Parameters

    PowerShell function parameters are variables that you define within a function to accept input values from the calling code. Parameters allow you to create flexible and reusable functions by specifying placeholders for values that can be passed when the function is called.

    PowerShell function parameters are crucial for customizing and reusing functions across projects, allowing dynamic execution and automation. They enforce consistency, prevent errors, and streamline workflows in production environments. Parameters adapt scripts to varying needs, ensuring adaptability and easy testing for specific functionalities.

    Making PowerShell Function with Parameters and Examples

    Now let’s create a PowerShell Function with Parameters step by step:

    Example 1

    Step 1: Creating function

    Use the function keyword followed by the name you want to assign to your function. Then, use a pair of curly braces {} to encapsulate the code

    function Test1
    {
        
    }
    

    Step 2: Add Parameters

    Use the param() block inside the function. Define each parameter using its name and data type. You can also set default values or define optional parameters. Below the function take two parameters ($param1 and $param2)

    function Test1 
    {
        param(
            [string]$param1,
            [int]$param2
        )
    
    }
    

    Step 3: Utilize the Parameters

    For example,

    function Test1 
    {
        param(
            [string]$param1,
            [int]$param2
        )
    
        Write-Host "Parameter 1: $param1"
        Write-Host "Parameter 2: $param2"
    }
    
    # Test the function 
    Test1 -param1 "This is a test" -param2 12

    Output

    PowerShell also supports various parameter types beyond basic data types like [string] and [int] such as:

    • Boolean : [bool]
    • Array: [array]
    • Hash Table: [hashtable]
    • DateTime: [datetime]
    • Custom Object: [MyCustomObject]
    • Switch: [switch], acting as a switch (true/false without a value)
    • File or Path: [System.IO.FileInfo] this type of parameter accept file paths or specific files
    • ValidatePattern: [ValidatePattern()], Validates input using a regular expression pattern

    Example 2

    Here’s an example using a [bool] (Boolean) parameter type

    function Check-Status 
    {
        param(
            [bool]$IsActive
        )
        if ($IsActive) 
        {
            Write-Host "The status is active."
        } 
        else 
        {
            Write-Host "The status is inactive."
        }
    }
    
    # Calling the function with a boolean argument
    Check-Status -IsActive $true
    

    Output:

    In this example, the Check-Status function takes a [bool] parameter named $IsActive. Inside the function, it checks the value of the $IsActive parameter. If it’s true, it outputs that the status is active; otherwise, it states that the status is inactive. In this case, we pass the argument -IsActive $true, indicating that the status is active. You can change $true to $false when calling the function to observe the “inactive” status output.

    Example 3:

    Here’s an example using a [switch] parameter type

    function Toggle-Status 
    {
        param(
            [switch]$Enable
        )
    
        if ($Enable) 
        {
            "Status is enabled."
        } 
        else 
        {
            "Status is disabled."
        }
    }
    
    # Calling the function without enabling the status (switch not specified)
    Toggle-Status
    
    # Calling the function and explicitly enabling the status using the switch parameter
    Toggle-Status -Enable

    The Toggle-Status function has a single parameter named $Enable of type [switch]. When the function is called without specifying -Enable, it defaults to $false. When you call the function with -Enable, it sets the switch parameter to $true. Try running the code the see the outputs.

    Using the [Parameter()] Attributes

    If you want to add additional attributes or properties to your parameters, you can use [Parameter()] along with various options to customize their behavior. [Parameter()] is an attribute used to define parameters within a function such as its position, mandatory status, default values, etc. For instance, you can use it to define parameter properties like this:

    • [Parameter(Mandatory = $true)] makes the parameter mandatory
    • [Parameter(Position = 0)] specifies the position of the parameter
    • [Parameter(ValueFromPipeline = $true)] allows the parameter to accept input from the pipeline, among others

    Let’s look at some examples:

    Example 1: Function with Mandatory parameter

    In this example, we will using Function with mandatory parameter. When you set a parameter as mandatory by assigning it a value of $true, you must provide a value for that variable when calling the function.

    function Print-Info 
    {
        param(
            [Parameter(Mandatory=$true)]
            [int]$Number
        )
    
        "The provided number is: $Number"
    }
    
    # Calling the Function
    Print-Info -Number 12
    
    # Note that Calling the function without providing the mandatory parameter
    # will generate an error because the mandatory parameter is missing

    Output:

    Example 2: Function with Positional parameter

    A function with positional parameters in PowerShell is a function where the parameters can be passed based on their positions rather than explicitly using their names. Positional parameters can be useful when you have functions with multiple parameters, and their order of usage is consistent. See example below:

    function Greet-User 
    {
        param(
            [Parameter(Position=0)]
            [string]$FirstName,
    
            [Parameter(Position=1)]
            [string]$LastName
        )
    
        "Hello, $FirstName $LastName! Welcome to PowerShell."
    }
    
    # Calling the function using positional parameters
    Greet-User "John" "Doe"

    Output:

    This function Greet-User, the parameters $FirstName and $LastName are set with specific positions using the [Parameter(Position=X)] attribute. This means when you call the function, you can pass the arguments in the order of their positions without explicitly mentioning the parameter names. “John” will be assigned to $FirstName because it’s the first positional parameter, and “Doe” will be assigned to $LastName as it’s the second positional parameter.

    However, you should explicitly specifying the parameter names while calling the function as it makes your script more readable and less error-prone, especially with functions that have numerous parameters or if the parameter order might be ambiguous.

    You can also use both the Mandatory and Position attributes together for a parameter in a function:

    function Get-Info 
    {
        param(
            [Parameter(Mandatory=$true, Position=0)]
            [string]$Name,
    
            [Parameter(Position=1)]
            [int]$Age
        )
    
        "Name: $Name"
        if ($Age) 
        {
            "Age: $Age"
        } 
        else 
        {
            "Age not provided."
        }
    }
    
    # Calling the function using positional parameters
    Get-Info "John" 30

    Output:

    In this Get-Info function:

    • $Name is set as a mandatory parameter and is also the first positional parameter.
    • $Age is set as a non-mandatory parameter and is the second positional parameter.

    In the output, “John” is assigned to $Name (first positional parameter), and 30 will be assigned to $Age (second positional parameter). The Mandatory attribute ensures that $Name must be provided when calling the function, while $Age remains optional since it doesn’t have the Mandatory attribute.

    Example 3 Function with ParameterSetName

    The ParameterSetName feature allows you to define different sets of parameters within a function. Each set, identified by a unique ParameterSetName can have its own parameters, providing flexibility in how the function is called and what parameters are required or optional based on a specific scenario. This approach allows you to create more versatile functions that adapt to different scenarios by defining different sets of parameters, each applicable under specific conditions or use cases.

    Below is an example simulates a function to manage network settings based on different parameter sets:

    function Set-NetworkSettings 
    {
        param (
            [Parameter(ParameterSetName='StaticIP', Mandatory=$true)]
            [string]$IPAddress,
    
            [Parameter(ParameterSetName='StaticIP', Mandatory=$true)]
            [string]$SubnetMask,
    
            
            [Parameter(ParameterSetName='DHCP', Mandatory=$true)]
            [switch]$UseDHCP
        )
        
        if ($PSCmdlet.ParameterSetName -eq 'StaticIP') 
        {
            "Setting static IP: $IPAddress, Subnet Mask: $SubnetMask"
            # Apply static IP settings
        }
    
        if ($PSCmdlet.ParameterSetName -eq 'DHCP') 
        {
            "Using DHCP for IP configuration."
            # Configure network to use DHCP
        }
    }
    
    # Setting network settings with a static IP address
    Set-NetworkSettings -IPAddress "192.168.1.100" -SubnetMask "255.255.255.0"
    
    # Configuring the network to use DHCP
    Set-NetworkSettings -UseDHCP

    Output 1: Setting network settings with a static IP address

    Output 2: If we configuring the network to use DHCP

    In the example above, the Set-NetworkSettings function has two parameter sets: ‘StaticIP’ and ‘DHCP’

    ‘StaticIP’ expects parameters $IPAddress and $SubnetMask for setting a static IP address

    ‘DHCP’ includes a [switch] parameter $UseDHCP to specify using DHCP for network configuration

    $PSCmdlet is a PowerShell automatic variable that refers to the cmdlet or script from within which it is accessed. It provides access to properties and methods related to the current cmdlet execution context. In the context of a function with multiple parameter sets, $PSCmdlet.ParameterSetName is used to determine which parameter set was used when the function was called.

    Using the [ValidateSet()] attributes

    The [ValidateSet()] attribute in PowerShell is used to limit the input of a parameter to a predefined set of valid values. It ensures that only specified values are accepted for that particular parameter. This can be useful for user inputs or configuration settings.

    Example 1

    function Set-Environment 
    {
        param(
            [ValidateSet("Development", "Testing", "Production")]
            [string]$Environment
        )
    
        Write-Host "Selected environment: $Environment"
        # Additional operations based on the selected environment
    }
    
    # Valid call using one of the specified values
    Set-Environment -Environment "Development"
    
    # Invalid call using a value not included in the ValidateSet
    # This will give error
    Set-Environment -Environment "Staging"

    Output 1:

    Output 2: when you put a value that is not included in the ValidateSet

    The Set-Environment function has a parameter named $Environment. [ValidateSet(“Development”, “Testing”, “Production”)] restricts the valid values for $Environment to only “Development”, “Testing”, or “Production”. If any other value is provided, PowerShell will throw an error indicating that the input is not valid.

    Using Begin, Process, End

    Begin, Process , End are script blocks that can be utilized in advanced functions, especially when dealing with cmdlets and scripts that handle pipeline input. These blocks are particularly useful when dealing with commands that accept input from the pipeline (ValueFromPipeline=$true). They provide a structured way to handle iterative processing of objects passed through the pipeline.

    If your PowerShell function or script doesn’t rely on or accept pipeline input, there might not be a significant need to use the Begin, Process and End block.

    Example 1:

    function Count-Characters 
    {
        param (
            [Parameter(ValueFromPipeline=$true)]
            [string]$Text
        )
    
        begin 
        {
            Write-Host "Starting character count."
        }
        process 
        {
            $charCount = $Text.Length
            Write-Host "Text: $Text - Character count: $charCount"
        }
        end 
        {
            Write-Host "Ending character count."
        }
    }
    
    # Use the Function
    "Hello", "Goodbye", "PowerShell" | Count-Characters
    

    Output

    This function Count-Characters, calculates the character count of text passed through the pipeline

    In Powershell there are two kind of types of pipeline input, known as ByValue and ByPropertyName

    ByValue (Entire Object)

    This type of pipeline input accepts the entire object passed through the pipeline. Here’s an example

    function Multiply-Number 
    {
        param (
            [Parameter(ValueFromPipeline=$true)]
            [int]$Number,
            [int]$Factor
        )
    
        process 
        {
            $result = $Number * $Factor
            Write-Output $result
        }
    }
    
    # Use the Function 
    1, 2, 3, 4 | Multiply-Number -Factor 10

    Output

    In this example, the numbers 1,2,3,4 are passed through the pipeline as individual objects. The Multiply-Number function receives each of these numbers as a whole object due to ValueFromPipeline=$true

    ByPropertyName (Single Object Property)

    This type of pipeline input operates on a single property of an object passed through the pipeline. Here’s an example

    function Capitalize-Property 
    {
        param (
            [Parameter(ValueFromPipelineByPropertyName=$true)]
            [string]$Name
        )
        
        process 
        {
            $result = $Name.ToUpper()
            Write-Output $result
        }
    }
    
    # Assume we have a custom object with a property called Name:
    $person = [PSCustomObject]@{
        Name = "john"
    }
    
    # Pass this object through the pipeline and modify its Name property
    $person | Capitalize-Property

    Output

    This example takes the property Name of the object $person and capitalizes it using the Capitalize-Property function. ValueFromPipelineByPropertyName=$true parameter attribute enables this behavior, allowing the function to work on the specified property of the incoming object.

    So choosing between ByValue and ByPropertyName pipeline input largely depends on the context of your script or function and the nature of the data you’re dealing with

    If your function needs to process the entirety of each object passing through the pipeline, use ValueFromPipeline=$true. For instance, if you’re performing actions on complete objects like files, services, or custom objects where all properties matter.

    If your function or script operates on specific properties of objects rather than the entire object, ValueFromPipelineByPropertyName=$true is beneficial. For example, if you want to modify specific attributes like filenames, usernames, specific properties of objects, etc.

    Using the [CmdletBinding()] attributes

    [CmdletBinding()] is an attribute used in PowerShell functions to enable advanced features associated with cmdlets. Here are some scenarios when you should consider using [CmdletBinding()]

    Example 1

    Using Common Parameter: If you want your function to support common parameters like -Verbose, -Debug, -ErrorAction, -WarningAction, etc then [CmdletBiding()] is necessary

    function Test-Function 
    {
        [CmdletBinding()]
        param (
            [Parameter()]
            [int]$Number
        )
    
        Write-Verbose "Verbose mode activated."
        
        try 
        {
            $result = 10 / $Number
            Write-Output "Result: $result"
        } 
        catch 
        {
            Write-Error "Error occurred: $_"
        }
    }
    
    # Use the Function 
    Test-Function -Number 0 -Verbose -ErrorAction Stop

    Output

    In this example, Write-Verbose is used to output verbose information if -Verbose is specified when calling the function. The try-catch block is used to handle errors. If an error occurs during the division, it’s caught and displayed using Write-Error

    Example 2

    SupportsShouldProcess: [CmdletBinding()] allow you to confirm potentially destructive actions before execution, prove a safer user experience.

    Note that [CmdletBinding ]

    function Remove-File 
    {
        [CmdletBinding(SupportsShouldProcess=$true)]
        param (
            [Parameter(Mandatory=$true)]
            [string]$FilePath
        )
    
        if ($PSCmdlet.ShouldProcess("Delete file: $FilePath", "Confirm deletion")) 
        {
            Remove-Item -Path $FilePath -Force
            Write-Output "File $FilePath has been deleted."
        } 
        else 
        {
            Write-Output "Deletion of file $FilePath was canceled."
        }
    }
    
    # Use the Function 
    Remove-File -FilePath "C:\Path\To\File.txt" -WhatIf

    In this example, [CmdletBinding(SupportsShouldProcess-$true)] enables the support for ShouldProcess(). The ShouldProcess() prompts the user for confirmation before deleting the file specified by $FilePath.

    In this case, -Whatif parameter allow you to see what would happen without actually performing the action. If you remove -Whatif it will prompt you for confirmation before deleting the file.

    Conclusion

    In conclusion, PowerShell function parameters promote modularity, flexibility, and clarity, enabling the creation of adaptable, reusable, and user-friendly functions that cater to diverse scenarios and enhance automation capabilities.

    Leave a Reply

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