PowerShell Advanced Function Template
Hello,
Today, we’ll see how to write a basic advanced function by using a wide variety of PowerShell features. We’ll try to use all the features provided by Microsoft to write a advanced function with the minimum of lines possible.
First, let list the features we want in our advanced function:
- Error handling
- Verbose
- Parameter Validation
- Pipeline utilization
To achieve this, we need to use:
- Try/Catch
- CmdletBinding
- ValidatePattern/ValidateScript/Validate*
- Parameter()
Hereunder a dummy example that use all of them:
First, a test function, to check behavior:
function Do-SomeThing { [CmdletBinding()] Param( [Parameter(ValueFromPipeline=$true)] [String]$Input ) if($Input -eq 'Toto'){ "Doing something on $Input." } else{ throw 'Error !' } }
Then, our function with the features:
Function Verb-Noun{ [CmdletBinding()] #Enable all the default paramters, including -Verbose Param( [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, HelpMessage='HelpMessage', Position=0)] [ValidatePattern('[A-Z]')] #Validate that the string only contains letter [String[]]$PipelineInput ) Begin{ Write-Verbose -Message "Starting $($MyInvocation.InvocationName) with $($PsCmdlet.ParameterSetName) parameterset..." } Process{ ForEach($Object in $PipelineInput){ #Pipeline input try{ #Error handling Write-Verbose -Message "Doing something on $Object..." $Result = $Object | Do-SomeThing -ErrorAction Stop #Generate Output New-Object -TypeName PSObject -Property @{ Result = $Result Object = $Object } } catch{ Write-Error -Message "$_ went wrong on $Object" } } } End{ Write-Verbose -Message "Ending $($MyInvocation.InvocationName)..." } }
Finally, you can test it with:
'Toto','Error' | Verb-Noun -Verbose
You can use this as a starting point to build your own advanced function, hereunder a list of link with some more interesting features to add:
Now that we have our template, now that you improved my basic example, hereunder a way to use it easily, with a snipet:
#AdvancedFunction $HereString = @' Function Verb-Noun{ [CmdletBinding()] #Enable all the default paramters, including -Verbose Param( [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, HelpMessage='HelpMessage', Position=0)] [ValidatePattern('[A-Z]')] #Validate that the string only contains letter [String[]]$PipelineInput ) Begin{ Write-Verbose -Message "Starting $($MyInvocation.InvocationName) with $($PsCmdlet.ParameterSetName) parameterset..." #Write-Verbose -Message "Parameters are $($PSBoundParameters | Select-Object -Property *)" } Process{ ForEach($Object in $PipelineInput){ #Pipeline input try{ #Error handling Write-Verbose -Message "Doing something on $Object..." $Result = $Object | Do-SomeThing -ErrorAction Stop #Generate Output New-Object -TypeName PSObject -Property @{ Result = $Result Object = $Object } } catch{ Write-Error -Message "$_ went wrong on $Object" } } } End{ Write-Verbose -Message "Ending $($MyInvocation.InvocationName)..." } } '@ New-IseSnippet -Title 'AdvancedFunction' -Description 'Cusctom advanced function template' -Text $HereString -Force
Now, in PowerShell_ISE, use “Ctrl+J”:
Now, you’ll be able to use it faster without having to remember where you saved your template.
As a side note, please also include a help section in your function:
<# .SYNOPSIS .DESCRIPTION .EXAMPLE .PARAMETER .INPUTS .OUTPUTS .NOTES .LINK #>
This will help the people with who you share your code to understand it, and, in a few months, will help you too.