All you need to know about functions in PowerShell in one page! All-in-one I didn’t find any resource where I have all information. Of course, there is the official page About Functions Advanced Parameters for advanced features. I lose too much time surfing on different websites, forum etc. I decided to create my own reference and share with everyone interested.
As a pragmatic person, I chose to make it simple, not a lot of text or complicated example including things we don’t need. You should be able to copy-paste the example et use it directly. As this page is intended to include every subject that a function could have, the advantage of the one-page is that we can easily find the information with CTRL + F.
Define parameters that can be received
Accept param from pipeline
[cmdletbinding()] param( [Parameter(Mandatory=$true, ValueFromPipeline)][string]$VarFromPipeline )
Is the parameter mandatory?
param( [Parameter(Mandatory=$true)]$MyString, [Parameter(Mandatory=$false)]$MyInt, [Parameter(Mandatory=$true)]$MySecondString = "Second string" )
If the parameter is not mandatory, you can then set a default value.
Define types
param( [Parameter(Mandatory=$true)][string]$MyString, [Parameter(Mandatory=$true)][int]$MyInt, [Parameter(Mandatory=$true)][double]$MyDouble, [Parameter(Mandatory=$true)][float]$MyFloat, [Parameter(Mandatory=$true)][DateTime]$MyDateTime, [Parameter(Mandatory=$true)][switch]$MySwitch # ... )
By defining the type, you ensure your function receive the proper type of variable
Switch parameters are parameters with no parameter value. They’re effective only when they’re used and have only one effect.
Group of parameters
param( [Parameter(Mandatory=$true)] [string]$Symbol, [Parameter(Mandatory=$true, ParameterSetName = 'Time')] [string]$StartTime, [Parameter(Mandatory=$true, ParameterSetName = 'Time')] [string]$EndTime, [Parameter(Mandatory=$true, ParameterSetName = 'Limit')] [ValidateRange(1, 1000)] [int]$Limit )
The ParameterSetName
argument specifies the parameter set to which a parameter belongs. If no parameter set is specified, the parameter belongs to all the parameter sets defined by the function. Therefore, to be unique, each parameter set must have at least one parameter that isn’t a member of any other parameter set.
Dynamic parameters
function Test-Order{ [cmdletbinding()] param( [Parameter(Mandatory=$true)] [ValidateSet("Market", "Limit", "TakeLimit")] [string]$OrderType ) DynamicParam{ # param1 $attributes = New-Object -Type System.Management.Automation.ParameterAttribute $attributes.Mandatory = $true $attributeCollection = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute] $attributeCollection.Add($attributes) $dynParam = New-Object -Type System.Management.Automation.RuntimeDefinedParameter("Price", [double], $attributeCollection) #param2 $attributes2 = New-Object -Type System.Management.Automation.ParameterAttribute $attributes2.Mandatory = $true $attributeCollection2 = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute] $attributeCollection2.Add($attributes2) $dynParam2 = New-Object -Type System.Management.Automation.RuntimeDefinedParameter("StopPrice", [double], $attributeCollection2) # add to dictionnary $paramDictionary = New-Object -Type System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add("Price", $dynParam) $paramDictionary.Add("StopPrice", $dynParam2) return $paramDictionary } BEGIN{ $Price = $paramDictionary.values[0].value[0] $StopPrice = $paramDictionary.values[0].value[1] write-host $paramDictionary.values[0].name[0] write-host $paramDictionary.values[0].value[1] } PROCESS{ Write-Host "Price: $Price" write-host "StopPrice: $StopPrice" write-host "orderType: $OrderType" } }
I noticed that it fails if your parameter has space. You can only add DynamicParam once in your function. You must add the PROCESS script block.
More information or this website
Valid parameters received
Valid a set of value
param( [Parameter(Mandatory=$true)] [ValidateSet("1m","3m","5m","15m","30m","1h","2h","4h","6h","8h","12h","1d","3d","1w","1M")] [string]$Interval )
This will valid the parameter only if it is included in the set
Valid a range
param( [Parameter(Mandatory=$true)] [ValidateRange(1, 15)] [int]$Limit )
Only a number between 1 to 15 is accepted
Valid a parameter with code
param( [Parameter(Mandatory=$true)] [ValidateScript({Test-Path $_ -PathType 'Container'})] [string]$MyPath )
Valid directly that the parameter which should be a path is correct
Valid a parameter is not null
param( [ValidateNotNull()] [Parameter(Mandatory=$true)] [string]$MyPath )
Check if a parameter is set
if($PSBoundParameters.ContainsKey('MyParam')){ }
If the parameter MyParam contains something…
Return values
function Get-MyFunction{ $Total = 2 + 2 return $Total } $MyInt = Get-MyFunction
You can return a variable with return.
function Get-MyFunction{ $a = "aha" $o = "oho" return $a, $o } $MyArray = Get-MyFunction
You can even return many parameters, you just need to separate them by a comma.
PS C:\> $MyArray aha oho
The value is stored in the variable $MyInt in the first example and in $MyArray in the second.
Provide information about your function
function Get-MyFunction{ <# .SYNOPSIS In a few words, what my function does .DESCRIPTION Here you can provide more information about what the function does and how .PARAMETER Param1 Explain what is param1 .PARAMETER Param2 Explain what is param2 .EXAMPLE Explain here how to run Get-MyFunction .EXAMPLE Get-MyFunction -Param1 "abc" -param2 "efg" .NOTES FunctionName : ADD-WPLibrary Created by : Yann Greder Date Coded : 2021/03/02 11:00:00 #>
Approved Verbs for PowerShell Commands/functions
If you use Visual Studio Code and don’t use an approved verb for your function, this going to trigger a warning saying “The cmdlet uses an unapproved verb”. Of course, the code will work just fine. If you want to follow best practices check this official doc. This is to ensure consistency between the cmdlets that you create, the cmdlets that are provided by PowerShell, and the cmdlets that are designed by others.
Examples: Do not use a synonym of an approved verb. For example, always use Remove, never use Delete or Eliminate. But use: New, Set, Add, Get, Read, Invoke, Copy, Open, Remove
Begin, Process, End
function Get-MyFunction{ <# .SYNOPSIS .DESCRIPTION #> [cmdletbinding()] param( ) BEGIN{ } PROCESS{ } END{ } }
Run a function with start-job (or Start-ThreadJob) and argument
Function Job1 ($variable) { Write-host "Start job1" Write-host $variable } $Var = "string" $ExportFunctions = [scriptblock]::Create(@" Function Job1 { $function:Job1 } "@) Start-Job -InitializationScript $ExportFunctions -ScriptBlock { Job1 $Using:Var } | Wait-Job | Receive-Job
Function template
function Get-MyTemplate{ <# .SYNOPSIS .DESCRIPTION .PARAMETER MyParam .EXAMPLE #> [cmdletbinding()] param( ) BEGIN{ } PROCESS{ } END{ } }
1 thought on “Functions in PowerShell – All-in-one”