Ironman Software Forums
Continue the conversion on the Ironman Software forums. Chat with over 1000 users about PowerShell, PowerShell Universal, and PowerShell Pro Tools.
In this post, we’ll look at how to create advanced functions with the CmdletBinding attribute.
The CmdletBinding
attribute is used to convert standard PowerShell functions into advanced functions that behave similar to compiled C# cmdlets. Some differences between standard functions include:
To use the CmdletBinding
attribute, you need to define a function and place the attribute before the param
block. You can optionally define parameters with the Parameter
attribute to adjust how parameters behave.
function Switch-String {
[CmdletBinding()]
param([string]$String)
$Array = $String.ToCharArray()
[Array]::Reverse($Array)
[string]::new($Array)
}
Advanced functions support the use of built-in parameters like -Confirm
. If you define ConfirmImpact
, you can call ShouldProcess
to make the user confirm that action. The ConfirmImpact
property should be set to the level at which the $ConfirmPreference
should prompt for confirmation. You will also need to set SupportsShouldProcess
in order to use ConfirmImpact
. Resetting the Universe is set to high.
function Reset-Universe {
[CmdletBInding(ConfirmImpact = 'High', SupportsShouldProcess)]
param()
if ($PSCmdlet.ShouldProcess("Universe"))
{
Write-Host "Universe reset!"
}
}
The resulting operation looks like this.
PS > Reset-Universe
Confirm
Are you sure you want to perform this action?
Performing the operation "Reset-Universe" on target "Universe".
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): Y
Universe reset!
You can use the CmdletBinding
attribute to set the default parameter set name when multiple are defined. Sometimes it’s not possible to determine a parameter set name without the default parameter set.
function Select-DefaultParameterSet {
[CmdletBinding(DefaultParameterSetName = "DefaultSet")]
param(
[Parameter(ParameterSetName = "DefaultSet")]
$DefaultValue1 = "Default1",
[Parameter(ParameterSetName = "NonDefaultSet")]
$DefaultValue2 = "Default2"
)
if ($PSCmdlet.ParameterSetName -eq 'DefaultSet')
{
$DefaultValue1
}
else
{
$DefaultValue2
}
}
The result of executing this cmdlet is as follows.
PS > Select-DefaultParameterSet
Default1
Advanced functions support begin
, process
and end
blocks. These blocks are used when processing pipeline input.
function Write-Pipeline {
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline)]
[string]$String
)
Begin {
Write-Host "Begin"
}
Process {
Write-Host "Process: $String"
}
End {
Write-Host "End"
}
}
The resulting output from the above function will be the following.
PS > "Hello", "World" | Write-Pipeline
Begin
Process: Hello
Process: World
End
We can update our Switch-String
cmdlet to take pipeline by including the Parameter
attribute and the Process
block.
function Switch-String {
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline)]
[string]$String
)
Process {
$Array = $String.ToCharArray()
[Array]::Reverse($Array)
[string]::new($Array)
}
}
The resulting behavior is that the Switch-String
cmdlet can now take pipeline input.
PS > "Hello", "World" | Switch-String
olleH
dlroW
With position binding defined, parameters can be used by position rather than by name.
function Write-Position {
[CmdletBinding(PositionalBinding)]
param(
$Position1,
$Position2
)
$Position1
$Position2
}
You can then use the cmdlet without specifying the parameter names.
Write-Position 1 2
The pipeline in PowerShell supports paging parameters that are similar to data processing features of systems such as SQL. The parameters include:
n
objects.n
objects and then gets the remaining objects.function Get-Numbers {
[CmdletBinding(SupportsPaging)]
param()
$FirstNumber = [Math]::Min($PSCmdlet.PagingParameters.Skip, 100)
$LastNumber = [Math]::Min($PSCmdlet.PagingParameters.First +
$FirstNumber - 1, 100)
if ($PSCmdlet.PagingParameters.IncludeTotalCount) {
$TotalCountAccuracy = 1.0
$TotalCount = $PSCmdlet.PagingParameters.NewTotalCount(100,
$TotalCountAccuracy)
Write-Output $TotalCount
}
$FirstNumber .. $LastNumber | Write-Output
}
The result of executing the above cmdlet is the following:
PS > Get-Numbers -IncludeTotalCount -Skip 10 -First 10
Total count: 100
10
11
12
13
14
15
16
17
18
19
Find this useful? Please consider sharing this article. Have a question about PowerShell? Contact us and we'll write a post about it.
Continue the conversion on the Ironman Software forums. Chat with over 1000 users about PowerShell, PowerShell Universal, and PowerShell Pro Tools.
Receive once-a-month updates about Ironman Software. You'll learn about our product updates and blogs related to PowerShell.