Can you overload functions in PowerShell?
I want to my function to accept a string, array or some switch.
An example of what I want:
In PowerShell functions are not overloaded. The last definition overrides the previous in the same scope or hides the previous in a parent scope. Thus, you should create a single function and provide a way to distinguish its call mode by arguments.
The overload definitions are a list of the different sets of arguments that can be used with a method. For example, the Substring method of System. String has two definitions: PS> 'thisString'.
When a function name is overloaded with different jobs it is called Function Overloading. In Function Overloading “Function” name should be the same and the arguments should be different. Function overloading can be considered as an example of a polymorphism feature in C++.
An overloaded function is really just a set of different functions that happen to have the same name. The determination of which function to use for a particular call is resolved at compile time. In Java, function overloading is also known as compile-time polymorphism and static polymorphism.
In PowerShell functions are not overloaded. The last definition overrides the previous in the same scope or hides the previous in a parent scope. Thus, you should create a single function and provide a way to distinguish its call mode by arguments.
In V2 you may use an advanced function, see help about_Functions_Advanced_Parameters
and avoid some manual coding on resolving parameter set ambiguities:
# advanced function with 3 parameter sets function Backup-UsersData ( [Parameter(Position=0, ParameterSetName="user")] [string]$user, [Parameter(Position=0, ParameterSetName="array")] [object[]]$array, [Parameter(Position=0, ParameterSetName="all")] [switch]$all ) { # use this to get the parameter set name $PSCmdlet.ParameterSetName } # test Backup-UsersData -user 'John' Backup-UsersData 1, 2 Backup-UsersData -all # OUTPUT: # user # array # all
Note that this mechanism is sometimes strange. For example in the first test we have to specify parameter name -user
explicitly. Otherwise:
Backup-UsersData : Parameter set cannot be resolved using the specified named parameters. At C:\TEMP\_101015_110059\try2.ps1:21 char:17 + Backup-UsersData <<<< 'John' + CategoryInfo : InvalidArgument: (:) [Backup-UsersData], ParentContainsErrorRecordException + FullyQualifiedErrorId : AmbiguousParameterSet,Backup-UsersData
In many cases standard, not advanced, function with mixed parameters will do:
function Backup-UsersData ( [string]$user, [object[]]$array, [switch]$all ) { if ($user) {'user'} elseif ($array) {'array'} elseif ($all) {'all'} else {'may be'} } Backup-UsersData -user 'John' Backup-UsersData -array 1, 2 Backup-UsersData -all Backup-UsersData
But in this case you should resolve (or accept and ignore) ambiguities, e.g. to decide what to do if, say:
Backup-UsersData -user 'John' -array 1, 2 -all
Here is a variant of Roman's answer that I think is a little more flexible:
function Backup { [CmdletBinding(DefaultParameterSetName='Users')] Param ( [parameter(mandatory=$true, ParameterSetName='Users', position=0, ValueFromPipeline=$true)][string[]]$User, [parameter(mandatory=$true, ParameterSetName='AllUsers')][switch]$All ) Begin { if ($All) { $User = @('User1', 'User2', 'User3') } } Process { foreach ($u in $User) { echo "Backup $u" } } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With