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.