More PowerShell Parameter Attributes
When you write a PowerShell function, you need to pay close attention to the parameters you define. The attributes you use can greatly affect how your function behaves and how users interact with it. You want to design parameters that make your code easy to use and that will set up the user for success. I've written about and demonstrated many parameter techniques in the past. Today, I want to cover a few lesser known parameter attributes. I can't guarantee that all of them will work in Windows PowerShell, but you should be able to use them PowerShell 7.`
AllowEmpty
When you define a parameter and make it mandatory, you force the user to provide a value.
Function Get-RemoteData {
[cmdletbinding()]
Param(
[Parameter(Position = 0, Mandatory)]
[string]$ComputerName
)
Write-Verbose 'Using these parameters'
$PSBoundParameters | Out-String | Write-Verbose
Write-Host "Processing $computername" -ForegroundColor green
}
The user can't run the function without providing a value for the ComputerName parameter.
PS C:\> Get-RemoteData
cmdlet Get-RemoteData at command pipeline position 1
Supply values for the following parameters:
ComputerName:
Get-RemoteData: Cannot bind argument to parameter 'ComputerName' because it is an empty string.
PS C:\> Get-RemoteData
cmdlet Get-RemoteData at command pipeline position 1
Supply values for the following parameters:
ComputerName:
If you need to allow it, it is possible to allow empty values. You can do this by using the AllowEmptyString()
attribute. It is up to you to decide how to handle the empty value. One option is to set a default value. Normally, you can't set a default value for a mandatory parameter, but you can do it with the AllowEmptyString()
attribute.
Function Get-RemoteData {
[cmdletbinding()]
Param(
[Parameter(Position = 0, Mandatory)]
[AllowEmptyString()]
[string]$ComputerName
)
Write-Verbose 'Using these parameters'
$PSBoundParameters | Out-String | Write-Verbose
if (-Not $ComputerName) {
Write-Host 'No computer names provided. Insert code here' -ForegroundColor yellow
#maybe provide a default or fallback
$Computername = $env:COMPUTERNAME
}
Write-Host "Processing $computername" -ForegroundColor green
}
Here's what it looks like in action:
PS C:\> Get-RemoteData
cmdlet Get-RemoteData at command pipeline position 1
Supply values for the following parameters:
ComputerName:
No computer names provided. Insert code here
Processing PROSPERO
This also works if the user is getting a value from somewhere else and it is empty.
PS C:\> $n = ""
PS C:\> Get-RemoteData $n
No computer names provided. Insert code here
Processing PROSPERO
This also works for collections such as when the parameter accepts an array of values.
Function Get-RemoteData {
[cmdletbinding()]
Param(
[Parameter(Position = 0, Mandatory)]
[AllowEmptyCollection()]
[string[]]$ComputerName
)
Write-Verbose 'Using these parameters'
$PSBoundParameters | Out-String | Write-Verbose
if ($ComputerName.Count -eq 0) {
Write-Host 'No computer names provided. Insert code here' -ForegroundColor yellow
#maybe provide a default or fallback
$Computername = $env:COMPUTERNAME
}
foreach ($cn in $Computername) {
Write-Host "Processing $cn" -ForegroundColor green
}
}
I'm using the same behavior as before.
PS C:\> Get-RemoteData Foo,Bar
Processing Foo
Processing Bar
PS C:\> $a = @()
PS C:\> Get-RemoteData $a
No computer names provided. Insert code here
Processing PROSPERO
The command will run with an empty value, so you need to decide how that affects your code.
PSDefaultValue
Some parameter attributes are designed as documentation aids. It is not uncommon to define a default value for a parameter.
Function Get-Thing {
<#
.SYNOPSIS
Get things from a path
.Parameter Path
Select a path for things to process
#>
[cmdletbinding()]
Param(
[Parameter(Position = 0, HelpMessage = 'Select a path to process')]
[string]$Path = "."
)
$path = Convert-Path $Path
Write-Host "Getting things from $Path"
}